Merge branch 'develop' into feature/licensing

# Conflicts:
#	client/config/dev.env.js
#	client/config/prod.env.js
#	client/cypress/fixtures/schema.json
#	client/cypress/integration/beta-login.spec.js
#	client/package-lock.json
#	client/src/graphql/client.js
#	client/src/layouts/PublicLayout.vue
#	client/src/main.js
#	client/src/styles/main.scss
#	server/core/settings.py
#	server/registration/mutations_public.py
#	server/users/factories.py
#	server/users/models.py
#	server/users/schema.py
This commit is contained in:
Christian Cueni 2020-04-30 15:22:55 +02:00
commit 6b76c27c55
160 changed files with 4457 additions and 2219 deletions

3
.gitignore vendored
View File

@ -43,3 +43,6 @@ server/media/
.coverage
# test reports
client/cypress/test-reports/
server/test-reports/

View File

@ -4,7 +4,7 @@ verify_ssl = true
name = "pypi"
[requires]
python_version = '3.6'
python_version = "3.6"
[dev-packages]
awscli = "*"
@ -36,7 +36,8 @@ django-libsass = "*"
bleach = "*"
newrelic = "*"
sentry-sdk = "==0.7.2"
"django-sendgrid-v5" = "==0.8.0"
django-sendgrid-v5 = "==0.8.0"
python-http-client = "==3.2.1"
ipython = "*"
requests = "*"
unittest-xml-reporting = "*"

322
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "ca4f635dc983134e4569df2af8f0d73f488211bc2a97d11c194f76279f942977"
"sha256": "f7bfa448c4413cfd5d7517793e7095aa2f0e072f570b32281c5f573aba34552d"
},
"pipfile-spec": 6,
"requires": {
@ -40,26 +40,26 @@
},
"bleach": {
"hashes": [
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
"sha256:cc8da25076a1fe56c3ac63671e2194458e0c4d9c7becfd52ca251650d517903c",
"sha256:e78e426105ac07026ba098f04de8abe9b6e3e98b5befbf89b51a5ef0a4292b03"
],
"index": "pypi",
"version": "==3.1.0"
"version": "==3.1.4"
},
"boto3": {
"hashes": [
"sha256:629ce3be236b6e0aed52358146eea9ffa7679d6cd1cc9b3e12332226270d6499",
"sha256:b1351e62136fae29be8fcbb1c4890f1d72017d57e33051d435a8bf9f71212fde"
"sha256:5246caf509baa4716065e6bb78bdc516fdd6b0dfbd9098cc2a0f779fad789c6c",
"sha256:52b8de35f6647e3b8ce81f6a745a67812623b5c4acc2d6bd5e814fddfa488321"
],
"index": "pypi",
"version": "==1.11.14"
"version": "==1.12.34"
},
"botocore": {
"hashes": [
"sha256:34ad4d73e6bef5c8ad956c66354611628cdebd431fe2927261ed9c068b9cfb7a",
"sha256:6570f2ba046956d5b548ab2346d32f713ecf8b8cb098a839d73fcf832ccfa223"
"sha256:c799623598d04c66b0be4cb990c01a24bd3c06023f0c7221adead38a7431c994",
"sha256:db0fba3f4adfb9bf3976aae10efa9acb59e3efe52ce8feac71ecac0b7be2fc2e"
],
"version": "==1.14.14"
"version": "==1.15.34"
},
"certifi": {
"hashes": [
@ -77,17 +77,17 @@
},
"click": {
"hashes": [
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
"sha256:8a18b4ea89d8820c5d0c7da8a64b2c324b4dabb695804dbfea19b9be9d88c0cc",
"sha256:e345d143d80bf5ee7534056164e5e112ea5e22716bbb1ce727941f4c8b471b9a"
],
"version": "==7.0"
"version": "==7.1.1"
},
"decorator": {
"hashes": [
"sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce",
"sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d"
"sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760",
"sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"
],
"version": "==4.4.1"
"version": "==4.4.2"
},
"dj-database-url": {
"hashes": [
@ -106,10 +106,10 @@
},
"django-appconf": {
"hashes": [
"sha256:35f13ca4d567f132b960e2cd4c832c2d03cb6543452d34e29b7ba10371ba80e3",
"sha256:c98a7af40062e996b921f5962a1c4f3f0c979fa7885f7be4710cceb90ebe13a6"
"sha256:1b1d0e1069c843ebe8ae5aa48ec52403b1440402b320c3e3a206a0907e97bb06",
"sha256:be58deb54a43d77d2e1621fe59f787681376d3cd0b8bd8e4758ef6c3a6453380"
],
"version": "==1.0.3"
"version": "==1.0.4"
},
"django-compressor": {
"hashes": [
@ -219,10 +219,10 @@
},
"faker": {
"hashes": [
"sha256:047d4d1791bfb3756264da670d99df13d799bb36e7d88774b1585a82d05dbaec",
"sha256:1b1a58961683b30c574520d0c739c4443e0ef6a185c04382e8cc888273dbebed"
"sha256:2d3f866ef25e1a5af80e7b0ceeacc3c92dec5d0fdbad3e2cb6adf6e60b22188f",
"sha256:b89aa33837498498e15c709eb40c31386408a901a53c7a5e12a425737a767976"
],
"version": "==4.0.0"
"version": "==4.0.2"
},
"future": {
"hashes": [
@ -276,18 +276,18 @@
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
"sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
"sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
],
"version": "==2.8"
"version": "==2.9"
},
"ipython": {
"hashes": [
"sha256:d9459e7237e2e5858738ff9c3e26504b79899b58a6d49e574d352493d80684c6",
"sha256:f6689108b1734501d3b59c84427259fd5ac5141afe2e846cfa8598eb811886c9"
"sha256:ca478e52ae1f88da0102360e57e528b92f3ae4316aabac80a2cd7f7ab2efb48a",
"sha256:eb8d075de37f678424527b5ef6ea23f7b80240ca031c2dd6de5879d687a65333"
],
"index": "pypi",
"version": "==7.12.0"
"version": "==7.13.0"
},
"ipython-genutils": {
"hashes": [
@ -305,18 +305,20 @@
},
"jmespath": {
"hashes": [
"sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6",
"sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c"
"sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec",
"sha256:cca55c8d153173e21baa59983015ad0daf603f9cb799904ff057bfb8ff8dc2d9"
],
"version": "==0.9.4"
"version": "==0.9.5"
},
"libsass": {
"hashes": [
"sha256:003a65b4facb4c5dbace53fb0f70f61c5aae056a04b4d112a198c3c9674b31f2",
"sha256:0fb4399f7bbecab7b181f2c2d82c3a0ba2916bf9169714b96e425355a5b23b9f",
"sha256:0fd8b4337b3b101c6e6afda9112cc0dc4bacb9133b59d75d65968c7317aa3272",
"sha256:338e9ae066bf1fde874e335324d5355c52d2081d978b4f74fc59536564b35b08",
"sha256:4dcfd561fb100250b89496e1362b96f2cc804f689a59731eb0f94f9a9e144f4a",
"sha256:50778d4be269a021ba2bf42b5b8f6ff3704ab96a82175a052680bddf3ba7cc9f",
"sha256:53f87116e7441827878bd79bbad8debac23e1930423f61ab8d837ec4a4c36e0c",
"sha256:6a51393d75f6e3c812785b0fa0b7d67c54258c28011921f204643b55f7355ec0",
"sha256:74acd9adf506142699dfa292f0e569fdccbd9e7cf619e8226f7117de73566e32",
"sha256:81a013a4c2a614927fd1ef7a386eddabbba695cbb02defe8f31cf495106e974c",
@ -333,17 +335,17 @@
},
"newrelic": {
"hashes": [
"sha256:8283dd54299b3fd2818a262f38f9193a2ee52b2a02fecca1a1d04764be533c92"
"sha256:5d83887781683975bd75ec624baa8de5e1e75c2bf89e7269ed2811b559da1504"
],
"index": "pypi",
"version": "==5.6.0.135"
"version": "==5.10.0.138"
},
"parso": {
"hashes": [
"sha256:56b2105a80e9c4df49de85e125feb6be69f49920e121406f15e7acde6c9dfc57",
"sha256:951af01f61e6dccd04159042a0706a31ad437864ec6e25d0d7a96a9fbb9b0095"
"sha256:0c5659e0c6eba20636f99a04f469798dca8da279645ce5c387315b2c23912157",
"sha256:8515fc12cfca6ee3aa59138741fc5624d62340c97e401c74875769948d4f2995"
],
"version": "==0.6.1"
"version": "==0.6.2"
},
"pexpect": {
"hashes": [
@ -365,19 +367,30 @@
"sha256:0013f590a8f260df60bcfd65db19d18efc04e7f046c3c82a40e2e2b3292a937c",
"sha256:0b899ee80920bb533f26581af9b4660bc12aff4562555afe74e429101ebf3c94",
"sha256:12f29d6c23424f704c66b5b68c02fe0b571504459605cfe36ab8158359b0e1bb",
"sha256:135e9aa65150c53f7db85bf2bebb8a0e1a48ea850e80cf66e16dd04fa09d309c",
"sha256:153ec6f18f7b61641e0e6e502acfaf4a06c9aba2ea11c0b4b3578ea9f13a4a4a",
"sha256:17fe25efc785194d48c38fad85dce470013ba19d2fb66639e149f14bccf1327f",
"sha256:1912b7230459fd53682dae32b83cbd8e5d642ba36d4be18566f00a9c063aa13d",
"sha256:1a5b93084e01328a1cb1ecdad99d11d75e881e89a95f88d85b523646553b36c2",
"sha256:25193f934d37d836a6b1f4c062ce574a96cbca7c6d9dc8ddfbbac7f9c54deaa4",
"sha256:2c042352b430d678db50c78c5214e19638eff8b688941271da2de21fd298dfe5",
"sha256:2e818dbe445e86fc6c266973fe540c35125c42eb2cf13a6095e9adaa89c0deb5",
"sha256:2fcde9954c8882d1c7f93bb828caa34a4c5e3ee69dbc7895dc8652ad972b455a",
"sha256:35f7d998b8e82fb3fb51ff88b30485eb81cd7dd56ec7e1a8deba23eb88532d44",
"sha256:37cc0339abfa9e295c75d9a7f227d35cb44716feb95057f9449c4a9e9a17daf7",
"sha256:43334f9581cd067945b8898cef9eb5714ee4883f8de0304c011f1dbdb1d4e2aa",
"sha256:4bd4a71501b6d51db4abc07e1f43f5a6fed0a1a9583cca0b401d6af50284b0db",
"sha256:57aa6198ba8acba1313c3b743e267d821a60cac77e6026caf0b55ca58d3d23be",
"sha256:5b0d657460d9f3615876fec6306e97ca15a471f6169b622d76a47e270998acf1",
"sha256:5cd36804f9f06a914a883fe682df5711d16d7b4f44d43189c5f013e7cd91e149",
"sha256:6977cf073d83358b34f93abf5c1f1193b88675fe0e4441e0e28318bc3dcba7a0",
"sha256:718ec7a122b28d64afc5fbc3a9b99bb0545ef511373cac06fe7624520e82cb20",
"sha256:7dfbefdb3fb911ca9faed307bf309861e9995e36cca6b761c7ba6d9b77a9744a",
"sha256:801cca8923508311bf5d6d0f7da5362552e8208ebd8ec0d7b9f2cd2ff5705734",
"sha256:82b172e3264e62372c01b5b009b5b1a02fbb9276cbe5cc57ab00a6d6e5ed9a18",
"sha256:82d1ff571489765df2816785d532e243bde213752156c227fca595723ec5ff42",
"sha256:8580fc58074a16b749905b26cf8363f7b628dd167ba0130f5382cdc91c86b509",
"sha256:931030d1d6282b7900e6b0a7ff9ecdb503b5e1e6781800dab2b71a9f39405bff",
"sha256:9525cd680a6f9e80c6c0af03cf973e6505c59f60b4745f682cd1a449e54b31bb",
"sha256:a224651a81e45ef4f1d0164e256c5f6b4abb49f2ae8f22ba2f3a9d0ff338e608",
"sha256:a370d1c570f1d72e877099651e752332444b1c5009381f043c9da5fd47f3ebae",
@ -386,7 +399,12 @@
"sha256:b85f703c2ffe539313e39ce0676bed0f355cec45a16e58c9ab7417445843047c",
"sha256:b9f63451084a718eccdeb1e382768c94647915653af4d6019f64560d9e98642b",
"sha256:c793dfaa130847ccff958492b76ae8b9304e60b8a79a92962cb19e368276a22b",
"sha256:ddd16ab250b4fc97db1c47407e78c25216a75c29d29d10ad37e51b7a2ec7b2c3"
"sha256:d60c1625b108432ace8b1fa1a584017e5efa73f107d0f493c7f39c79bebf1d41",
"sha256:dc4b018d5c9b636f7546583c5591b9ea00c328c3e5871992ef5b95bac353f097",
"sha256:ddd16ab250b4fc97db1c47407e78c25216a75c29d29d10ad37e51b7a2ec7b2c3",
"sha256:e126ff4fed71e78333840c07279e1617f63cfca76d63ad5b27d65a7277206a3d",
"sha256:f8d49be8c282df8d2e1ab6ab53ab8abd859b1fa6fed384457ee85c9eff64ef97",
"sha256:fcf64c91fd44485100a2965d23bb0e227d093e91f7e776c5ca3b32574766eb56"
],
"index": "pypi",
"version": "==5.0.0"
@ -399,10 +417,10 @@
},
"prompt-toolkit": {
"hashes": [
"sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e",
"sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a"
"sha256:563d1a4140b63ff9dd587bda9557cffb2fe73650205ab6f4383092fb882e7dc8",
"sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"
],
"version": "==3.0.3"
"version": "==3.0.5"
},
"psycopg2": {
"hashes": [
@ -450,10 +468,10 @@
},
"pygments": {
"hashes": [
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
"sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"
"sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
"sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
],
"version": "==2.5.2"
"version": "==2.6.1"
},
"python-dateutil": {
"hashes": [
@ -502,11 +520,11 @@
},
"requests": {
"hashes": [
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
"sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
"sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
],
"index": "pypi",
"version": "==2.22.0"
"version": "==2.23.0"
},
"rjsmin": {
"hashes": [
@ -542,10 +560,11 @@
},
"sendgrid": {
"hashes": [
"sha256:12ea8203c48c47b03dbe33e219408ca32c9259526d05b783418482d40f17943c",
"sha256:5ad98598c13b8cf5545d20f6fb6ecf967a08b48e3e175affabd82cfc71522d01"
"sha256:2954caf82c94c3566147e78ff7772f0883a7cc668de5a1c5ff1c49dcb9c1af31",
"sha256:7c606125c59d1df7354e20581ca645d109be1d026f5b01dd62112e07348b2d87",
"sha256:a58c8d3f99e1b4fed6c041e6bb0e30893a6c40ffc0ecd33430a08d044fe78832"
],
"version": "==6.1.1"
"version": "==6.2.1"
},
"sentry-sdk": {
"hashes": [
@ -598,12 +617,19 @@
],
"version": "==1.1.1"
},
"unittest-xml-reporting": {
"hashes": [
"sha256:74eaf7739a7957a74f52b8187c5616f61157372189bef0a32ba5c30bbc00e58a",
"sha256:e09b8ae70cce9904cdd331f53bf929150962869a5324ab7ff3dd6c8b87e01f7d"
],
"index": "pypi",
"version": "==3.0.2"
},
"urllib3": {
"hashes": [
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
],
"markers": "python_version != '3.4'",
"version": "==1.25.8"
},
"wagtail": {
@ -624,10 +650,10 @@
},
"wcwidth": {
"hashes": [
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
"sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"
"sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1",
"sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"
],
"version": "==0.1.8"
"version": "==0.1.9"
},
"webencodings": {
"hashes": [
@ -655,10 +681,10 @@
"develop": {
"asgiref": {
"hashes": [
"sha256:7e06d934a7718bf3975acbf87780ba678957b87c7adc056f13b6215d610695a0",
"sha256:ea448f92fc35a0ef4b1508f53a04c4670255a3f33d22a81c8fc9c872036adbe5"
"sha256:8036f90603c54e93521e5777b2b9a39ba1bad05773fcf2d208f0299d1df58ce5",
"sha256:9ca8b952a0a9afa61d30aa6d3d9b570bb3fd6bafcf7ec9e6bed43b936133db1c"
],
"version": "==3.2.3"
"version": "==3.2.7"
},
"autopep8": {
"hashes": [
@ -668,11 +694,11 @@
},
"awscli": {
"hashes": [
"sha256:2748af4e77728ced50d7d5bda0fa980449bd71eedff90ee643bee86ed4283d2f",
"sha256:9118015f4bbab1c671d9c9927d07b6f7eadb7e1e8bbb2b06dc849c3de578d692"
"sha256:b713641674a228959e4030cab578d2720d1132f40bed15f0c5cd950525b559c9",
"sha256:c0b75242000ed03152e30cee50a61d571019da27a5862d520e758f03842c206d"
],
"index": "pypi",
"version": "==1.17.14"
"version": "==1.18.34"
},
"backcall": {
"hashes": [
@ -683,10 +709,10 @@
},
"botocore": {
"hashes": [
"sha256:34ad4d73e6bef5c8ad956c66354611628cdebd431fe2927261ed9c068b9cfb7a",
"sha256:6570f2ba046956d5b548ab2346d32f713ecf8b8cb098a839d73fcf832ccfa223"
"sha256:c799623598d04c66b0be4cb990c01a24bd3c06023f0c7221adead38a7431c994",
"sha256:db0fba3f4adfb9bf3976aae10efa9acb59e3efe52ce8feac71ecac0b7be2fc2e"
],
"version": "==1.14.14"
"version": "==1.15.34"
},
"certifi": {
"hashes": [
@ -712,47 +738,47 @@
},
"coverage": {
"hashes": [
"sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3",
"sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c",
"sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0",
"sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477",
"sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a",
"sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf",
"sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691",
"sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73",
"sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987",
"sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894",
"sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e",
"sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef",
"sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf",
"sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68",
"sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8",
"sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954",
"sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2",
"sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40",
"sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc",
"sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc",
"sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e",
"sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d",
"sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f",
"sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc",
"sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301",
"sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea",
"sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb",
"sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af",
"sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52",
"sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37",
"sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0"
"sha256:03f630aba2b9b0d69871c2e8d23a69b7fe94a1e2f5f10df5049c0df99db639a0",
"sha256:046a1a742e66d065d16fb564a26c2a15867f17695e7f3d358d7b1ad8a61bca30",
"sha256:0a907199566269e1cfa304325cc3b45c72ae341fbb3253ddde19fa820ded7a8b",
"sha256:165a48268bfb5a77e2d9dbb80de7ea917332a79c7adb747bd005b3a07ff8caf0",
"sha256:1b60a95fc995649464e0cd48cecc8288bac5f4198f21d04b8229dc4097d76823",
"sha256:1f66cf263ec77af5b8fe14ef14c5e46e2eb4a795ac495ad7c03adc72ae43fafe",
"sha256:2e08c32cbede4a29e2a701822291ae2bc9b5220a971bba9d1e7615312efd3037",
"sha256:3844c3dab800ca8536f75ae89f3cf566848a3eb2af4d9f7b1103b4f4f7a5dad6",
"sha256:408ce64078398b2ee2ec08199ea3fcf382828d2f8a19c5a5ba2946fe5ddc6c31",
"sha256:443be7602c790960b9514567917af538cac7807a7c0c0727c4d2bbd4014920fd",
"sha256:4482f69e0701139d0f2c44f3c395d1d1d37abd81bfafbf9b6efbe2542679d892",
"sha256:4a8a259bf990044351baf69d3b23e575699dd60b18460c71e81dc565f5819ac1",
"sha256:513e6526e0082c59a984448f4104c9bf346c2da9961779ede1fc458e8e8a1f78",
"sha256:5f587dfd83cb669933186661a351ad6fc7166273bc3e3a1531ec5c783d997aac",
"sha256:62061e87071497951155cbccee487980524d7abea647a1b2a6eb6b9647df9006",
"sha256:641e329e7f2c01531c45c687efcec8aeca2a78a4ff26d49184dce3d53fc35014",
"sha256:65a7e00c00472cd0f59ae09d2fb8a8aaae7f4a0cf54b2b74f3138d9f9ceb9cb2",
"sha256:6ad6ca45e9e92c05295f638e78cd42bfaaf8ee07878c9ed73e93190b26c125f7",
"sha256:73aa6e86034dad9f00f4bbf5a666a889d17d79db73bc5af04abd6c20a014d9c8",
"sha256:7c9762f80a25d8d0e4ab3cb1af5d9dffbddb3ee5d21c43e3474c84bf5ff941f7",
"sha256:85596aa5d9aac1bf39fe39d9fa1051b0f00823982a1de5766e35d495b4a36ca9",
"sha256:86a0ea78fd851b313b2e712266f663e13b6bc78c2fb260b079e8b67d970474b1",
"sha256:8a620767b8209f3446197c0e29ba895d75a1e272a36af0786ec70fe7834e4307",
"sha256:922fb9ef2c67c3ab20e22948dcfd783397e4c043a5c5fa5ff5e9df5529074b0a",
"sha256:9fad78c13e71546a76c2f8789623eec8e499f8d2d799f4b4547162ce0a4df435",
"sha256:a37c6233b28e5bc340054cf6170e7090a4e85069513320275a4dc929144dccf0",
"sha256:c3fc325ce4cbf902d05a80daa47b645d07e796a80682c1c5800d6ac5045193e5",
"sha256:cda33311cb9fb9323958a69499a667bd728a39a7aa4718d7622597a44c4f1441",
"sha256:db1d4e38c9b15be1521722e946ee24f6db95b189d1447fa9ff18dd16ba89f732",
"sha256:eda55e6e9ea258f5e4add23bcf33dc53b2c319e70806e180aecbff8d90ea24de",
"sha256:f372cdbb240e09ee855735b9d85e7f50730dcfb6296b74b95a3e5dea0615c4c1"
],
"index": "pypi",
"version": "==5.0.3"
"version": "==5.0.4"
},
"decorator": {
"hashes": [
"sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce",
"sha256:5d19b92a3c8f7f101c8dd86afd86b0f061a8ce4540ab8cd401fa2542756bce6d"
"sha256:41fa54c2a0cc4ba648be4fd43cff00aedf5b9465c9bf18d64325bc225f08f760",
"sha256:e3a62f0520172440ca0dcc823749319382e377f37f140a0b99ef45fecb84bfe7"
],
"version": "==4.4.1"
"version": "==4.4.2"
},
"django": {
"hashes": [
@ -764,11 +790,10 @@
},
"django-silk": {
"hashes": [
"sha256:9d5d66628689230288d1020de186b86e6f38583f611b5dd796ec988bb6a6333e",
"sha256:b0033ec3713882a5abb8b3db2b4392a746b83ce164ab7be568f0eeec4ba78a98"
"sha256:56c2c5aefd1c65161df61e49cf2674862a748a43e81c7c470bcbc4c35c53491c"
],
"index": "pypi",
"version": "==4.0.0"
"version": "==4.0.1"
},
"docutils": {
"hashes": [
@ -786,25 +811,25 @@
},
"idna": {
"hashes": [
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
"sha256:7588d1c14ae4c77d74036e8c22ff447b26d0fde8f007354fd48a7814db15b7cb",
"sha256:a068a21ceac8a4d63dbfd964670474107f541babbd2250d61922f029858365fa"
],
"version": "==2.8"
"version": "==2.9"
},
"ipdb": {
"hashes": [
"sha256:5d9a4a0e3b7027a158fc6f2929934341045b9c3b0b86ed5d7e84e409653f72fd"
"sha256:77fb1c2a6fccdfee0136078c9ed6fe547ab00db00bebff181f1e8c9e13418d49"
],
"index": "pypi",
"version": "==0.12.3"
"version": "==0.13.2"
},
"ipython": {
"hashes": [
"sha256:d9459e7237e2e5858738ff9c3e26504b79899b58a6d49e574d352493d80684c6",
"sha256:f6689108b1734501d3b59c84427259fd5ac5141afe2e846cfa8598eb811886c9"
"sha256:ca478e52ae1f88da0102360e57e528b92f3ae4316aabac80a2cd7f7ab2efb48a",
"sha256:eb8d075de37f678424527b5ef6ea23f7b80240ca031c2dd6de5879d687a65333"
],
"index": "pypi",
"version": "==7.12.0"
"version": "==7.13.0"
},
"ipython-genutils": {
"hashes": [
@ -829,10 +854,10 @@
},
"jmespath": {
"hashes": [
"sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6",
"sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c"
"sha256:695cb76fa78a10663425d5b73ddc5714eb711157e52704d69be03b1a02ba4fec",
"sha256:cca55c8d153173e21baa59983015ad0daf603f9cb799904ff057bfb8ff8dc2d9"
],
"version": "==0.9.4"
"version": "==0.9.5"
},
"markupsafe": {
"hashes": [
@ -874,10 +899,10 @@
},
"parso": {
"hashes": [
"sha256:56b2105a80e9c4df49de85e125feb6be69f49920e121406f15e7acde6c9dfc57",
"sha256:951af01f61e6dccd04159042a0706a31ad437864ec6e25d0d7a96a9fbb9b0095"
"sha256:0c5659e0c6eba20636f99a04f469798dca8da279645ce5c387315b2c23912157",
"sha256:8515fc12cfca6ee3aa59138741fc5624d62340c97e401c74875769948d4f2995"
],
"version": "==0.6.1"
"version": "==0.6.2"
},
"pexpect": {
"hashes": [
@ -896,10 +921,10 @@
},
"prompt-toolkit": {
"hashes": [
"sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e",
"sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a"
"sha256:563d1a4140b63ff9dd587bda9557cffb2fe73650205ab6f4383092fb882e7dc8",
"sha256:df7e9e63aea609b1da3a65641ceaf5bc7d05e0a04de5bd45d05dbeffbabf9e04"
],
"version": "==3.0.3"
"version": "==3.0.5"
},
"ptyprocess": {
"hashes": [
@ -910,8 +935,19 @@
},
"pyasn1": {
"hashes": [
"sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359",
"sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576",
"sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf",
"sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7",
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"
"sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00",
"sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8",
"sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86",
"sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12",
"sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776",
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba",
"sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2",
"sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"
],
"version": "==0.4.8"
},
@ -924,10 +960,10 @@
},
"pygments": {
"hashes": [
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
"sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"
"sha256:647344a061c249a3b74e230c739f434d7ea4d8b1d5f3721bc0f3558049b38f44",
"sha256:ff7a40b4860b727ab48fad6360eb351cc1b33cbf9b15a0f689ca5353e9463324"
],
"version": "==2.5.2"
"version": "==2.6.1"
},
"python-dateutil": {
"hashes": [
@ -945,27 +981,28 @@
},
"pyyaml": {
"hashes": [
"sha256:0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc",
"sha256:2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803",
"sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc",
"sha256:38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15",
"sha256:483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075",
"sha256:4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd",
"sha256:7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31",
"sha256:8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f",
"sha256:c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c",
"sha256:e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04",
"sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"
"sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97",
"sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76",
"sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2",
"sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648",
"sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf",
"sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f",
"sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2",
"sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee",
"sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d",
"sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c",
"sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"
],
"version": "==5.2"
"markers": "python_version != '3.4'",
"version": "==5.3.1"
},
"requests": {
"hashes": [
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
"sha256:43999036bfa82904b6af1d99e4882b560e5e2c68e5c4b0aa03b655f3d7d73fee",
"sha256:b3f43d496c6daba4493e7c431722aeb7dbc6288f52a6e04e7b6023b0247817e6"
],
"index": "pypi",
"version": "==2.22.0"
"version": "==2.23.0"
},
"rsa": {
"hashes": [
@ -990,10 +1027,10 @@
},
"sqlparse": {
"hashes": [
"sha256:40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177",
"sha256:7c3dca29c022744e95b547e867cee89f4fce4373f3549ccd8797d8eb52cdb873"
"sha256:022fb9c87b524d1f7862b3037e541f68597a730a8843245c349fc93e1643dc4e",
"sha256:e162203737712307dfe78860cc56c8da8a852ab2ee33750e33aeadf38d12c548"
],
"version": "==0.3.0"
"version": "==0.3.1"
},
"traitlets": {
"hashes": [
@ -1007,15 +1044,14 @@
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
],
"markers": "python_version != '3.4'",
"version": "==1.25.8"
},
"wcwidth": {
"hashes": [
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
"sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"
"sha256:cafe2186b3c009a04067022ce1dcd79cb38d8d65ee4f4791b8888d6599d1bbe1",
"sha256:ee73862862a156bf77ff92b09034fc4825dd3af9cf81bc5b360668d425f3c5f1"
],
"version": "==0.1.8"
"version": "==0.1.9"
}
}
}

View File

@ -190,8 +190,5 @@ There is a schema.json in the fixtures folder. For now it has been generated onc
To generate a new schema, use the management command
```
python manage.py graphql_schema --schema api.schema.schema --out schema.json --indent 4
python manage.py export_schema_for_cypress
```
Then, remove the `data` property from the generated `schema.json`, so the `__schema` property is on the top level.
Also remove the two objects with `"name": "__debug"` from the JSON file.

View File

@ -60,20 +60,35 @@ aliases:
- npm run test:unit
- &deploy-prod
name: deploy to prod on Heroku
deployment: prod
script:
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/skillbox-prod.git HEAD:master
- &deploy-prod-manual
name: deploy to prod on Heroku
deployment: prod
trigger: manual
script:
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/skillbox-prod.git HEAD:master
- &deploy-dev
name: deploy to dev on Heroku
deployment: dev
trigger: manual
script:
- git push --force https://heroku:$HEROKU_API_KEY@git.heroku.com/skillbox-dev.git HEAD:master
pipelines:
default:
- step: *unittest-python
- step: *cypress-test
- step: *jest-test
- step: *deploy-dev
branches:
master:
- step: *unittest-python
- step: *cypress-test
- step: *jest-test
- step: *deploy-prod-manual
develop:
- step: *unittest-python
@ -81,6 +96,7 @@ pipelines:
- step: *jest-test
- step:
name: deploy to stage on Heroku
deployment: stage
script:
- git push https://heroku:$HEROKU_API_KEY@git.heroku.com/skillbox-stage.git develop:master

View File

@ -6,4 +6,6 @@ module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
GOOGLE_ANALYTICS_ID: JSON.stringify(process.env.GOOGLE_ANALYTICS_ID),
HEP_URL: JSON.stringify(process.env.HEP_URL),
})
MATOMO_HOST: JSON.stringify(process.env.MATOMO_HOST),
MATOMO_SITE_ID: JSON.stringify(process.env.MATOMO_SITE_ID),
});

View File

@ -3,4 +3,6 @@ module.exports = {
NODE_ENV: '"production"',
GOOGLE_ANALYTICS_ID: JSON.stringify(process.env.GOOGLE_ANALYTICS_ID),
HEP_URL: JSON.stringify(process.env.HEP_URL),
MATOMO_HOST: JSON.stringify(process.env.MATOMO_HOST),
MATOMO_SITE_ID: JSON.stringify(process.env.MATOMO_SITE_ID),
}

View File

@ -1,4 +1,9 @@
{
"baseUrl": "http://localhost:8000",
"videoUploadOnPasses": false
"videoUploadOnPasses": false,
"reporter": "junit",
"reporterOptions": {
"mochaFile": "cypress/test-reports/cypress-results-[hash].xml",
"toConsole": true
}
}

View File

@ -7,6 +7,7 @@
"firstName": "Rahel",
"lastName": "Cueni",
"avatarUrl": "",
"isTeacher": false,
"lastModule": {
"id": "TW9kdWxlTm9kZToxNw==",
"slug": "lohn-und-budget",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
{
"me": {
"id": "VXNlck5vZGU6Mg==",
"isTeacher": false,
"selectedClass": {
"id": "U2Nob29sQ2xhc3NOb2RlOjE=",
"name": "Moordale",
"members": [
{
"id": "VXNlck5vZGU6Mw==",
"firstName": "Otis",
"lastName": "Milburn",
"isTeacher": false,
"active": true,
"__typename": "ClassMemberNode"
},
{
"id": "VXNlck5vZGU6NA==",
"firstName": "Maeve",
"lastName": "Wiley",
"isTeacher": false,
"active": true,
"__typename": "ClassMemberNode"
}
],
"__typename": "SchoolClassNode"
},
"__typename": "UserNode"
}
}

View File

@ -35,4 +35,31 @@ describe('The Login Page', () => {
cy.get('[data-cy=login-error]').contains('Die E-Mail oder das Passwort ist falsch. Bitte versuchen Sie nochmals.');
});
it('redirect after login', () => {
const username = 'test';
const password = 'test';
cy.visit('/book/topic/berufliche-grundbildung');
cy.login(username, password);
cy.get('body').contains('Berufliche Grundbildung');
});
it.only('logs out then logs in again', () => {
cy.viewport('macbook-15');
cy.apolloLogin('rahel.cueni', 'test');
cy.visit('/me/my-class');
cy.get('[data-cy=header-user-widget]').should('exist').within(() => {
cy.get('[data-cy=user-widget-avatar]').should('exist').click();
});
cy.get('[data-cy=logout]').click();
cy.login('rahel.cueni', 'test');
cy.get('[data-cy=header-user-widget]').should('exist').within(() => {
cy.get('[data-cy=user-widget-avatar]').should('exist').click();
});
cy.get('.profile-sidebar').should('be.visible');
});
})

View File

@ -1,49 +0,0 @@
const schema = require('../fixtures/schema.json');
const me = require('../fixtures/me.join-class.json');
describe('Join Class', () => {
beforeEach(() => {
cy.server();
cy.mockGraphql({
schema: schema,
});
cy.viewport('macbook-15');
cy.apolloLogin('rahel.cueni', 'test');
});
it('should join class', () => {
cy.mockGraphqlOps({
operations: {
MeQuery: me,
JoinClass: {
joinClass: {
success: true,
schoolClass: {
id: "U2Nob29sQ2xhc3NOb2RlOjI=",
name: "KF1A",
__typename: "SchoolClassNode"
}
}
}
}
});
cy.visit('/me/profile');
cy.get('[data-cy=user-widget-avatar]').click();
cy.get('[data-cy=class-selection]').click();
cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
cy.get('[data-cy=join-class-link]').click();
cy.get('[data-cy=input-class-code]').type('XXXX');
cy.get('[data-cy=join-class]').click();
cy.get('[data-cy=class-selection]').click();
cy.get('[data-cy=class-selection-entry]').should('have.length', 2);
})
})

View File

@ -10,9 +10,12 @@ describe('New student', () => {
schema: schema,
});
cy.apolloLogin('hansli', 'test');
const __typename = "SchoolClassNode";
const name = "KF1A";
const id = "U2Nob29sQ2xhc3NOb2RlOjI=";
cy.mockGraphqlOps({
operations: {
MeQuery: me,
@ -20,9 +23,20 @@ describe('New student', () => {
joinClass: {
success: true,
schoolClass: {
id: "U2Nob29sQ2xhc3NOb2RlOjI=",
name: "KF1A",
__typename: "SchoolClassNode"
id,
name,
__typename
}
}
},
MySchoolClassQuery: {
me: {
...me.me,
selectedClass: {
__typename,
name,
id,
members: []
}
}
}

View File

@ -0,0 +1,320 @@
const schema = require('../fixtures/schema.json');
const me = require('../fixtures/me.join-class.json');
const selectedClass = require('../fixtures/selected-school-class.json');
describe('Class Management', () => {
beforeEach(() => {
cy.server();
cy.mockGraphql({
schema: schema,
});
cy.viewport('macbook-15');
cy.apolloLogin('rahel.cueni', 'test');
});
// fixme: cache misbehaves with mequery, but only for test
// it('should join class', () => {
// const name = 'KF1A';
// const id = 'U2Nob29sQ2xhc3NOb2RlOjI=';
// const __typename = 'SchoolClassNode';
//
// let localMe = {
// ...me
// };
//
// cy.mockGraphqlOps({
// operations: {
// MeQuery: localMe,
// // JoinClass() {
// // // fixme: is this necessary? the cache somehow does not seem to do anything for the MeQuery
// // let schoolClass = {
// // id,
// // name,
// // // __typename
// // };
// // // localMe.me.schoolClasses.edges.push({
// // // node: schoolClass,
// // // __typename: 'SchoolClassNodeEdge'
// // // });
// // return {
// // joinClass: {
// // success: true,
// // schoolClass
// // }
// // }
// // },
// JoinClass: {
// joinClass: {
// success: true,
// schoolClass: {
// name,
// id
// }
// }
// },
// MySchoolClassQuery: {
// me: {
// ...selectedClass.me,
// selectedClass: {
// __typename,
// name,
// id,
// members: []
// }
// }
// }
// }
// });
//
// cy.visit('/me/profile');
//
// cy.get('[data-cy=header-user-widget]').within(() => {
// cy.get('[data-cy=user-widget-avatar]').click();
// });
// //
// cy.get('[data-cy=class-selection]').click();
// cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
// cy.get('[data-cy=class-selection]').click();
//
// cy.get('[data-cy=join-class-link]').click();
//
// cy.get('[data-cy=input-class-code]').type('XXXX');
// cy.get('[data-cy=join-class]').click();
//
// cy.get('[data-cy=school-class-name]').should('contain', name);
// cy.get('[data-cy=current-class-name]').should('contain', name);
//
// cy.get('[data-cy=header-user-widget]').within(() => {
// cy.get('[data-cy=user-widget-avatar]').click();
// });
//
// cy.get('[data-cy=class-selection]').click();
// cy.get('[data-cy=class-selection-entry]').should('have.length', 2);
// //
// });
it('should not be able to leave class', () => {
cy.mockGraphqlOps({
operations: {
MeQuery: me,
MySchoolClassQuery: selectedClass
}
});
cy.visit('/me/my-class');
cy.get('[data-cy=school-class-member]').should('have.length', 2);
cy.get('[data-cy=remove-from-class]').should('have.length', 0);
cy.get('[data-cy=add-to-class]').should('have.length', 0);
});
it('should leave and re-join class', () => {
// todo: re-enable after the deactivation of users is re-enabled again
// const teacher = {
// me: {
// ...me.me,
// isTeacher: true
// }
// };
// const teacherSelectedClass = {
// me: {
// ...selectedClass.me,
// isTeacher: true
// }
// };
// cy.mockGraphqlOps({
// operations: {
// MeQuery: teacher,
// AddRemoveMember: {
// addRemoveMember: {
// success: true
// }
// },
// MySchoolClassQuery: teacherSelectedClass
// }
// });
//
// cy.visit('/me/my-class');
// cy.get('[data-cy=active-class-members-list]').within(() => {
// cy.get('[data-cy=school-class-member]').should('have.length', 2)
// });
// cy.get('[data-cy=inactive-class-members-list]').should('not.exist');
//
// cy.get('[data-cy=remove-from-class]').first().click();
//
// cy.get('[data-cy=modal-save-button]').click();
//
// cy.get('[data-cy=active-class-members-list]').within(() => {
// cy.get('[data-cy=school-class-member]').should('have.length', 1)
// });
// cy.get('[data-cy=inactive-class-members-list]').within(() => {
// cy.get('[data-cy=school-class-member]').should('have.length', 1)
// });
//
// cy.get('[data-cy=add-to-class]').first().click();
//
// cy.get('[data-cy=active-class-members-list]').within(() => {
// cy.get('[data-cy=school-class-member]').should('have.length', 2)
// });
// cy.get('[data-cy=inactive-class-members-list]').should('not.exist');
});
it('should display old classes', () => {
let oldClasses = me.me.schoolClasses;
let OldClassesQuery = {
me: {
...me.me,
oldClasses
},
};
cy.mockGraphqlOps({
operations: {
MeQuery: me,
OldClassesQuery
}
});
cy.visit('/me/old-classes');
cy.get('[data-cy=old-class-item]').should('have.length', 1);
});
});
describe('Teacher Class Management', () => {
beforeEach(() => {
cy.server();
cy.mockGraphql({
schema: schema,
});
cy.viewport('macbook-15');
cy.apolloLogin('nico.zickgraf', 'test');
});
it('changes class name', () => {
let className = 'Gotta have class';
let localMe = {
me: {
...me.me,
isTeacher: true
}
};
cy.mockGraphqlOps({
operations: {
MeQuery: localMe,
MySchoolClassQuery: {
me: {
...selectedClass.me,
isTeacher: true
}
},
UpdateSchoolClass: {
updateSchoolClass: {
success: true,
schoolClass: {
name: className,
__typename: 'SchoolClassNode'
},
__typename: 'UpdateSchoolClassPayload'
}
}
}
});
cy.visit('/me/my-class');
cy.get('[data-cy=edit-class-name-link]').click();
cy.get('[data-cy=edit-class-name-input] input').type('{selectall}{backspace}').type(className);
cy.get('[data-cy=modal-save-button]').click();
cy.get('[data-cy=school-class-name]').should('contain', className);
});
// // fixme: cache misbehaves with mequery, but only for test
//
// it.only('creates a new class', () => {
// const name = 'Moordale';
// const id = 'U2Nob29sQ2xhc3NOb2RlOjI=';
// const __typename = "SchoolClassNode";
// let localMe = {
// me: {
// ...me.me,
// isTeacher: true
// }
// };
//
// cy.mockGraphqlOps({
// operations: {
// MeQuery: () => {
// return localMe;
// },
// CreateSchoolClass() {
// // fixme: is this necessary? the cache somehow does not seem to do anything for the MeQuery
// let schoolClass = {
// id,
// name,
// __typename
// };
// // localMe.me.schoolClasses.edges.push({
// // node: schoolClass,
// // __typename: 'SchoolClassNodeEdge'
// // });
// return {
// createSchoolClass: {
// success: true,
// schoolClass
// }
// }
// },
// MySchoolClassQuery: {
// me: {
// ...selectedClass.me,
// selectedClass: {
// __typename,
// name,
// id,
// members: []
// }
// }
// }
// }
// });
//
// cy.visit('/me/my-class');
//
// cy.get('h1').should('exist');
//
// cy.get('[data-cy=header-user-widget]').within(() => {
// cy.get('[data-cy=user-widget-avatar]').click();
// });
//
// cy.get('[data-cy=class-selection]').click();
// cy.get('[data-cy=class-selection-entry]').should('have.length', 1);
//
//
// cy.get('[data-cy=create-class-link]').click();
//
// cy.get('[data-cy=input-class-name]').type(name);
//
// cy.get('[data-cy=create-class]').click();
//
// cy.get('[data-cy=school-class-name]').should('contain', name);
// cy.get('[data-cy=current-class-name]').should('contain', name);
//
// cy.get('[data-cy=header-user-widget]').within(() => {
// cy.get('[data-cy=user-widget-avatar]').click();
// });
//
// cy.get('[data-cy=class-selection]').click();
// cy.get('[data-cy=class-selection-entry]').should('have.length', 2);
// });
});

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">
<title>skillbox</title>
<title>mySkillbox</title>
<link href='https://fonts.googleapis.com/css?family=Material+Icons' rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,600,800" rel="stylesheet">
@ -11,6 +11,13 @@
<!-- FIXME: replace with own css -->
<link href="https://surveyjs.azureedge.net/1.0.87/survey.css" type="text/css" rel="stylesheet"/>
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
<link rel="manifest" href="/static/site.webmanifest">
<link rel="mask-icon" href="/static/safari-pinned-tab.svg" color="#5bbad5">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="theme-color" content="#ffffff">
<script>
window.UPLOADCARE_PUBLIC_KEY = '78212ff39934a59775ac';

560
client/package-lock.json generated
View File

@ -2766,6 +2766,15 @@
"@types/yargs": "^12.0.9"
}
},
"@samverschueren/stream-to-observable": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz",
"integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==",
"dev": true,
"requires": {
"any-observable": "^0.3.0"
}
},
"@types/babel__core": {
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz",
@ -3185,6 +3194,12 @@
"integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=",
"dev": true
},
"any-observable": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz",
"integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==",
"dev": true
},
"anymatch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@ -5699,13 +5714,10 @@
}
},
"cachedir": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz",
"integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==",
"dev": true,
"requires": {
"os-homedir": "^1.0.1"
}
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
"integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
"dev": true
},
"caffeine-eight": {
"version": "2.5.9",
@ -6066,9 +6078,9 @@
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE="
},
"ci-info": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
"integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
"dev": true
},
"cipher-base": {
@ -6166,6 +6178,17 @@
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz",
"integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg=="
},
"cli-table3": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz",
"integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==",
"dev": true,
"requires": {
"colors": "^1.1.2",
"object-assign": "^4.1.0",
"string-width": "^2.1.1"
}
},
"cli-truncate": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
@ -7009,61 +7032,65 @@
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
},
"cypress": {
"version": "3.8.1",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-3.8.1.tgz",
"integrity": "sha512-eLk5OpL/ZMDfQx9t7ZaDUAGVcvSOPTi7CG1tiUnu9BGk7caBiDhuFi3Tz/D5vWqH/Dl6Uh4X+Au4W+zh0xzbXw==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-4.2.0.tgz",
"integrity": "sha512-8LdreL91S/QiTCLYLNbIjLL8Ht4fJmu/4HGLxUI20Tc7JSfqEfCmXELrRfuPT0kjosJwJJZacdSji9XSRkPKUw==",
"dev": true,
"requires": {
"@cypress/listr-verbose-renderer": "0.4.1",
"@cypress/xvfb": "1.2.4",
"@types/sizzle": "2.3.2",
"arch": "2.1.1",
"bluebird": "3.5.0",
"cachedir": "1.3.0",
"bluebird": "3.7.2",
"cachedir": "2.3.0",
"chalk": "2.4.2",
"check-more-types": "2.24.0",
"commander": "2.15.1",
"cli-table3": "0.5.1",
"commander": "4.1.0",
"common-tags": "1.8.0",
"debug": "3.2.6",
"execa": "0.10.0",
"debug": "4.1.1",
"eventemitter2": "4.1.2",
"execa": "1.0.0",
"executable": "4.1.1",
"extract-zip": "1.6.7",
"fs-extra": "5.0.0",
"getos": "3.1.1",
"is-ci": "1.2.1",
"fs-extra": "8.1.0",
"getos": "3.1.4",
"is-ci": "2.0.0",
"is-installed-globally": "0.1.0",
"lazy-ass": "1.6.0",
"listr": "0.12.0",
"listr": "0.14.3",
"lodash": "4.17.15",
"log-symbols": "2.2.0",
"minimist": "1.2.0",
"log-symbols": "3.0.0",
"minimist": "1.2.2",
"moment": "2.24.0",
"ramda": "0.24.1",
"request": "2.88.0",
"ospath": "1.2.2",
"pretty-bytes": "5.3.0",
"ramda": "0.26.1",
"request": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
"request-progress": "3.0.0",
"supports-color": "5.5.0",
"supports-color": "7.1.0",
"tmp": "0.1.0",
"untildify": "3.0.3",
"untildify": "4.0.0",
"url": "0.11.0",
"yauzl": "2.10.0"
},
"dependencies": {
"ajv": {
"version": "6.10.2",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
"version": "6.12.0",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
"dev": true,
"requires": {
"fast-deep-equal": "^2.0.1",
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"bluebird": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
"integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
"dev": true
},
"chalk": {
@ -7075,12 +7102,23 @@
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"dependencies": {
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"commander": {
"version": "2.15.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.0.tgz",
"integrity": "sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==",
"dev": true
},
"cross-spawn": {
@ -7097,22 +7135,22 @@
}
},
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"execa": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
"integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^3.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
@ -7121,11 +7159,20 @@
}
},
"fast-deep-equal": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@ -7162,10 +7209,19 @@
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"log-symbols": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
"integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
"dev": true,
"requires": {
"chalk": "^2.4.2"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.2.tgz",
"integrity": "sha512-rIqbOrKb8GJmx/5bc2M0QchhUouMXSpd1RTclXsB41JdL+VtnojfaJR+h7F9k18/4kHUsBFgk80Uk+q569vjPA==",
"dev": true
},
"ms": {
@ -7180,16 +7236,19 @@
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
"dev": true
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"request": {
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"version": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
"from": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
@ -7199,7 +7258,7 @@
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.0",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
@ -7209,7 +7268,7 @@
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.4.3",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
@ -7224,12 +7283,20 @@
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
"has-flag": "^4.0.0"
},
"dependencies": {
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
}
}
},
"tmp": {
@ -7242,13 +7309,13 @@
}
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"dev": true,
"requires": {
"psl": "^1.1.24",
"punycode": "^1.4.1"
"psl": "^1.1.28",
"punycode": "^2.1.1"
}
}
}
@ -8280,6 +8347,12 @@
"es5-ext": "~0.10.14"
}
},
"eventemitter2": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
"integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=",
"dev": true
},
"eventemitter3": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
@ -8988,16 +9061,22 @@
}
},
"fs-extra": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"graceful-fs": "^4.2.0",
"jsonfile": "^4.0.0",
"universalify": "^0.1.0"
},
"dependencies": {
"graceful-fs": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
"dev": true
},
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@ -9606,12 +9685,20 @@
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
"getos": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/getos/-/getos-3.1.1.tgz",
"integrity": "sha512-oUP1rnEhAr97rkitiszGP9EgDVYnmchgFzfqRzSkgtfv7ai6tEi7Ko8GgjNXts7VLWEqrTWyhsOKLe5C5b/Zkg==",
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/getos/-/getos-3.1.4.tgz",
"integrity": "sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw==",
"dev": true,
"requires": {
"async": "2.6.1"
"async": "^3.1.0"
},
"dependencies": {
"async": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz",
"integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==",
"dev": true
}
}
},
"getpass": {
@ -10514,12 +10601,12 @@
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
},
"is-ci": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
"integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
"integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
"dev": true,
"requires": {
"ci-info": "^1.5.0"
"ci-info": "^2.0.0"
}
},
"is-data-descriptor": {
@ -10645,6 +10732,15 @@
}
}
},
"is-observable": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz",
"integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==",
"dev": true,
"requires": {
"symbol-observable": "^1.1.0"
}
},
"is-path-cwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
@ -13191,114 +13287,26 @@
}
},
"listr": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz",
"integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=",
"version": "0.14.3",
"resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz",
"integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==",
"dev": true,
"requires": {
"chalk": "^1.1.3",
"cli-truncate": "^0.2.1",
"figures": "^1.7.0",
"indent-string": "^2.1.0",
"@samverschueren/stream-to-observable": "^0.3.0",
"is-observable": "^1.1.0",
"is-promise": "^2.1.0",
"is-stream": "^1.1.0",
"listr-silent-renderer": "^1.1.1",
"listr-update-renderer": "^0.2.0",
"listr-verbose-renderer": "^0.4.0",
"log-symbols": "^1.0.2",
"log-update": "^1.0.2",
"ora": "^0.2.3",
"p-map": "^1.1.1",
"rxjs": "^5.0.0-beta.11",
"stream-to-observable": "^0.1.0",
"strip-ansi": "^3.0.1"
"listr-update-renderer": "^0.5.0",
"listr-verbose-renderer": "^0.5.0",
"p-map": "^2.0.0",
"rxjs": "^6.3.3"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"cli-cursor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"dev": true,
"requires": {
"restore-cursor": "^1.0.1"
}
},
"cli-spinners": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz",
"integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=",
"dev": true
},
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5",
"object-assign": "^4.1.0"
}
},
"log-symbols": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
"integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
"dev": true,
"requires": {
"chalk": "^1.0.0"
}
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
"ora": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
"integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
"dev": true,
"requires": {
"chalk": "^1.1.1",
"cli-cursor": "^1.0.2",
"cli-spinners": "^0.1.2",
"object-assign": "^4.0.1"
}
},
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"dev": true,
"requires": {
"exit-hook": "^1.0.0",
"onetime": "^1.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"p-map": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
"integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
"dev": true
}
}
@ -13310,9 +13318,9 @@
"dev": true
},
"listr-update-renderer": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz",
"integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz",
"integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==",
"dev": true,
"requires": {
"chalk": "^1.1.3",
@ -13321,7 +13329,7 @@
"figures": "^1.7.0",
"indent-string": "^3.0.0",
"log-symbols": "^1.0.2",
"log-update": "^1.0.2",
"log-update": "^2.3.0",
"strip-ansi": "^3.0.1"
},
"dependencies": {
@ -13378,77 +13386,15 @@
}
},
"listr-verbose-renderer": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz",
"integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz",
"integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==",
"dev": true,
"requires": {
"chalk": "^1.1.3",
"cli-cursor": "^1.0.2",
"chalk": "^2.4.1",
"cli-cursor": "^2.1.0",
"date-fns": "^1.27.2",
"figures": "^1.7.0"
},
"dependencies": {
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
"has-ansi": "^2.0.0",
"strip-ansi": "^3.0.0",
"supports-color": "^2.0.0"
}
},
"cli-cursor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"dev": true,
"requires": {
"restore-cursor": "^1.0.1"
}
},
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": {
"escape-string-regexp": "^1.0.5",
"object-assign": "^4.1.0"
}
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"dev": true,
"requires": {
"exit-hook": "^1.0.0",
"onetime": "^1.0.0"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
}
"figures": "^2.0.0"
}
},
"load-json-file": {
@ -13658,44 +13604,39 @@
}
},
"log-update": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
"integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz",
"integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=",
"dev": true,
"requires": {
"ansi-escapes": "^1.0.0",
"cli-cursor": "^1.0.2"
"ansi-escapes": "^3.0.0",
"cli-cursor": "^2.0.0",
"wrap-ansi": "^3.0.1"
},
"dependencies": {
"ansi-escapes": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
"cli-cursor": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
"integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
"restore-cursor": "^1.0.1"
"ansi-regex": "^3.0.0"
}
},
"onetime": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"wrap-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz",
"integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=",
"dev": true,
"requires": {
"exit-hook": "^1.0.0",
"onetime": "^1.0.0"
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0"
}
}
}
@ -15006,6 +14947,12 @@
"os-tmpdir": "^1.0.0"
}
},
"ospath": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
"integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=",
"dev": true
},
"p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@ -17178,6 +17125,12 @@
}
}
},
"pretty-bytes": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
"integrity": "sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==",
"dev": true
},
"pretty-error": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
@ -17343,9 +17296,9 @@
"integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw=="
},
"ramda": {
"version": "0.24.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz",
"integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=",
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz",
"integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==",
"dev": true
},
"randomatic": {
@ -17962,20 +17915,12 @@
}
},
"rxjs": {
"version": "5.5.12",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz",
"integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==",
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
"dev": true,
"requires": {
"symbol-observable": "1.0.1"
},
"dependencies": {
"symbol-observable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
"dev": true
}
"tslib": "^1.9.0"
}
},
"safe-buffer": {
@ -18766,12 +18711,6 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
},
"stream-to-observable": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz",
"integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=",
"dev": true
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
@ -18886,9 +18825,9 @@
}
},
"survey-vue": {
"version": "1.0.96",
"resolved": "https://registry.npmjs.org/survey-vue/-/survey-vue-1.0.96.tgz",
"integrity": "sha512-6vwEprt6NdTC4BFELdReQWdPNAuVb59jnj2rI/tl7bhk4TJQluRtacy95T9V5r1oMDyATzn8kl2eX0Kr14KVSg==",
"version": "1.5.18",
"resolved": "https://registry.npmjs.org/survey-vue/-/survey-vue-1.5.18.tgz",
"integrity": "sha512-DJURzwbCmVgcW2YTM/L9+8J8AgfRffqbPygYY9eXtf5UR4YVAX0wGcVzmcnqwHnjxCw4sX5DW1UDLzXRBtgGWQ==",
"requires": {
"vue": "^2.1.10"
}
@ -19530,9 +19469,9 @@
}
},
"untildify": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz",
"integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
"dev": true
},
"upath": {
@ -19861,6 +19800,11 @@
}
}
},
"vue-matomo": {
"version": "3.13.4-0",
"resolved": "https://registry.npmjs.org/vue-matomo/-/vue-matomo-3.13.4-0.tgz",
"integrity": "sha512-EeJ75XJAXo8JDHVN+XswFxhXabcZ4DUa0z4ishWaTuvAkLHR+tYNaiouy70UXh4YCU5mbQW3P1msHRijO1j1Bw=="
},
"vue-router": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.1.tgz",

View File

@ -68,7 +68,7 @@
"sass-loader": "^7.1.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"survey-vue": "^1.0.96",
"survey-vue": "^1.5.18",
"uglifyjs-webpack-plugin": "^1.1.1",
"unfetch": "^3.1.1",
"uploadcare-widget": "^3.6.0",
@ -80,6 +80,7 @@
"vue-apollo": "^3.0.0-beta.16",
"vue-axios": "^2.1.1",
"vue-loader": "^14.2.1",
"vue-matomo": "^3.13.4-0",
"vue-router": "^3.0.1",
"vue-scrollto": "^2.11.0",
"vue-style-loader": "^3.0.1",
@ -108,7 +109,7 @@
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^24.8.0",
"canvas": "^2.5.0",
"cypress": "3.8.1",
"cypress": "^4.2.0",
"jest": "^24.8.0",
"jest-serializer-vue": "^2.0.2",
"jest-transform-graphql": "^2.1.0",

View File

@ -1,5 +1,6 @@
<template>
<div :class="{'no-scroll': showModal || showMobileNavigation}" class="app" id="app">
<component :is="showModalDeprecated" v-if="showModalDeprecated"></component>
<component :is="showModal" v-if="showModal"></component>
<component :is="layout"></component>
<mobile-navigation v-if="showMobileNavigation"></mobile-navigation>
@ -18,16 +19,16 @@
import EditContentBlockWizard from '@/components/content-block-form/EditContentBlockWizard';
import NewRoomEntryWizard from '@/components/rooms/room-entries/NewRoomEntryWizard';
import EditRoomEntryWizard from '@/components/rooms/room-entries/EditRoomEntryWizard';
import NewObjectiveGroupWizard from '@/components/objective-groups/NewObjectiveGroupWizard';
import EditObjectiveGroupWizard from '@/components/objective-groups/EditObjectiveGroupWizard';
import NewProjectEntryWizard from '@/components/portfolio/NewProjectEntryWizard';
import EditProjectEntryWizard from '@/components/portfolio/EditProjectEntryWizard';
import NewObjectiveWizard from '@/components/objective-groups/NewObjectiveWizard';
import NewNoteWizard from '@/components/notes/NewNoteWizard';
import EditNoteWizard from '@/components/notes/EditNoteWizard';
import EditClassNameWizard from '@/components/school-class/EditClassNameWizard';
import FullscreenImage from '@/components/FullscreenImage';
import FullscreenInfographic from '@/components/FullscreenInfographic';
import FullscreenVideo from '@/components/FullscreenVideo';
import DeactivatePerson from '@/components/profile/DeactivatePerson';
import {mapGetters} from 'vuex';
@ -46,24 +47,29 @@
EditContentBlockWizard,
NewRoomEntryWizard,
EditRoomEntryWizard,
// todo: remove
NewObjectiveGroupWizard,
EditObjectiveGroupWizard,
NewProjectEntryWizard,
EditProjectEntryWizard,
NewObjectiveWizard,
NewNoteWizard,
EditNoteWizard,
EditClassNameWizard,
FullscreenImage,
FullscreenInfographic,
FullscreenVideo
FullscreenVideo,
DeactivatePerson
},
computed: {
layout() {
return (this.$route.meta.layout || 'default') + '-layout';
},
...mapGetters(['showModal', 'showMobileNavigation'])
...mapGetters({
showModalDeprecated: 'showModal', // don't use this any more todo: remove this
showMobileNavigation: 'showMobileNavigation'
}),
showModal() {
return this.$modal.state.component;
}
},
mounted() {

View File

@ -1,65 +0,0 @@
<template>
<div class="add-objective-group-button" @click="addObjectiveGroup()">
<add-icon class="add-objective-group-button__icon"></add-icon>
<div class="add-objective-group-button__text">Zusätzlich Lernziele für «{{typeDescription}}» erfassen</div>
</div>
</template>
<script>
import AddIcon from '@/components/icons/AddIcon';
export default {
props: ['type', 'module'],
components: {
AddIcon
},
computed: {
typeDescription() {
if (this.type === 'society') {
return 'Gesellschaft'
}
return 'Sprache & Kommunikation';
}
},
methods: {
addObjectiveGroup() {
this.$store.dispatch('addObjectiveGroup', {
module: this.module,
type: this.type
});
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.add-objective-group-button {
display: none;
grid-template-columns: 45px auto;
align-items: center;
margin-top: -20px;
margin-bottom: 35px;
cursor: pointer;
@include desktop {
display: grid;
}
&__icon {
width: 25px;
height: 25px;
fill: $color-silver-dark;
}
&__text {
color: $color-silver-dark;
font-family: $sans-serif-font-family;
}
}
</style>

View File

@ -57,7 +57,9 @@
const instruments = {
base_communication: 'Sprache & Kommunikation',
base_society: 'Gesellschaft'
base_society: 'Gesellschaft',
base_interdisciplinary: 'Überfachliches Instrument',
};
export default {
@ -291,6 +293,14 @@
}
}
&--base_interdisciplinary {
@include content-box($color-accent-4-list);
.content-block__instrument-label {
color: $color-accent-4-dark;
}
}
/deep/ p {
line-height: 1.5;
margin-bottom: 1em;

View File

@ -89,9 +89,11 @@
order: 3;
border-bottom: 0;
}
&:nth-child(2) {
order: 1;
}
&:nth-child(3) {
order: 2;
}

View File

@ -2,12 +2,14 @@
<header class="header-bar">
<content-navigation></content-navigation>
<router-link to="/" class="header-bar__logo" data-cy="home-link">
<logo></logo>
<logo class="header-bar__logo-icon"></logo>
</router-link>
<div class="user-header">
<a class="user-header__sidebar-link" @click="openSidebar()"><current-class class="user-header__current-class"/></a>
<a class="user-header__sidebar-link" @click="openSidebar()">
<current-class class="user-header__current-class"/>
</a>
<user-widget v-bind="me"></user-widget>
<user-widget data-cy="header-user-widget" v-bind="me"></user-widget>
</div>
<book-navigation v-if="showSubnavigation">
</book-navigation>
@ -18,7 +20,6 @@
import ContentNavigation from '@/components/ContentNavigation.vue';
import BookNavigation from '@/components/book-navigation/BookNavigation';
import UserWidget from '@/components/UserWidget.vue';
import LogoutWidget from '@/components/LogoutWidget.vue';
import Logo from '@/components/icons/Logo';
import CurrentClass from '@/components/school-class/CurrentClass';
@ -31,7 +32,6 @@
components: {
ContentNavigation,
UserWidget,
LogoutWidget,
BookNavigation,
Logo,
CurrentClass
@ -50,7 +50,8 @@
@import "@/styles/_mixins.scss";
.header-bar {
display: -ms-grid;
display: flex;
flex-direction: row;
@supports (display: grid) {
display: none;
@ -59,13 +60,14 @@
}
}
align-items: center;
justify-content: space-around;
justify-content: space-between;
background-color: $color-white;
grid-auto-rows: 50px;
width: 100%;
@include desktop {
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 50px;
grid-auto-rows: auto;
}
@ -115,6 +117,13 @@
-ms-grid-row-align: center;
-ms-grid-column-align: center;
}
&__logo-icon {
width: 212px;
height: 31px;
}
}
.user-header {

View File

@ -1,6 +1,6 @@
<template>
<div class="logout-widget">
<button class="logout-widget__logout" data-cy="logout" @click="logout()">Logout</button>
<a class="logout-widget__logout" data-cy="logout" @click="logout()">Logout</a>
</div>
</template>
@ -8,7 +8,6 @@
import LOGOUT_MUTATION from '@/graphql/gql/mutations/logoutUser.gql';
export default {
methods: {
logout() {
this.$apollo.mutate({
@ -23,6 +22,7 @@
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.logout-widget {
color: $color-silver-dark;
@ -30,15 +30,8 @@
align-items: center;
&__logout {
font-family: $sans-serif-font-family;
line-height: 16px;
margin: 0 15px 0 $large-spacing;
background: none;
color: inherit;
border: none;
padding: 0;
@include regular-text;
cursor: pointer;
outline: inherit;
}
}
</style>

View File

@ -1,24 +1,31 @@
<template>
<div class="mobile-header">
<router-link to="/" data-cy="mobile-home-link">
<logo></logo>
</router-link>
<a @click="showMobileNavigation">
<hamburger class="mobile-header__hamburger"></hamburger>
</a>
<router-link to="/" data-cy="mobile-home-link">
<logo></logo>
</router-link>
<user-widget v-bind="me"></user-widget>
</div>
</template>
<script>
import Logo from '@/components/icons/Logo';
import Hamburger from '@/components/icons/Hamburger';
import UserWidget from '@/components/UserWidget';
import me from '@/mixins/me';
export default {
mixins: [me],
components: {
Logo,
Hamburger
Hamburger,
UserWidget
},
methods: {

View File

@ -18,51 +18,5 @@
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.widget-popover {
position: absolute;
right: 0;
display: flex;
flex-direction: column;
background-color: $color-white;
padding: 20px;
z-index: 100;
@include widget-shadow;
&--mobile {
left: 0;
right: inherit;
}
}
.popover-links {
list-style: none;
display: grid;
&__link {
& > a {
display: inline-block;
color: $color-silver-dark;
font-family: $sans-serif-font-family;
font-size: toRem(14px);
line-height: 1.5;
padding: 5px 0;
cursor: pointer;
}
&--large {
line-height: 40px;
& > a, & {
@include small-text;
}
}
&--emph {
@include regular-text;
font-weight: 600;
}
}
}
</style>

View File

@ -4,18 +4,12 @@
<div class="mobile-navigation__close-button" @click="hideMobileNavigation">
<cross class="mobile-navigation__close-icon"></cross>
</div>
<div class="mobile-navigation__subnavigation"></div>
<div class="mobile-navigation__secondary">
<class-selection-widget :mobile="true" />
<user-widget class="mobile-navigation__user-widget" v-bind="me" :mobile="true"></user-widget>
</div>
</div>
</template>
<script>
import Cross from '@/components/icons/Cross';
import UserWidget from '@/components/UserWidget';
import LogoutWidget from '@/components/LogoutWidget';
import ContentNavigation from '@/components/ContentNavigation';
import ClassSelectionWidget from '@/components/school-class/ClassSelectionWidget';
@ -26,7 +20,6 @@
ContentNavigation,
Cross,
UserWidget,
LogoutWidget,
ClassSelectionWidget
},
@ -101,20 +94,5 @@
opacity: 0.5;
fill: $color-white;
}
&__secondary {
grid-area: s;
padding: $medium-spacing;
display: flex;
flex-direction: column;
}
&__user-widget {
margin-bottom: $small-spacing;
}
&__logout-widget {
margin-left: -$large-spacing;
}
}
</style>

View File

@ -42,30 +42,3 @@
}
}
</script>
<style lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.book-subnavigation {
&__item {
@include small-text;
margin-bottom: $small-spacing;
cursor: pointer;
color: $color-silver-dark;
&--mobile {
color: $color-white;
}
&:last-of-type {
margin-bottom: 0;
}
&--active {
color: $color-brand;
}
}
}
</style>

View File

@ -32,11 +32,13 @@
import ThinglinkBlock from '@/components/content-blocks/ThinglinkBlock';
import GeniallyBlock from '@/components/content-blocks/GeniallyBlock';
import SubtitleBlock from '@/components/content-blocks/SubtitleBlock';
import SectionTitleBlock from '@/components/content-blocks/SectionTitleBlock';
import ContentListBlock from '@/components/content-blocks/ContentListBlock';
import ModuleRoomSlug from '@/components/content-blocks/ModuleRoomSlug';
import Assignment from '@/components/content-blocks/assignment/Assignment';
import Survey from '@/components/content-blocks/SurveyBlock';
import Solution from '@/components/content-blocks/Solution';
import Instruction from '@/components/content-blocks/Instruction';
import BookmarkActions from '@/components/notes/BookmarkActions';
import {constructContentComponentBookmarkMutation} from '@/helpers/update-content-bookmark-mutation';
@ -56,11 +58,13 @@
'infogram_block': InfogramBlock,
'genially_block': GeniallyBlock,
'subtitle': SubtitleBlock,
'section_title': SectionTitleBlock,
'content_list': ContentListBlock,
'module_room_slug': ModuleRoomSlug,
'thinglink_block': ThinglinkBlock,
Survey,
Solution,
Instruction,
Assignment,
BookmarkActions
},
@ -102,6 +106,7 @@
.content-component {
position: relative;
&--bookmarked {
}

View File

@ -50,8 +50,7 @@
data() {
return {
height: 0,
// title: 'Zahlungsmittel'
height: 0
}
}
}
@ -61,16 +60,9 @@
@import "@/styles/_variables.scss";
.infogram-block {
/*padding: 8px 0;*/
/*font-family: $sans-serif-font-family;*/
/*font-size: 13px !important;*/
/*line-height: 15px !important;*/
/*text-align: center;*/
/*border-top: 1px solid #dadada;*/
/*margin: 0 30px;*/
margin-bottom: $large-spacing;
&__link {
/*color:#989898;*/
text-decoration: none;
cursor: pointer;
}

View File

@ -0,0 +1,47 @@
<template>
<div class="instruction" v-if="me.isTeacher">
<bulb-icon class="instruction__icon"></bulb-icon>
<a class="instruction__link" :href="value.url">{{text}}</a>
</div>
</template>
<script>
import me from '@/mixins/me';
import BulbIcon from '@/components/icons/BulbIcon';
export default {
props: ['value'],
mixins: [me],
components: {
BulbIcon
},
computed: {
text() {
return this.value.text ? this.value.text : 'Anweisungen'
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_mixins.scss";
.instruction {
margin-bottom: 1rem;
display: flex;
align-items: center;
&__icon {
width: 40px;
height: 40px;
margin-right: $small-spacing;
}
&__link {
@include heading-3;
}
}
</style>

View File

@ -0,0 +1,13 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<g id="shape">
<circle cx="50" cy="50" r="50" style="fill:#17a887"/>
<path
d="M57.96318,62.73515H41.99379A2.48236,2.48236,0,0,1,39.51288,60.34c-.06061-1.72061-.21515-2.61273-3.23576-5.60545a20.69086,20.69086,0,1,1,27.55152-.18485l-.27394.26848c-2.89273,2.86424-3.04424,3.76485-3.11091,5.52848A2.48231,2.48231,0,0,1,57.96318,62.73515ZM44.17652,57.7703H55.77409c.50667-2.1903,1.72788-3.94606,4.29636-6.48909l.317-.3103c.02364-.023.04727-.04545.07212-.06788a15.62483,15.62483,0,1,0-20.85788.14364c.03848.03333.07606.06848.11273.10424C42.38379,53.78848,43.65439,55.58424,44.17652,57.7703Z"
style="fill:#fff"/>
<path
d="M58.13591,83H41.86773a2.48255,2.48255,0,0,1-2.48242-2.48242V70.50909a2.48255,2.48255,0,0,1,2.48242-2.48242H58.13227a2.48229,2.48229,0,0,1,2.48242,2.48121l.00364,10.00848A2.482,2.482,0,0,1,58.13591,83ZM44.35015,78.03515H55.65227l-.00121-5.04364H44.35015Z"
style="fill:#fff"/>
</g>
</svg>
</template>

View File

@ -1,7 +1,7 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400">
<defs>
<clipPath id="clip-path">
<clipPath id="avatar-clip-path">
<circle class="cls-1" cx="200" cy="200" r="197"/>
</clipPath>
</defs>
@ -38,7 +38,7 @@
}
.cls-3 {
clip-path: url(#clip-path);
clip-path: url(#avatar-clip-path);
}
.cls-4 {

View File

@ -0,0 +1,84 @@
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 79.6006 25.5117">
<g id="bild_wortmarke">
<path d="M42.6597,6.811h8.1616V9.2915H45.6001v2.6211H50.041v2.46H45.6001v3.0009h5.4214V19.854H42.6597Z"/>
<path d="M54.9195,6.811h2.9404v5.0215h4.5005V6.811h2.9609V19.854H62.3604V14.4126H57.8599V19.854H54.9195Z"/>
<path
d="M69.6983,6.811h4.4609c2.7012,0,4.8018.7403,4.8018,3.2412a2.84374,2.84374,0,0,1-2.1807,2.8204v.08c1.8604.3399,2.8203,1.3204,2.8203,3.0606,0,2.6601-2.2402,3.8408-5.0605,3.8408H69.6983Zm4.3213,5.2618c1.4404,0,2.0605-.6202,2.0605-1.6006s-.6602-1.3809-2.041-1.3809H72.6397v2.9815Zm.2802,5.5009c1.5996,0,2.42-.6006,2.42-1.7802,0-1.1407-.7999-1.6407-2.42-1.6407H72.6397v3.4209Z"/>
<polygon class="cls-1" points="7.087 0 0 4.252 7.087 8.504 7.087 0"/>
<polygon class="cls-1" points="7.087 8.504 14.173 4.252 7.087 0 7.087 8.504"/>
<polygon class="cls-2" points="7.087 17.008 0 21.26 7.087 25.512 7.087 17.008"/>
<polygon class="cls-2" points="7.087 25.512 14.173 21.26 7.087 17.008 7.087 25.512"/>
<polygon class="cls-1" points="7.087 8.511 7.093 8.507 7.087 8.504 7.087 8.511"/>
<polygon class="cls-3" points="0 4.252 0 12.756 7.087 8.504 0 4.252"/>
<polygon class="cls-4" points="7.087 8.504 7.087 17.008 14.173 12.756 7.087 8.504"/>
<polygon class="cls-5" points="7.087 8.504 7.087 17.008 0 12.756 7.087 8.504"/>
<polygon class="cls-5" points="14.173 12.756 14.173 4.252 7.087 8.504 14.173 12.756"/>
<polygon class="cls-2" points="0 12.756 0 21.26 7.087 17.008 0 12.756"/>
<polygon class="cls-6" points="14.173 21.26 14.173 12.756 7.087 17.008 14.173 21.26"/>
<polygon class="cls-7" points="21.26 0 14.173 4.252 21.26 8.504 21.26 0"/>
<polygon class="cls-7" points="21.26 8.504 28.347 4.252 21.26 0 21.26 8.504"/>
<polygon class="cls-8" points="21.26 17.008 14.173 21.26 21.26 25.512 21.26 17.008"/>
<polygon class="cls-8" points="21.26 25.512 28.347 21.26 21.26 17.008 21.26 25.512"/>
<polygon class="cls-1" points="21.26 8.511 21.266 8.507 21.26 8.504 21.26 8.511"/>
<polygon class="cls-9" points="14.173 4.252 14.173 12.756 21.26 8.504 14.173 4.252"/>
<polygon class="cls-10" points="21.26 8.504 21.26 17.008 28.347 12.756 21.26 8.504"/>
<polygon class="cls-9" points="21.26 8.504 21.26 17.008 14.173 12.756 21.26 8.504"/>
<polygon class="cls-11" points="28.347 12.756 28.347 4.252 21.26 8.504 28.347 12.756"/>
<polygon class="cls-6" points="14.173 12.756 14.173 21.26 21.26 17.008 14.173 12.756"/>
<polygon class="cls-8" points="28.347 21.26 28.347 12.756 21.26 17.008 28.347 21.26"/>
<polyline class="cls-12"
points="26.794 11.486 26.794 14.04 23.815 14.04 23.815 17.02 21.26 17.02 21.26 14.04 18.28 14.04 18.28 11.486 21.26 11.486 21.26 8.506 23.814 8.506 23.815 11.486 26.794 11.486"/>
</g>
</svg>
</template>
<style scoped lang="scss">
.cls-1 {
fill: #723c83;
}
.cls-2 {
fill: #29c3ec;
}
.cls-3 {
fill: #956daf;
}
.cls-4 {
fill: #004b60;
}
.cls-5 {
fill: #3f2c7f;
}
.cls-6 {
fill: #007dad;
}
.cls-7 {
fill: #009a7e;
}
.cls-8 {
fill: #cbdd5f;
}
.cls-9 {
fill: #00553c;
}
.cls-10 {
fill: #c14451;
}
.cls-11 {
fill: #f9a134;
}
.cls-12 {
fill: #fff;
}
</style>

View File

@ -0,0 +1,47 @@
<template>
<svg id="Ebene_1" data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 147.39503 34.72434">
<circle class="cls-1" cx="17.36217" cy="17.36217" r="17.36217"/>
<path class="cls-1"
d="M52.4432,8.634a4.55121,4.55121,0,0,0-.89344-1.506,3.95842,3.95842,0,0,0-1.37354-.97187,4.42834,4.42834,0,0,0-1.7625-.34656,4.00352,4.00352,0,0,0-1.80914.40273,3.454,3.454,0,0,0-1.30783,1.14356h-.03922V2.59971H42.62491V17.82914h2.63262V10.86921a3.046,3.046,0,0,1,.17382-1.03228,2.49255,2.49255,0,0,1,.49812-.8468,2.33973,2.33973,0,0,1,.79169-.56277,2.52558,2.52558,0,0,1,1.03016-.20561,2.30456,2.30456,0,0,1,1.72223.68041,2.663,2.663,0,0,1,.66028,1.9236v7.00338h2.63262V10.60425A5.72892,5.72892,0,0,0,52.4432,8.634Z"/>
<path class="cls-1"
d="M65.73936,9.3865a5.357,5.357,0,0,0-1.081-1.8494A5.22188,5.22188,0,0,0,62.9096,6.278a5.72948,5.72948,0,0,0-2.37084-.46844,6.03155,6.03155,0,0,0-2.26911.41333,4.92935,4.92935,0,0,0-1.7625,1.19125,5.3972,5.3972,0,0,0-1.13508,1.91618,7.81512,7.81512,0,0,0-.40062,2.59977,7.81313,7.81313,0,0,0,.40062,2.59872A5.37548,5.37548,0,0,0,56.50715,16.445a4.91636,4.91636,0,0,0,1.7837,1.19338,6.37091,6.37091,0,0,0,2.33587.41121,6.1752,6.1752,0,0,0,1.95857-.29039,5.0312,5.0312,0,0,0,1.51557-.7917,4.95493,4.95493,0,0,0,1.09162-1.17005,5.74691,5.74691,0,0,0,.69-1.42442l.02013-.06041H63.05586l-.01378.01908a4.05,4.05,0,0,1-.95067.939,2.503,2.503,0,0,1-1.44243.3667,2.73105,2.73105,0,0,1-2.07515-.81289,3.29407,3.29407,0,0,1-.85635-2.07515h8.272l.00636-.03922c.01378-.089.02861-.19183.04345-.31053.01484-.1028.02968-.22151.04451-.354a4.07907,4.07907,0,0,0,.02332-.44725A6.72183,6.72183,0,0,0,65.73936,9.3865Zm-5.2006-1.16475a2.61117,2.61117,0,0,1,1.94373.71538,3.20654,3.20654,0,0,1,.87224,1.73071H57.7249a3.3678,3.3678,0,0,1,.94643-1.77416A2.62777,2.62777,0,0,1,60.53876,8.22175Z"/>
<path class="cls-1"
d="M79.14786,9.29748A5.456,5.456,0,0,0,78.0912,7.38236a4.5326,4.5326,0,0,0-1.61836-1.17112,5.23851,5.23851,0,0,0-2.072-.40167,4.12277,4.12277,0,0,0-2.06667.50342,4.59474,4.59474,0,0,0-1.37884,1.1531h-.05088l-.32431-1.4-.00741-.036h-2.1822V21.37068h2.63368v-4.8674h.03816a2.65765,2.65765,0,0,0,.45891.5066,3.83135,3.83135,0,0,0,.74824.514,4.59617,4.59617,0,0,0,.97081.38048,4.44481,4.44481,0,0,0,1.16051.1452,5.23834,5.23834,0,0,0,2.072-.40168,4.53245,4.53245,0,0,0,1.61836-1.17111,5.43932,5.43932,0,0,0,1.05666-1.91512,8.40143,8.40143,0,0,0,.37942-2.63157A8.41306,8.41306,0,0,0,79.14786,9.29748ZM73.95891,8.22175a2.87335,2.87335,0,0,1,1.14144.22786,2.62129,2.62129,0,0,1,.93266.68359,3.25549,3.25549,0,0,1,.63166,1.15522,5.2844,5.2844,0,0,1,.22892,1.64168,5.29386,5.29386,0,0,1-.22892,1.64169,3.25948,3.25948,0,0,1-.63166,1.15415,2.59368,2.59368,0,0,1-.93266.6836,2.97289,2.97289,0,0,1-2.28288,0,2.59373,2.59373,0,0,1-.93265-.6836,3.277,3.277,0,0,1-.63166-1.15521,5.28178,5.28178,0,0,1-.22893-1.64063,5.28409,5.28409,0,0,1,.22893-1.64168,3.27711,3.27711,0,0,1,.63166-1.15522,2.62134,2.62134,0,0,1,.93265-.68359A2.87342,2.87342,0,0,1,73.95891,8.22175Z"/>
<path class="cls-1"
d="M42.61643,23.24323h1.01v5.18046l3.29714-3.29714h1.27816L44.77,28.55829l3.63311,3.56634H47.125l-3.49851-3.43174v3.43174h-1.01Z"/>
<path class="cls-1"
d="M52.01023,32.25923a3.50763,3.50763,0,0,1-1.30571-.23529,2.72284,2.72284,0,0,1-1.01638-.69949,3.34743,3.34743,0,0,1-.66558-1.1372,5.14225,5.14225,0,0,1,0-3.12227,3.34743,3.34743,0,0,1,.66558-1.1372,2.723,2.723,0,0,1,1.01638-.69949,3.72016,3.72016,0,0,1,2.604,0,2.69623,2.69623,0,0,1,1.02274.69949,3.34936,3.34936,0,0,1,.66663,1.1372,5.16374,5.16374,0,0,1,0,3.12227,3.34936,3.34936,0,0,1-.66663,1.1372,2.69611,2.69611,0,0,1-1.02274.69949A3.52016,3.52016,0,0,1,52.01023,32.25923Zm0-.9422a2.21008,2.21008,0,0,0,.88814-.17487,1.92179,1.92179,0,0,0,.69949-.51826,2.489,2.489,0,0,0,.46421-.84044,4.05861,4.05861,0,0,0,0-2.31468,2.50459,2.50459,0,0,0-.46421-.84151,1.93408,1.93408,0,0,0-.69949-.51826,2.3428,2.3428,0,0,0-1.77628,0,1.94676,1.94676,0,0,0-.70055.51826,2.50476,2.50476,0,0,0-.46421.84151,4.08323,4.08323,0,0,0,0,2.31468,2.48917,2.48917,0,0,0,.46421.84044,1.93431,1.93431,0,0,0,.70055.51826A2.21008,2.21008,0,0,0,52.01023,31.317Z"/>
<path class="cls-1"
d="M56.86809,25.12655h.80759l.1346.94219h.06677a2.00568,2.00568,0,0,1,.83409-.84045,2.37269,2.37269,0,0,1,1.05029-.23528,2.14389,2.14389,0,0,1,1.18384.336,2.37008,2.37008,0,0,1,.83409.94219h.06783a2.25262,2.25262,0,0,1,.92841-.96869,2.69067,2.69067,0,0,1,1.29194-.30947,2.31173,2.31173,0,0,1,.94219.195,2.25742,2.25742,0,0,1,.77368.55853,2.62232,2.62232,0,0,1,.51826.88814,3.49864,3.49864,0,0,1,.18865,1.18384v4.3061h-1.01v-4.3061a1.9851,1.9851,0,0,0-.45042-1.4,1.52165,1.52165,0,0,0-1.1637-.48435,1.56955,1.56955,0,0,0-.66028.142,1.63624,1.63624,0,0,0-.53839.39638,1.8526,1.8526,0,0,0-.35611.5988,2.11158,2.11158,0,0,0-.12824.74719v4.3061h-1.009v-4.3061a1.98506,1.98506,0,0,0-.45043-1.4,1.52233,1.52233,0,0,0-1.16475-.48435,1.50178,1.50178,0,0,0-.63166.142,1.62552,1.62552,0,0,0-.5384.39638,2.07492,2.07492,0,0,0-.37094.5988,1.962,1.962,0,0,0-.141.74719v4.3061h-1.009Z"/>
<path class="cls-1"
d="M68.39055,25.12655h.80759l.1346.94219h.06677a2.34585,2.34585,0,0,1,.93583-.79381,3.313,3.313,0,0,1,2.56374-.04664,2.60919,2.60919,0,0,1,.95491.69949,3.36014,3.36014,0,0,1,.63272,1.1372,5.43759,5.43759,0,0,1,0,3.12227,3.36014,3.36014,0,0,1-.63272,1.1372,2.60908,2.60908,0,0,1-.95491.69949,3.06349,3.06349,0,0,1-1.21139.23529,2.92848,2.92848,0,0,1-1.31949-.27556,2.53882,2.53882,0,0,1-.90086-.7334h-.06783v3.02508h-1.009ZM71.55309,31.317a1.96128,1.96128,0,0,0,1.56114-.68571,2.99146,2.99146,0,0,0,.59138-2.0052,2.99149,2.99149,0,0,0-.59138-2.00521,2.11774,2.11774,0,0,0-3.12227,0,2.98588,2.98588,0,0,0-.59245,2.00521,2.98585,2.98585,0,0,0,.59245,2.0052A1.95829,1.95829,0,0,0,71.55309,31.317Z"/>
<path class="cls-1"
d="M79.36143,32.25923a3.5076,3.5076,0,0,1-1.30571-.23529,2.72284,2.72284,0,0,1-1.01638-.69949,3.34727,3.34727,0,0,1-.66558-1.1372,4.60854,4.60854,0,0,1-.2427-1.56113A4.6949,4.6949,0,0,1,76.3674,27.065a3.25231,3.25231,0,0,1,.65922-1.1372,2.73334,2.73334,0,0,1,1.0026-.69949A3.32709,3.32709,0,0,1,79.2936,24.993a3.047,3.047,0,0,1,1.4.302,3.11509,3.11509,0,0,1,.98882.7811,3.1694,3.1694,0,0,1,.585,1.04923,3.49088,3.49088,0,0,1,.18865,1.09693,2.59583,2.59583,0,0,1-.01271.2692c-.00954.08055-.018.15262-.02756.21515-.00848.07206-.018.13459-.0265.18865H77.14108a2.58155,2.58155,0,0,0,.67935,1.81655,2.13015,2.13015,0,0,0,1.541.60516,1.9818,1.9818,0,0,0,1.81655-1.009h1.07679a2.79418,2.79418,0,0,1-1.11706,1.46045A3.22194,3.22194,0,0,1,79.36143,32.25923Zm2.08575-4.23934a2.3453,2.3453,0,0,0-.69949-1.54735,2.23134,2.23134,0,0,0-2.90712,0,2.33547,2.33547,0,0,0-.69949,1.54735Z"/>
<path class="cls-1"
d="M84.99393,31.63392a1.70429,1.70429,0,0,1-.49176-1.258V26.06874H83.42538v-.94219h1.07679l.1346-1.88332h.87542v1.88332h1.81655v.94219H85.51219V30.3759a.77962.77962,0,0,0,.80653.80654h1.01v.94219H86.25195A1.70186,1.70186,0,0,1,84.99393,31.63392Z"/>
<path class="cls-1"
d="M91.58563,32.25923a3.50769,3.50769,0,0,1-1.30572-.23529,2.723,2.723,0,0,1-1.01638-.69949,3.34741,3.34741,0,0,1-.66557-1.1372,4.6083,4.6083,0,0,1-.2427-1.56113A4.6949,4.6949,0,0,1,88.5916,27.065a3.25231,3.25231,0,0,1,.65922-1.1372,2.73334,2.73334,0,0,1,1.0026-.69949A3.32709,3.32709,0,0,1,91.5178,24.993a3.047,3.047,0,0,1,1.4.302,3.11509,3.11509,0,0,1,.98882.7811,3.1694,3.1694,0,0,1,.585,1.04923,3.49088,3.49088,0,0,1,.18865,1.09693,2.59288,2.59288,0,0,1-.01272.2692c-.00953.08055-.018.15262-.02755.21515-.00848.07206-.018.13459-.0265.18865H89.36528a2.58155,2.58155,0,0,0,.67935,1.81655,2.13015,2.13015,0,0,0,1.541.60516,1.9818,1.9818,0,0,0,1.81655-1.009H94.479a2.79418,2.79418,0,0,1-1.11706,1.46045A3.22194,3.22194,0,0,1,91.58563,32.25923Zm2.08575-4.23934a2.3453,2.3453,0,0,0-.69949-1.54735,2.23134,2.23134,0,0,0-2.90712,0,2.33547,2.33547,0,0,0-.69949,1.54735Z"/>
<path class="cls-1"
d="M96.3745,25.12655h.8076l.13459.94219h.06677a1.9014,1.9014,0,0,1,.90828-.84045,2.84328,2.84328,0,0,1,1.11071-.23528,2.68728,2.68728,0,0,1,1.02909.195,2.43164,2.43164,0,0,1,.83409.55853,2.53811,2.53811,0,0,1,.55854.88814,3.27437,3.27437,0,0,1,.20242,1.18384v4.3061h-1.009v-4.3061a1.88054,1.88054,0,0,0-.49176-1.4,1.71981,1.71981,0,0,0-1.258-.48435,1.8029,1.8029,0,0,0-.74718.15474,2.014,2.014,0,0,0-.59881.41121,1.815,1.815,0,0,0-.39744.59881,1.88894,1.88894,0,0,0-.141.71963v4.3061h-1.009Z"/>
<path class="cls-1"
d="M104.7764,31.63392a1.7043,1.7043,0,0,1-.49177-1.258V26.06874h-1.07679v-.94219h1.07679l.1346-1.88332h.87542v1.88332h1.81656v.94219h-1.81656V30.3759a.77964.77964,0,0,0,.80654.80654h1.01v.94219h-1.07679A1.70184,1.70184,0,0,1,104.7764,31.63392Z"/>
<path class="cls-1"
d="M115.14105,32.25923a3.0872,3.0872,0,0,1-1.35234-.28192,2.34409,2.34409,0,0,1-.93478-.79487h-.06783l-.1346.94219h-.80759v-8.8814h1.01V26.002h.06677a2.54267,2.54267,0,0,1,.90192-.7334,2.91289,2.91289,0,0,1,1.31843-.27556,3.05625,3.05625,0,0,1,1.21139.23528,2.61284,2.61284,0,0,1,.956.69949,3.37627,3.37627,0,0,1,.63166,1.1372,5.43736,5.43736,0,0,1,0,3.12227,3.37627,3.37627,0,0,1-.63166,1.1372,2.61273,2.61273,0,0,1-.956.69949A3.05608,3.05608,0,0,1,115.14105,32.25923Zm-.1346-.9422a1.95833,1.95833,0,0,0,1.56114-.68571,2.98585,2.98585,0,0,0,.59245-2.0052,2.98588,2.98588,0,0,0-.59245-2.00521,2.11774,2.11774,0,0,0-3.12227,0,2.99144,2.99144,0,0,0-.59139,2.00521,2.99141,2.99141,0,0,0,.59139,2.0052A1.96127,1.96127,0,0,0,115.00645,31.317Z"/>
<path class="cls-1"
d="M120.392,24.19429a.69831.69831,0,0,1-.50448-.20136.66738.66738,0,0,1-.20878-.49813.69925.69925,0,0,1,.20242-.50448.68231.68231,0,0,1,.51084-.20878.66738.66738,0,0,1,.49813.20878.69925.69925,0,0,1,.20242.50448.68177.68177,0,0,1-.20242.49071A.66349.66349,0,0,1,120.392,24.19429Zm-.51084.93226h1.009v6.99808h-1.009Z"/>
<path class="cls-1" d="M123.03591,23.24323h1.01v8.8814h-1.01Z"/>
<path class="cls-1"
d="M128.79071,32.25923a3.05086,3.05086,0,0,1-1.21033-.23529,2.604,2.604,0,0,1-.956-.69949,3.36014,3.36014,0,0,1-.63272-1.1372,5.43759,5.43759,0,0,1,0-3.12227,3.36014,3.36014,0,0,1,.63272-1.1372,2.6041,2.6041,0,0,1,.956-.69949,3.051,3.051,0,0,1,1.21033-.23528,2.91444,2.91444,0,0,1,1.31949.27556,2.53874,2.53874,0,0,1,.90086.7334h.06783V23.24323h1.009v8.8814h-.80759l-.1346-.94219h-.06677a2.34,2.34,0,0,1-.93583.79487A3.084,3.084,0,0,1,128.79071,32.25923Zm.1346-.9422a1.95829,1.95829,0,0,0,1.56113-.68571,2.98585,2.98585,0,0,0,.59245-2.0052,2.98588,2.98588,0,0,0-.59245-2.00521,2.11772,2.11772,0,0,0-3.12226,0,2.99144,2.99144,0,0,0-.59139,2.00521,2.99141,2.99141,0,0,0,.59139,2.0052A1.96124,1.96124,0,0,0,128.92531,31.317Z"/>
<path class="cls-1"
d="M137.11233,32.25923a3.50763,3.50763,0,0,1-1.30571-.23529,2.72284,2.72284,0,0,1-1.01638-.69949,3.34743,3.34743,0,0,1-.66558-1.1372,4.60854,4.60854,0,0,1-.2427-1.56113,4.6949,4.6949,0,0,1,.23634-1.56114,3.25231,3.25231,0,0,1,.65922-1.1372,2.73334,2.73334,0,0,1,1.0026-.69949,3.32709,3.32709,0,0,1,1.26438-.23528,3.047,3.047,0,0,1,1.4.302,3.11524,3.11524,0,0,1,.98883.7811,3.16955,3.16955,0,0,1,.585,1.04923,3.49088,3.49088,0,0,1,.18865,1.09693,2.59583,2.59583,0,0,1-.01271.2692c-.00954.08055-.018.15262-.02756.21515-.00848.07206-.018.13459-.0265.18865H134.892a2.58155,2.58155,0,0,0,.67935,1.81655,2.13015,2.13015,0,0,0,1.541.60516,1.9818,1.9818,0,0,0,1.81655-1.009h1.0768a2.79424,2.79424,0,0,1-1.11707,1.46045A3.22194,3.22194,0,0,1,137.11233,32.25923Zm2.08575-4.23934a2.3453,2.3453,0,0,0-.69949-1.54735,2.23134,2.23134,0,0,0-2.90712,0,2.33547,2.33547,0,0,0-.69949,1.54735Z"/>
<path class="cls-1"
d="M141.74294,25.12655h.80759l.1346.94219h.06677a1.90132,1.90132,0,0,1,.90828-.84045,2.84327,2.84327,0,0,1,1.1107-.23528,2.68734,2.68734,0,0,1,1.0291.195,2.43174,2.43174,0,0,1,.83409.55853,2.53823,2.53823,0,0,1,.55853.88814,3.27415,3.27415,0,0,1,.20243,1.18384v4.3061h-1.009v-4.3061a1.88054,1.88054,0,0,0-.49177-1.4,1.71979,1.71979,0,0,0-1.258-.48435,1.8029,1.8029,0,0,0-.74718.15474,2.01427,2.01427,0,0,0-.59881.41121,1.81485,1.81485,0,0,0-.39743.59881,1.88875,1.88875,0,0,0-.141.71963v4.3061h-1.009Z"/>
<rect class="cls-1" x="42.62491" y="2.59971" width="2.63263" height="15.22942"/>
</svg>
</template>
<style scoped lang="scss">
.cls-1 {
fill: #002f6c;
}
</style>

View File

@ -1,37 +1,29 @@
<template>
<svg class="logo" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1350 250">
<path
d="M304.4,242.15a60,60,0,0,1-19.59-3.1,64.2,64.2,0,0,1-17.6-9.63l-2.94-2.22,21.17-34,3.58,3.21a21.91,21.91,0,0,0,6,4,15.21,15.21,0,0,0,5.81,1.09c4,0,6.51-1.44,8.08-4.68l1.15-2.19L263.73,85.72H313.8L334.27,143l17.38-57.3h48.8L353,208.39c-4.53,11.34-10.91,19.87-19,25.41h0C326,239.34,316,242.15,304.4,242.15Zm-29.33-17a53.63,53.63,0,0,0,12.38,6.3,51.94,51.94,0,0,0,17,2.66c10,0,18.42-2.33,25.12-6.94h0c6.71-4.62,12.1-11.92,16-21.71L388.67,93.79h-31l-22.74,75-26.79-75H275.94L319,195l-2.88,5.47c-2.87,5.92-8.18,9.11-15.29,9.11a23.28,23.28,0,0,1-8.88-1.69,24.83,24.83,0,0,1-4.58-2.53Z"
style="fill:#36c0a1"/>
<path
d="M458.66,113a12.63,12.63,0,0,0-6.43,1.39,4.55,4.55,0,0,0-2.36,4.18q0,3.22,4.4,5.25a93.59,93.59,0,0,0,14,4.61,178.08,178.08,0,0,1,21.33,7.29,40.28,40.28,0,0,1,14.79,11q6.32,7.39,6.33,19,0,17.8-14,28.19t-37.19,10.4A102.76,102.76,0,0,1,430,200.15a84.64,84.64,0,0,1-25.4-12.33l13.29-27.22a97.33,97.33,0,0,0,21.76,10.72A64.21,64.21,0,0,0,460.16,175a14.94,14.94,0,0,0,7.07-1.39,4.33,4.33,0,0,0,2.57-4q0-3.22-4.18-5.25a84.51,84.51,0,0,0-13.83-4.61A157.5,157.5,0,0,1,431,152.67a40,40,0,0,1-14.58-10.93q-6.22-7.29-6.22-18.86,0-18,13.72-28.51t36-10.5q26.79,0,51.23,14.15l-14.36,27.22Q473,113,458.66,113Z"
style="fill:#36c0a1"/>
<path d="M604.69,202.4l-21.22-40.51-8.79,9.22v31.3h-43.3V43.35h43.3v77.38l32.15-34.94h48.87l-42.66,45,42.87,71.6Z"
style="fill:#36c0a1"/>
<path
d="M712.25,36.49q6.22,6.22,6.22,16.08t-6.22,16.08q-6.22,6.22-16.08,6.22T680,68.64q-6.33-6.21-6.32-16.08T680,36.49q6.32-6.21,16.18-6.22T712.25,36.49Zm-37.51,49.3H718V202.4h-43.3Z"
style="fill:#36c0a1"/>
<path d="M748.47,43.35h43.3V202.4h-43.3Z" style="fill:#36c0a1"/>
<path d="M823.5,43.35h43.3V202.4H823.5Z" style="fill:#36c0a1"/>
<path
d="M1002.06,91.79A50.33,50.33,0,0,1,1021,113q6.75,13.72,6.75,31.73,0,17.8-6.54,31.19a48.35,48.35,0,0,1-18.54,20.69q-12,7.29-27.87,7.29A44,44,0,0,1,956.19,200a40.21,40.21,0,0,1-14.36-11.15v13.5h-43.3V43.35h43.3V99.29a38.85,38.85,0,0,1,13.93-11.15,41.53,41.53,0,0,1,18-3.86Q989.85,84.29,1002.06,91.79Zm-23.8,70.63q5.79-7.18,5.79-18.76t-5.79-18.76a18.82,18.82,0,0,0-15.43-7.18,18.59,18.59,0,0,0-15.22,7.18q-5.79,7.19-5.79,18.76t5.79,18.76a18.58,18.58,0,0,0,15.22,7.18A18.8,18.8,0,0,0,978.27,162.42Z"
style="fill:#36c0a1"/>
<path
d="M1142.8,91.69a54.24,54.24,0,0,1,22.62,20.9q8,13.5,8,31.51,0,17.8-8,31.4a54,54,0,0,1-22.62,21q-14.58,7.4-34.08,7.4t-34.19-7.4a53.86,53.86,0,0,1-22.73-21q-8-13.61-8-31.4,0-18,8-31.51a54.08,54.08,0,0,1,22.73-20.9q14.68-7.4,34.19-7.4T1142.8,91.69Zm-49.52,34.08q-5.79,7.18-5.79,18.76,0,11.79,5.79,18.86a18.92,18.92,0,0,0,15.43,7.07,18.7,18.7,0,0,0,15.22-7.07q5.79-7.07,5.79-18.86,0-11.58-5.79-18.76a18.6,18.6,0,0,0-15.22-7.18A18.81,18.81,0,0,0,1093.28,125.77Z"
style="fill:#36c0a1"/>
<path
d="M1176.45,85.79h49.73L1242.26,116l18-30.23h47.16L1271,142.6l39,59.81h-49.73l-18-33-20.58,33h-47.59l39-59.59Z"
style="fill:#36c0a1"/>
<path
d="M245,105.8A38.35,38.35,0,0,0,229.9,89.74h0a46.56,46.56,0,0,0-46.21,1.09A41.77,41.77,0,0,0,171.45,103a38.76,38.76,0,0,0-11.67-12,42.9,42.9,0,0,0-24.06-6.82,44.09,44.09,0,0,0-21.4,5.16,41.05,41.05,0,0,0-8.13,5.83v-9.4H58V201.83h48.19V144.37c0-5.32,1.23-9.42,3.77-12.55a11.7,11.7,0,0,1,9.27-4.46,9.48,9.48,0,0,1,7.75,3.35c2.09,2.45,3.11,5.75,3.11,10.09v61h48.19V144.37c0-5.26,1.24-9.49,3.69-12.59a11.44,11.44,0,0,1,9.15-4.43,9.48,9.48,0,0,1,7.75,3.35c2.09,2.45,3.11,5.75,3.11,10.09v61h48.19V129.28A51.17,51.17,0,0,0,245,105.8Zm-2.87,88h-32v-53c0-6.25-1.7-11.41-5-15.33a17.51,17.51,0,0,0-14-6.18h0a19.38,19.38,0,0,0-15.37,7.49c-3.61,4.55-5.44,10.48-5.44,17.6v49.39h-32v-53c0-6.25-1.7-11.41-5-15.33a17.53,17.53,0,0,0-14-6.18h0a19.66,19.66,0,0,0-15.44,7.45c-3.69,4.56-5.57,10.49-5.57,17.63v49.39h-32v-100h32v18.16h5.19l2.25-3.54a34.63,34.63,0,0,1,12.63-12,36.13,36.13,0,0,1,17.53-4.17,35,35,0,0,1,19.62,5.49,31.51,31.51,0,0,1,12.17,15.38l.46,1.18h6.52l.45-1a36.75,36.75,0,0,1,50.91-16.55,30,30,0,0,1,11.93,12.74,43.2,43.2,0,0,1,4.33,19.81Z"
style="fill:#36c0a1"/>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 965 159" class="logo">
<path class="cls-1"
d="M187.19877,158.76991a44.9261,44.9261,0,0,1-14.89082-2.35518,49.72607,49.72607,0,0,1-13.37134-7.29346l-2.20323-1.67142,16.1064-25.831,2.73505,2.43115a16.48614,16.48614,0,0,0,4.55841,3.03894,12.27557,12.27557,0,0,0,4.40646.83572c3.03894,0,4.93828-1.06363,6.15386-3.57076l.83571-1.67141L156.27756,39.94731H194.3403l15.57457,43.53283,13.21939-43.53283h37.07507l-36.08742,93.21951c-3.41881,8.585-8.28111,15.11873-14.435,19.29728h0C203.60906,156.64265,196.0117,158.76991,187.19877,158.76991Zm-22.26024-12.9155a42.27771,42.27771,0,0,0,9.42072,4.78634,41.3796,41.3796,0,0,0,12.9155,2.05128c7.59735,0,13.97912-1.74739,19.06936-5.24217h0c5.09023-3.49479,9.1928-9.04084,12.15576-16.48625l32.7446-84.86243h-23.5518l-17.246,56.98015L190.08578,46.10118H165.62229l32.66862,76.8852-2.20323,4.17854c-2.20323,4.48243-6.22984,6.9136-11.62394,6.9136a18.75655,18.75655,0,0,1-6.76164-1.29155,22.3379,22.3379,0,0,1-3.49479-1.89934Z"/>
<path class="cls-1"
d="M142.0705,55.218a29.671,29.671,0,0,0-11.472-12.23174h0a35.49322,35.49322,0,0,0-35.09977.83571A30.81285,30.81285,0,0,0,86.23,53.09073a29.93237,29.93237,0,0,0-8.8889-9.11682A32.47292,32.47292,0,0,0,59.03143,38.8077a33.62833,33.62833,0,0,0-16.25834,3.95063,32.37806,32.37806,0,0,0-6.15385,4.40646V40.02328H0v88.20527H36.61924V84.54377c0-4.0266.91168-7.14151,2.887-9.57267a9.08143,9.08143,0,0,1,7.06555-3.41881,7.19568,7.19568,0,0,1,5.92593,2.58309c1.59545,1.82336,2.35519,4.40647,2.35519,7.67333v46.34386H91.47214V84.54377c0-4.0266.91168-7.21749,2.811-9.57267a8.59712,8.59712,0,0,1,6.9136-3.34284,7.1957,7.1957,0,0,1,5.92594,2.5831c1.59545,1.82336,2.35518,4.40647,2.35518,7.67333v46.34386h36.61924V73.14774A40.46686,40.46686,0,0,0,142.0705,55.218Zm-2.20323,66.85671H115.55574v-40.266c0-4.71036-1.29155-8.661-3.79867-11.624a13.29891,13.29891,0,0,0-10.6363-4.71035h0a14.71867,14.71867,0,0,0-11.69992,5.698c-2.73505,3.49479-4.10256,7.97722-4.10256,13.37135v37.53093H61.00676v-40.266c0-4.71036-1.29155-8.661-3.79868-11.62395a13.29886,13.29886,0,0,0-10.63629-4.71036h0a14.874,14.874,0,0,0-11.69993,5.622c-2.811,3.49478-4.25451,7.97722-4.25451,13.37134v37.53092H6.30582V46.0252H30.61735V59.85238H34.568l1.67141-2.65907a26.852,26.852,0,0,1,9.57267-9.11683A27.91925,27.91925,0,0,1,59.10742,44.8856a26.47638,26.47638,0,0,1,14.89082,4.17854A23.86631,23.86631,0,0,1,83.267,60.76407l.37987.91168h4.93828L88.889,60.916A27.95184,27.95184,0,0,1,126.0401,47.54467c.53181.22792.98766.53181,1.51947.75974a22.60065,22.60065,0,0,1,9.04085,9.64863,32.40876,32.40876,0,0,1,3.26686,15.04276Z"/>
<path class="cls-1"
d="M360.27637,63.88867h-.00049c-8.79639-5.28613-20.01465-7.7207-29.91211-9.86816-12.25732-2.66016-22.84229-4.95606-22.84229-11.85254,0-4.76172,3.2959-10.4375,18.99707-10.4375,10.56348,0,21.68165,3.09668,33.04541,9.20215l.33692.18066,10.70361-25.7959-.2622-.15234c-11.499-6.666-27.40967-10.48926-43.65284-10.48926-16.82812,0-30.69433,3.96973-40.10058,11.48047a34.38057,34.38057,0,0,0-13.31055,27.72363c0,12.0918,4.93555,20.9834,15.08936,27.18262,8.73877,5.333,19.92431,7.832,29.793,10.03711,12.4795,2.78711,23.24659,5.19141,23.24659,12.42187,0,6.24414-6.44922,9.41016-19.168,9.41016a75.23455,75.23455,0,0,1-39.35205-11.75293l-.34033-.22559-11.40967,25.627.23437.16406c11.54395,8.04395,31.44336,13.24219,50.6958,13.24219,16.77,0,30.63672-4.00684,40.10108-11.58789A34.60313,34.60313,0,0,0,375.479,90.95312C375.479,78.88672,370.50635,70.03418,360.27637,63.88867Z"/>
<path class="cls-1"
d="M452.96851,77.98757l37.01587-38.16839H451.21527L421.62593,68.64681V7.84824H389.22977V128.48585h32.39616V106.62707l7.86292-8.003,23.88936,29.86182H492.7151Z"/>
<rect class="cls-1" x="500.00637" y="39.81918" width="32.39617" height="88.66666"/>
<rect class="cls-1" x="551.47678" y="7.84824" width="32.39617" height="120.63761"/>
<rect class="cls-1" x="602.9472" y="7.84824" width="32.39617" height="120.63761"/>
<path class="cls-1"
d="M709.94,38.3811c-9.53615,0-17.30258,2.56053-23.12619,7.61709v-38.15H654.41762V128.48585h30.9576v-7.05418c5.79209,5.70967,13.85913,8.49275,24.56476,8.49275a42.82556,42.82556,0,0,0,30.79226-12.38954c8.33566-8.422,12.74155-20.02118,12.74155-33.54237,0-13.44264-4.40686-24.96622-12.74445-33.32515C732.82666,42.74481,721.89218,38.3811,709.94,38.3811Zm-6.39428,65.38143c-10.45545,0-17.211-7.76012-17.211-19.77,0-11.81546,6.7555-19.44953,17.211-19.44953,10.45593,0,17.21191,7.63407,17.21191,19.44953C720.75761,96.00241,714.00163,103.76253,703.5457,103.76253Z"/>
<path class="cls-1"
d="M847.31484,51.174c-9.04355-8.24935-21.78266-12.79294-35.87065-12.79294-28.92944,0-49.92712,19.18237-49.92712,45.61141,0,26.61474,20.99768,45.93191,49.92712,45.93191,14.08605,0,26.82614-4.58,35.87307-12.89573,9.06342-8.3308,14.055-20.06336,14.055-33.03618C861.37228,71.09873,856.37971,59.44326,847.31484,51.174Zm-35.87065,52.58849c-10.45544,0-17.211-7.76012-17.211-19.77,0-11.81546,6.75551-19.44953,17.211-19.44953,10.45593,0,17.21192,7.63407,17.21192,19.44953C828.65611,96.00241,821.90012,103.76253,811.44419,103.76253Z"/>
<polygon class="cls-1"
points="931.16 83.038 963.901 39.819 929.221 39.819 913.766 60.992 898.929 39.819 862.189 39.819 894.901 84.143 861.194 128.486 896.678 128.486 912.761 106.526 927.762 128.486 965 128.486 931.16 83.038"/>
<path class="cls-1"
d="M527.91913,4.4834a15.80713,15.80713,0,0,1,4.4834,11.64237,15.92237,15.92237,0,0,1-4.4834,11.64238c-2.96486,3.03714-6.86973,4.4834-11.64236,4.4834a16.09319,16.09319,0,0,1-11.7147-4.4834,15.5782,15.5782,0,0,1-4.5557-11.64238,15.69049,15.69049,0,0,1,4.5557-11.64237A16.09313,16.09313,0,0,1,516.27677,0C521.1217,0,524.95427,1.44626,527.91913,4.4834Z"/>
</svg>
</template>
<style scoped lang="scss">
.logo {
width: 250px;
height: 48px;
<style scoped>
.cls-1 {
fill: #17a887;
}
</style>

View File

@ -31,7 +31,6 @@
<script>
import ObjectiveGroups from '@/components/objective-groups/ObjectiveGroups.vue';
import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl.vue';
import AddObjectiveGroupButton from '@/components/AddObjectiveGroupButton';
import Chapter from '@/components/Chapter.vue';
import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
@ -49,7 +48,6 @@
BookmarkActions,
ObjectiveGroups,
ObjectiveGroupControl,
AddObjectiveGroupButton,
Chapter
},

View File

@ -164,7 +164,7 @@
display: none;
width: 100%;
box-sizing: border-box;
z-index: 90;
z-index: 11;
background-color: $color-white;
border-top: 1px solid $color-silver;

View File

@ -1,107 +0,0 @@
<template>
<objective-group-form
:title="title"
:objectives="objectives"
@save="saveObjectiveGroup"
@hide="hideModal"
></objective-group-form>
</template>
<script>
import Modal from '@/components/Modal';
import ObjectiveGroupForm from '@/components/objective-groups/ObjectiveGroupForm';
import AddContentElement from '@/components/AddContentElement';
import UPDATE_OBJECTIVE_GROUP_MUTATION from '@/graphql/gql/mutations/updateObjectiveGroup.gql';
import MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
import OBJECTIVE_GROUP_QUERY from '@/graphql/gql/objectiveGroupQuery.gql';
export default {
components: {
AddContentElement,
Modal,
ObjectiveGroupForm
},
computed: {
title() {
if (this.$store.state.objectiveGroupType === 'society') {
return 'Gesellschaft';
}
return 'Sprache & Kommunikation';
},
objectives() {
return this.objectiveGroup.objectives.edges.map(edge => edge.node)
}
},
methods: {
saveObjectiveGroup(objectives) {
const objectiveGroup = {
id: this.$store.state.currentObjectiveGroup,
objectives,
};
this.$apollo.mutate({
mutation: UPDATE_OBJECTIVE_GROUP_MUTATION,
variables: {
input: {
objectiveGroup
}
},
// todo: make update work
// update: (store, {data: {addObjectiveGroup: {objectiveGroup}}}) => {
// const query = MODULE_DETAILS_QUERY;
// const variables = {slug: this.$route.params.slug};
// const data = store.readQuery({query, variables});
// debugger;
// if (data.module && data.module.objectiveGroups) {
// data.module.objectiveGroups.edges.push({
// node: objectiveGroup,
// __typename: 'ObjectiveGroupNode'
// });
// store.writeQuery({query, variables, data});
// }
//
// }
refetchQueries: [{
query: MODULE_DETAILS_QUERY,
variables: {
slug: this.$route.params.slug
}
}]
}).then(() => {
this.hideModal();
});
},
hideModal() {
this.$store.dispatch('hideModal');
},
},
apollo: {
objectiveGroup() {
return {
query: OBJECTIVE_GROUP_QUERY,
variables: {
id: this.$store.state.currentObjectiveGroup
}
}
}
},
data() {
return {
objectiveGroup: {
objectives: {
edges: []
}
}
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -1,91 +0,0 @@
<template>
<objective-group-form
:title="title"
:objectives="objectives"
@save="saveObjectiveGroup"
@hide="hideModal"
></objective-group-form>
</template>
<script>
import Modal from '@/components/Modal';
import ObjectiveGroupForm from '@/components/objective-groups/ObjectiveGroupForm';
import AddContentElement from '@/components/AddContentElement';
import NEW_OBJECTIVE_GROUP_MUTATION from '@/graphql/gql/mutations/addObjectiveGroup.gql';
import MODULE_DETAILS_QUERY from '@/graphql/gql/moduleDetailsQuery.gql';
export default {
components: {
AddContentElement,
Modal,
ObjectiveGroupForm
},
computed: {
title() {
if (this.$store.state.objectiveGroupType === 'society') {
return 'Gesellschaft';
}
return 'Sprache & Kommunikation';
}
},
methods: {
saveObjectiveGroup(objectives) {
const objectiveGroup = {
title: this.$store.state.objectiveGroupType,
module: this.$store.state.parentModule,
objectives,
};
this.$apollo.mutate({
mutation: NEW_OBJECTIVE_GROUP_MUTATION,
variables: {
input: {
objectiveGroup
}
},
// todo: make update work
// update: (store, {data: {addObjectiveGroup: {objectiveGroup}}}) => {
// const query = MODULE_DETAILS_QUERY;
// const variables = {slug: this.$route.params.slug};
// const data = store.readQuery({query, variables});
// debugger;
// if (data.module && data.module.objectiveGroups) {
// data.module.objectiveGroups.edges.push({
// node: objectiveGroup,
// __typename: 'ObjectiveGroupNode'
// });
// store.writeQuery({query, variables, data});
// }
//
// }
refetchQueries: [{
query: MODULE_DETAILS_QUERY,
variables: {
slug: this.$route.params.slug
}
}]
}).then(() => {
this.hideModal();
});
},
hideModal() {
this.$store.dispatch('hideModal');
},
},
data() {
return {
objectives: [
{},
]
}
}
}
</script>
<style scoped lang="scss">
</style>

View File

@ -56,12 +56,6 @@
return this.me.selectedClass;
},
},
methods: {
editObjectiveGroup() {
this.$store.dispatch('editObjectiveGroup', this.group.id);
}
}
}
</script>

View File

@ -1,64 +0,0 @@
<template>
<modal class="objective-group-form">
<template slot="header">
<h4 class="objective-group-form__heading">Lernziele: {{title}}</h4>
</template>
<objective-form
:objective="objective"
v-for="(objective, index) in initialObjectives"
@input="updateObjective($event, index)"
@delete="removeObjective(index)"
:key="index"></objective-form>
<add-content-element @add-element="addObjective"></add-content-element>
<div slot="footer">
<a class="button button--primary" data-cy="modal-save-button"
@click="$emit('save', initialObjectives)">Speichern</a>
<a class="button" @click="$emit('hide')">Abbrechen</a>
</div>
</modal>
</template>
<script>
import Modal from '@/components/Modal';
import ObjectiveForm from '@/components/objective-groups/ObjectiveForm';
import AddContentElement from '@/components/AddContentElement';
export default {
props: ['title', 'objectives'],
components: {
AddContentElement,
Modal,
ObjectiveForm
},
methods: {
addObjective() {
this.initialObjectives.push({});
},
updateObjective(text, index) {
this.initialObjectives.splice(index, 1, {text});
},
removeObjective(index) {
this.initialObjectives.splice(index, 1);
}
},
data() {
return {
initialObjectives: this.objectives
}
}
}
</script>
<style scoped lang="scss">
.objective-group-form {
&__heading {
margin-bottom: 0;
}
}
</style>

View File

@ -0,0 +1,109 @@
<template>
<div class="school-class">
<h2 class="school-class__heading"><span class="school-class__name" data-cy="school-class-name">{{name}}</span>
<edit-class-name v-if="teacher" @edit="editClassName"></edit-class-name>
</h2>
<div class="school-class__members school-class-members">
<ul class="school-class-members__list simple-list simple-list--active" data-cy="active-class-members-list">
<li
class="simple-list__item member-item"
data-cy="school-class-member"
v-for="member in activeMembers"
:key="member.id">
<span class="member-item__name">{{fullName(member)}}</span>
<span class="member-item__role">{{role(member)}}</span>
<!-- <a-->
<!-- class="member-item__action simple-list__action"-->
<!-- data-cy="remove-from-class"-->
<!-- v-if="teacher"-->
<!-- @click="$emit('remove', member)">Deaktivieren</a>-->
</li>
</ul>
<!-- <template v-if="inactiveMembers.length">-->
<!-- <h3 class="school-class__inactive-heading">Deaktivierte Personen</h3>-->
<!-- <ul data-cy="inactive-class-members-list" class="simple-list simple-list&#45;&#45;inactive">-->
<!-- <li-->
<!-- class="simple-list__item member-item"-->
<!-- data-cy="school-class-member"-->
<!-- v-for="member in inactiveMembers"-->
<!-- :key="member.id">-->
<!-- <span class="member-item__name">{{fullName(member)}}</span>-->
<!-- <span class="member-item__role">{{role(member)}}</span>-->
<!-- <a-->
<!-- class="member-item__action simple-list__action"-->
<!-- data-cy="add-to-class"-->
<!-- v-if="teacher"-->
<!-- @click="$emit('add', member)">Aktivieren</a>-->
<!-- </li>-->
<!-- </ul>-->
<!-- </template>-->
</div>
</div>
</template>
<script>
import EditClassName from '@/components/school-class/EditClassName';
export default {
props: ['members', 'name', 'teacher', 'id'],
components: {
EditClassName
},
methods: {
fullName(member) {
return `${member.firstName} ${member.lastName}`;
},
role({isTeacher}) {
return isTeacher ? 'Lehrperson' : 'Schüler';
},
editClassName() {
this.$store.dispatch('editClassName');
}
},
computed: {
activeMembers() {
return this.members.filter(member => member.active)
},
inactiveMembers() {
return this.members.filter(member => !member.active)
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.school-class {
&__inactive-heading {
@include heading-4;
margin-bottom: $small-spacing;
}
&__name {
@include heading-2;
}
}
.member-item {
&__name {
font-family: $sans-serif-font-family;
font-weight: $font-weight-bold;
flex: 2 1 auto;
}
&__role {
flex: 0 1 110px;
text-align: right;
}
&__action {
flex: 0 1 110px;
padding-left: $large-spacing;
}
}
</style>

View File

@ -1,59 +0,0 @@
<template>
<div class="schoolclass">
<h2 class="schoolclass__name">{{name}}</h2>
<div class="schoolclass__members schoolclass-members">
<ul class="schoolclass-members__list members-list">
<li v-for="user in users" :key="user.id" class="members-list__item">
<p class="member-item"><span class="member-item__name">{{fullName(user)}}</span> <span class="member-item__role">{{role(user)}}</span></p>
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['users', 'name'],
methods: {
fullName (user) {
return `${user.firstName} ${user.lastName}`;
},
role ({permissions}) {
return permissions.indexOf('users.can_manage_school_class_content') > -1 ? 'Lehrperson' : '';
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
$height: 52px;
.members-list {
&__item {
line-height: $height;
height: $height;
border-bottom: 1px solid $color-silver-dark;
}
}
.member-item {
line-height: $height;
height: $height;
display: flex;
flex-direction: row;
justify-content: space-between;
&__name {
font-family: $sans-serif-font-family;
font-weight: $font-weight-bold;
}
&__role {
padding-right: $medium-spacing;
}
}
</style>

View File

@ -0,0 +1,115 @@
<template>
<modal class="deactivate-user" :hide-header="true" :small="true">
<h3 class="deactivate-user__heading">
<template v-if="myself">
Mich
</template>
<template v-else>
Person
</template>
deaktivieren
</h3>
<p class="deactivate-user__text deactivate-user__paragraph">
<template v-if="myself">
Möchten Sie die Klasse <strong class="deactivate-user__text--strong">{{schoolClass}}</strong> verlassen?
</template>
<template v-else>
Möchten Sie <strong
class="deactivate-user__text--strong">{{name}}</strong> in der
Klasse
<strong class="deactivate-user__text--strong">{{schoolClass}}</strong> deaktivieren?
</template>
</p>
<ul class="deactivate-user__list">
<li class="deactivate-user__text deactivate-user__list-item">
<template v-if="myself">
Sie können
</template>
<template v-else>
Diese Person kann
</template>
in Zukunft keine Inhalte mehr erfassen, bearbeiten und teilen.
</li>
<li class="deactivate-user__text deactivate-user__list-item">
<template v-if="myself">
Sie können
</template>
<template v-else>
Diese Person kann
</template>
weiterhin Module und Instrumente lesen.
</li>
<li class="deactivate-user__text deactivate-user__list-item">
<template v-if="myself">
Sie können der Klasse jederzeit wieder beitreten.
</template>
<template v-else>
Sie können diese Person jederzeit wieder aktivieren.
</template>
</li>
</ul>
<div slot="footer">
<a class="button button--primary" data-cy="modal-save-button" v-on:click="confirm">Speichern</a>
<a class="button" v-on:click="cancel">Abbrechen</a>
</div>
</modal>
</template>
<script>
import Modal from '@/components/Modal';
export default {
components: {
Modal
},
computed: {
myself() {
return this.$modal.state.payload.myself;
},
name() {
return this.$modal.state.payload.name;
},
schoolClass() {
return this.$modal.state.payload.className;
}
},
methods: {
confirm() {
this.$modal.confirm();
},
cancel() {
this.$modal.cancel();
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.deactivate-user {
&__heading {
margin-bottom: $medium-spacing;
}
&__list {
padding-left: $medium-spacing;
}
&__list-item {
list-style: disc;
}
&__text {
@include regular-text;
margin-bottom: $medium-spacing;
&--strong {
font-weight: 600;
}
}
}
</style>

View File

@ -1,7 +1,6 @@
<template>
<div class="profile">
<h1 class="profile__header">Profil</h1>
<h2 class="profile__avatar profile-avatar">Profilbild</h2>
<h1 class="profile__header">Profilbild</h1>
<div class="profile-avatar" v-if="me.avatarUrl" >
<div class="profile-avatar__image">
<avatar :avatarUrl="me.avatarUrl" />

View File

@ -1,5 +1,5 @@
<template>
<div class="profile-sidebar" v-if="sidebar.open">
<div class="profile-sidebar" v-if="sidebar.open" v-click-outside="closeSidebar">
<a class="profile-sidebar__close-link" @click="closeSidebar">
<cross class="profile-sidebar__close-icon"></cross>
</a>
@ -10,14 +10,22 @@
<div class="profile-sidebar__item">
<h3 class="profile-sidebar__subtitle">Klasse</h3>
<class-selection-widget></class-selection-widget>
<router-link :to="{name: 'my-classes'}" class="profile-sidebar__link">Klassenliste anzeigen</router-link>
<div @click="closeSidebar">
<router-link :to="{name: 'my-class'}" class="profile-sidebar__link">Klassenliste anzeigen</router-link>
</div>
</div>
<div class="profile-sidebar__item" @click="closeSidebar">
<router-link :to="{name:'join-class'}" class="profile-sidebar__link">Zugangscode eingeben</router-link>
<router-link :to="{name:'join-class'}" data-cy="join-class-link" class="profile-sidebar__link">Zugangscode
eingeben
</router-link>
</div>
<div class="profile-sidebar__item" @click="logout">
<a class="profile-sidebar__link">Logout</a>
<div class="profile-sidebar__item">
<logout-widget></logout-widget>
</div>
<p class="profile-sidebar__support">
Supportanfragen: rahel.wenger@hep-verlag.ch
</p>
</div>
</template>
@ -25,49 +33,20 @@
import ProfileWidget from '@/components/profile/ProfileWidget';
import Cross from '@/components/icons/Cross';
import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
import TOGGLE_SIDEBAR from '@/graphql/gql/local/mutations/toggleSidebar.gql';
import LOGOUT_MUTATION from '@/graphql/gql/mutations/logoutUser.gql';
import ClassSelectionWidget from '@/components/school-class/ClassSelectionWidget';
import sidebarMixin from '@/mixins/sidebar';
import LogoutWidget from '@/components/LogoutWidget';
export default {
components: {
LogoutWidget,
ClassSelectionWidget,
ProfileWidget,
Cross
},
methods: {
closeSidebar() {
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: false
}
});
},
logout() {
this.$apollo.mutate({
mutation: LOGOUT_MUTATION,
}).then(({data}) => {
if (data.logout.success) {
location.replace('/logout')
}
});
}
},
apollo: {
sidebar: {
query: SIDEBAR
}
},
data: () => ({
sidebar: {
open: false
}
})
mixins: [sidebarMixin],
}
</script>
@ -82,10 +61,16 @@
right: 0;
top: 0;
bottom: 0;
width: 333px;
height: 100vh;
background-color: $color-white;
z-index: 10;
z-index: 15;
box-shadow: 0 3px 9px 0 rgba(0, 0, 0, 0.12);
overflow-y: scroll;
width: 100%;
@include desktop {
width: 333px;
}
display: flex;
flex-direction: column;
@ -117,5 +102,11 @@
width: 40px;
height: 40px;
}
&__support {
padding: $small-spacing;
@include regular-text;
color: $color-silver-dark;
}
}
</style>

View File

@ -38,6 +38,7 @@
&__name {
@include heading-3;
text-align: center;
margin-bottom: $small-spacing;
}
&__avatar {

View File

@ -2,7 +2,8 @@
<div class="class-selection" v-if="currentClassSelection">
<div data-cy="class-selection" class="class-selection__selected-class selected-class"
@click="showPopover = !showPopover">
<current-class class="selected-class__text"></current-class> <chevron-down class="selected-class__dropdown-icon"></chevron-down>
<current-class class="selected-class__text"></current-class>
<chevron-down class="selected-class__dropdown-icon"></chevron-down>
</div>
<widget-popover v-if="showPopover"
@hide-me="showPopover = false"
@ -13,9 +14,20 @@
:key="schoolClass.id"
:label="schoolClass.name"
:item="schoolClass"
@click="updateFilter(schoolClass)">
@click="updateSelectedClassAndHidePopover(schoolClass)">
{{schoolClass.name}}
</li>
<li class="popover-links__link popover-links__link--large popover-links__divider"
v-if="me.isTeacher"
data-cy="create-class-link" @click="closeSidebar">
<router-link tag="span" class="popover-links__link-with-icon" :to="{name: 'create-class'}">
<add-icon class="popover-links__icon"/>
<span>Klasse erfassen</span>
</router-link>
</li>
<!-- <li class="popover-links__link popover-links__link&#45;&#45;large popover-links__divider" @click="closeSidebar">-->
<!-- <router-link tag="span" :to="{name: 'old-classes'}">Alte Klassen anzeigen</router-link>-->
<!-- </li>-->
</widget-popover>
</div>
</template>
@ -24,14 +36,18 @@
import WidgetPopover from '@/components/WidgetPopover';
import ChevronDown from '@/components/icons/ChevronDown';
import CurrentClass from '@/components/school-class/CurrentClass';
import ME_QUERY from '@/graphql/gql/meQuery.gql';
import UPDATE_USER_SETTING from '@/graphql/gql/mutations/updateUserSetting.gql';
import AddIcon from '@/components/icons/AddIcon';
import updateSelectedClassMixin from '@/mixins/updateSelectedClass';
import sidebarMixin from '@/mixins/sidebar';
import meMixin from '@/mixins/me';
export default {
components: {
WidgetPopover,
ChevronDown,
CurrentClass
CurrentClass,
AddIcon
},
props: {
@ -41,49 +57,19 @@
}
},
apollo: {
me: {
query: ME_QUERY,
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
this.me = this.$getRidOfEdges(data).me;
}
}
}
},
mixins: [updateSelectedClassMixin, sidebarMixin, meMixin],
data() {
return {
me: {
selectedClass: {
id: ''
},
permissions: [],
schoolClasses: []
},
showPopover: false
}
},
methods: {
updateFilter(selectedClass) {
this.$apollo.mutate({
mutation: UPDATE_USER_SETTING,
variables: {
input: {
id: selectedClass.id
}
},
update(store, data) {
let meData = store.readQuery({query: ME_QUERY});
meData.me.selectedClass = selectedClass;
store.writeQuery({query: ME_QUERY, data: meData});
}
}).catch((error) => {
console.log('fail', error)
});
updateSelectedClassAndHidePopover(selectedClass) {
this.updateSelectedClass(selectedClass);
this.showPopover = false;
this.closeSidebar();
}
},
@ -109,8 +95,6 @@
margin-bottom: $medium-spacing;
border: 1px solid $color-silver;
border-radius: 4px;
padding: $small-spacing $medium-spacing;
/*justify-self: space-between;*/
&__popover {
white-space: nowrap;
@ -118,10 +102,13 @@
left: 0;
transform: translateY($small-spacing);
}
}
.selected-class {
width: 100%;
box-sizing: border-box;
padding: $small-spacing $medium-spacing;
display: flex;
align-items: center;
@ -139,9 +126,4 @@
fill: $color-brand;
}
}
.popover-links__link {
cursor: pointer;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<span class="current-class">Klasse: {{currentClassName}}</span>
<span class="current-class" data-cy="current-class-name">{{currentClassName}}</span>
</template>
<script>

View File

@ -0,0 +1,27 @@
<template>
<a class="edit-class-name" @click="$emit('edit')" data-cy="edit-class-name-link">
<pen-icon class="edit-class-name__icon"></pen-icon>
</a>
</template>
<script>
import PenIcon from '@/components/icons/PenIcon';
export default {
components: {
PenIcon
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.edit-class-name {
&__icon {
width: 20px;
height: 20px;
fill: $color-brand;
}
}
</style>

View File

@ -0,0 +1,74 @@
<template>
<modal :hide-header="false" :small="true" title="Hello">
<h4 slot="header">Klasse bearbeiten</h4>
<modal-input v-on:input="name = $event"
placeholder="Klassenname"
data-cy="edit-class-name-input"
:value="name"
></modal-input>
<div slot="footer">
<a class="button button--primary" data-cy="modal-save-button"
@click="save">Speichern</a>
<a class="button" @click="hide">Abbrechen</a>
</div>
</modal>
</template>
<script>
import Modal from '@/components/Modal';
import ModalInput from '@/components/ModalInput';
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass.gql';
import UPDATE_SCHOOL_CLASS_MUTATION from '@/graphql/gql/mutations/updateSchoolClass.gql';
export default {
components: {
Modal,
ModalInput
},
methods: {
save() {
this.$apollo.mutate({
mutation: UPDATE_SCHOOL_CLASS_MUTATION,
variables: {
input: {
name: this.name,
id: this.schoolClass.id
}
},
update(store, {data: {updateSchoolClass: {schoolClass: {name}}}}) {
let query = MY_SCHOOL_CLASS_QUERY;
let data = store.readQuery({query});
data.me.selectedClass.name = name;
store.writeQuery({query, data});
}
});
this.hide();
},
hide() {
this.$store.dispatch('hideModal');
}
},
apollo: {
schoolClass: {
query: MY_SCHOOL_CLASS_QUERY,
update(data) {
return this.$getRidOfEdges(data).me.selectedClass
}
}
},
mounted() {
this.name = this.schoolClass ? this.schoolClass.name : '';
},
data() {
return {
name: ''
}
}
}
</script>

View File

@ -8,6 +8,27 @@ import {typeDefs} from '@/graphql/typedefs';
import {resolvers} from '@/graphql/resolvers';
export default function (uri, networkErrorCallback) {
const writeLocalCache = cache => {
// we use the cache as our local state
cache.writeData({
data: {
scrollPosition: {
__typename: 'ScrollPosition',
scrollTo: ''
},
sidebar: {
__typename: 'Sidebar',
open: false
},
helloEmail: {
__typename: 'HelloEmail',
email: ''
},
}
});
};
export default function (uri) {
const httpLink = createHttpLink({
// uri: process.env.NODE_ENV !== 'production' ? 'http://localhost:8000/api/graphql/' : '/api/graphql/',
uri,
@ -101,31 +122,19 @@ export default function (uri, networkErrorCallback) {
}
};
// we use the cache as our local state
cache.writeData({
data: {
scrollPosition: {
__typename: 'ScrollPosition',
scrollTo: ''
},
helloEmail: {
__typename: 'HelloEmail',
email: ''
},
sidebar: {
__typename: 'Sidebar',
open: false
}
}
});
writeLocalCache(cache);
// Create the apollo client
return new ApolloClient({
const client = new ApolloClient({
link: composedLink,
// link: httpLink,
cache,
connectToDevTools: true,
typeDefs,
resolvers
})
});
client.onResetStore(() => {
writeLocalCache(cache);
});
return client;
}

View File

@ -3,6 +3,7 @@
query MeQuery {
me {
...UserParts
isTeacher
permissions
}
}

View File

@ -1,16 +0,0 @@
#import "../fragments/objectiveGroupParts.gql"
mutation AddObjectiveGroup($input: AddObjectiveGroupInput!) {
addObjectiveGroup(input: $input) {
objectiveGroup {
...ObjectiveGroupParts
objectives {
edges {
node {
id
text
}
}
}
}
}
}

View File

@ -0,0 +1,5 @@
mutation AddRemoveMember($input: AddRemoveMemberInput!) {
addRemoveMember(input: $input) {
success
}
}

View File

@ -0,0 +1,9 @@
mutation CreateSchoolClass($input: CreateSchoolClassInput!) {
createSchoolClass(input: $input) {
success
schoolClass {
id
name
}
}
}

View File

@ -1,16 +0,0 @@
#import "../fragments/objectiveGroupParts.gql"
mutation UpdateObjectiveGroup($input: UpdateObjectiveGroupInput!) {
updateObjectiveGroup(input: $input) {
objectiveGroup {
...ObjectiveGroupParts
objectives {
edges {
node {
id
text
}
}
}
}
}
}

View File

@ -0,0 +1,8 @@
mutation UpdateSchoolClass($input: UpdateSchoolClassInput!) {
updateSchoolClass(input: $input) {
success
schoolClass {
name
}
}
}

View File

@ -0,0 +1,18 @@
query MySchoolClassQuery {
me {
id
isTeacher
selectedClass {
id
name
code
members {
id
firstName
lastName
isTeacher
active
}
}
}
}

View File

@ -1,23 +0,0 @@
query {
me {
id
schoolClasses {
edges {
node {
id
name
users {
edges {
node {
id
firstName
lastName
permissions
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,13 @@
query OldClassesQuery {
me {
id
oldClasses {
edges {
node {
id
name
}
}
}
}
}

View File

@ -6,6 +6,7 @@ query Topic($slug: String!){
teaser
description
vimeoId
instructions
modules {
edges {
node {

View File

@ -0,0 +1,103 @@
<template>
<footer class="default-footer">
<div class="default-footer__section">
<div class="default-footer__info">
<div class="default-footer__who-are-we who-are-we">
<h5 class="who-are-we__title">Wer sind wir?</h5>
<p class="who-are-we__text">
mySkillbox ist ein Angebot des hep Verlags in Zusammenarbeit mit dem Eidgenössischen Hochschulinstitut für
Berufsbildung (EHB)
</p>
</div>
<a href="https://www.hep-verlag.ch/" target="_blank">
<hep-logo class="default-footer__logo-hep">
</hep-logo>
</a>
<a href="https://www.ehb.swiss/" target="_blank">
<ehb-logo class="default-footer__logo-ehb">
</ehb-logo>
</a>
</div>
</div>
<div class="default-footer__section">
<div class="default-footer__links">
<a href="https://www.hep-verlag.ch/datenschutz" target="_blank" class="default-footer__link">Datenschutz</a>
<a href="https://www.hep-verlag.ch/impressum" target="_blank" class="default-footer__link">Impressum</a>
<a href="https://www.hep-verlag.ch/agb" target="_blank" class="default-footer__link">AGB</a>
<a href="https://www.hep-verlag.ch/kontakt-verlag" target="_blank" class="default-footer__link">Kontakt</a>
<a href="https://www.hep-verlag.ch/kundenservice" target="_blank" class="default-footer__link">Hilfe</a>
</div>
</div>
</footer>
</template>
<script>
import HepLogo from '@/components/icons/HepLogo';
import EhbLogo from '@/components/icons/EhbLogo';
export default {
components: {
HepLogo,
EhbLogo
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.default-footer {
background-color: $color-silver-light;
&__section {
width: 100%;
border-bottom: $color-silver 1px solid;
display: flex;
justify-content: center;
}
&__info {
width: $footer-width;
padding: 2*$large-spacing 0;
display: flex;
justify-content: space-between;
}
&__who-are-we {
width: 330px;
}
&__logo-hep {
width: 147px;
height: 35px;
}
&__logo-ehb {
width: 100px;
height: 32px;
}
&__links {
width: $footer-width;
padding: $large-spacing 0;
}
&__link {
@include aside-with-cheese;
margin-right: $large-spacing;
}
}
.who-are-we {
&__title {
@include heading-4;
}
&__text {
@include aside-text;
}
}
</style>

View File

@ -1,13 +1,15 @@
<template>
<div class="container skillbox" :class="specialContainerClass">
<div class="container skillbox layout" :class="specialContainerClass">
<profile-sidebar></profile-sidebar>
<header-bar class="header skillbox__header">
<header-bar class="header layout__header">
</header-bar>
<mobile-header class="header skillbox__header skillbox__header--mobile"></mobile-header>
<mobile-header
class="header layout__header layout__header--mobile"
></mobile-header>
<router-view class="skillbox__content"></router-view>
<footer class="skillbox__footer">Footer</footer>
<router-view class="layout__content"></router-view>
<default-footer class="layout__footer"></default-footer>
</div>
</template>
@ -15,12 +17,14 @@
import HeaderBar from '@/components/HeaderBar';
import MobileHeader from '@/components/MobileHeader';
import ProfileSidebar from '@/components/profile/ProfileSidebar';
import DefaultFooter from '@/layouts/DefaultFooter';
export default {
components: {
HeaderBar,
MobileHeader,
ProfileSidebar
ProfileSidebar,
DefaultFooter
},
computed: {
@ -39,5 +43,4 @@
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
@import "@/styles/_default-layout.scss";
</style>

View File

@ -1,10 +1,10 @@
<template>
<div class="container skillbox" :class="specialContainerClass">
<div class="container layout layout--fullscreen" :class="specialContainerClass">
<div class="close-button" v-on:click="back">
<cross class="close-button__icon"></cross>
</div>
<router-view class="skillbox__content"></router-view>
<router-view class="layout__content"></router-view>
</div>
</template>

View File

@ -1,14 +1,8 @@
<template>
<div class="skillbox public">
<div class="skillbox__header public__logo">
<logo class=""></logo>
</div>
<router-view class="skillbox__content public__content"></router-view>
<footer class="skillbox__footer public__footer footer">
<div class="footer__content">
Footer
</div>
</footer>
<div class="layout layout--public public">
<logo class="public__logo"></logo>
<router-view class="layout__content"></router-view>
<footer class="layout__footer">Footer</footer>
</div>
</template>
@ -27,26 +21,15 @@ import Logo from '@/components/icons/Logo';
@import "@/styles/_default-layout.scss";
.public {
grid-template-areas: "h" "c" "f";
max-width: 800px;
min-width: 320px;
padding-top: 4*$large-spacing;
&__logo {
position: relative;
left: -10px;
width: 100%;
}
&__content {
@include content-block();
margin-bottom: $large-spacing;
}
&__logo {
@include content-block();
}
&__footer {
background-color: $color-silver-light;
display: block;
width: 260px;
height: 43px;
}
}

View File

@ -0,0 +1,34 @@
<template>
<footer class="simple-footer">
<p class="simple-footer__strong">Copyright © 2020 hep Verlag, in Zusammenarbeit mit dem EHB</p>
<p class="simple-footer__regular">Alle Inhalte von mySkillbox, insbesondere Texte und Grafiken, sind urheberrechtlich geschützt. </p>
</footer>
</template>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.simple-footer {
width: 100%;
justify-self: center;
padding: $large-spacing 0;
background-color: $color-silver-light;
display: grid;
grid-template-columns: 1fr $footer-width 1fr;
box-sizing: border-box;
overflow: hidden;
height: 105px;
&__strong {
@include aside-with-cheese;
font-weight: 600;
grid-column: 2;
}
&__regular {
@include aside-text;
grid-column: 2;
}
}
</style>

View File

@ -1,13 +1,33 @@
<template>
<div class="skillbox layout--simple">
<div class="skillbox layout layout--simple">
<div class="close-button" v-on:click="back">
<cross class="close-button__icon"></cross>
</div>
<router-view></router-view>
<simple-footer class="layout__footer"></simple-footer>
</div>
</template>
<script>
import Cross from '@/components/icons/Cross';
import SimpleFooter from '@/layouts/SimpleFooter';
export default {
components: {
Cross,
SimpleFooter
},
methods: {
back() {
this.$router.go(-1);
}
}
}
</script>
<style lang="scss" scoped>
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.layout {
@ -16,11 +36,12 @@
@supports (display: grid) {
display: grid;
}
padding: 20px;
width: 100%;
@include desktop {
grid-template-columns: 1fr 640px 1fr;
grid-template-rows: 60px 1fr 105px;
-ms-grid-columns: 1fr 640px 1fr;
& > :nth-child(2) {
@ -28,7 +49,10 @@
-ms-grid-column: 2;
}
}
}
&__footer {
grid-column: 1 / span 3;
}
}
@ -42,6 +66,8 @@
@include desktop {
grid-column: 3;
-ms-grid-column: 3;
margin-right: $medium-spacing;
margin-top: $medium-spacing;
}
&__icon {
@ -50,20 +76,3 @@
}
}
</style>
<script>
import Cross from '@/components/icons/Cross';
export default {
components: {
Cross
},
methods: {
back() {
this.$router.go(-1);
}
}
}
</script>

View File

@ -9,7 +9,6 @@ import App from './App'
import router from './router'
import store from '@/store/index'
import VueScrollTo from 'vue-scrollto';
import VueAnalytics from 'vue-analytics';
import {Validator, install as VeeValidate} from 'vee-validate/dist/vee-validate.minimal.esm.js';
import {required, min, decimal, confirmed} from 'vee-validate/dist/rules.esm.js';
import veeDe from 'vee-validate/dist/locale/de';
@ -17,32 +16,14 @@ import {dateFilter} from './filters/date-filter';
import autoGrow from '@/directives/auto-grow'
import clickOutside from '@/directives/click-outside'
import ME_QUERY from '@/graphql/gql/meQuery.gql';
import VueModal from '@/plugins/modal';
import VueRemoveEdges from '@/plugins/edges';
import VueMatomo from 'vue-matomo'
Vue.config.productionTip = false;
// TODO: Move into a separate project as a plugin
//
function getRidOfEdges(collection) {
if (typeof collection === 'object' && collection && !Array.isArray(collection)) {
let newObj = {};
for (const k in collection) {
if (k === 'edges') {
return collection.edges.map(edge => getRidOfEdges(edge.node));
} else {
newObj[k] = getRidOfEdges(collection[k]);
if (newObj[k]) {
// delete newObj[k]['__typename']
}
}
}
return newObj
} else {
return collection
}
}
Object.defineProperty(Vue.prototype, '$getRidOfEdges', {value: getRidOfEdges});
Vue.use(VueModal);
Vue.use(VueRemoveEdges);
Vue.use(VueApollo);
Vue.use(VueAxios, axios);
Vue.use(VueVimeoPlayer);
@ -53,12 +34,12 @@ Vue.use(VueScrollTo, {
offset: -50
});
if (process.env.GOOGLE_ANALYTICS_ID) {
Vue.use(VueAnalytics, {
id: process.env.GOOGLE_ANALYTICS_ID,
router
if (process.env.MATOMO_HOST) {
Vue.use(VueMatomo, {
host: process.env.MATOMO_HOST,
siteId: process.env.MATOMO_SITE_ID,
router: router
});
console.log(process.env.GOOGLE_ANALYTICS_ID);
}
Vue.directive('click-outside', clickOutside);
@ -154,9 +135,9 @@ function networkErrorCallback(statusCode) {
router.beforeEach(async (to, from, next) => {
if (to.path === '/logout') {
privateApolloClient.resetStore();
publicApolloClient.resetStore();
next({name: 'hello'});
return;
return
}
if (unauthorizedAccess(to)) {

View File

@ -0,0 +1,27 @@
import ME_QUERY from '@/graphql/gql/meQuery';
export default {
methods: {
addSchoolClass(store, schoolClass) {
const query = ME_QUERY;
if (schoolClass) {
console.log('updating school class');
const data = store.readQuery({query});
if (data) {
data.me.schoolClasses.edges = [
...data.me.schoolClasses.edges,
{
node: schoolClass,
__typename: 'SchoolClassNodeEdge'
}
];
data.me.selectedClass = {
id: schoolClass.id,
__typename: 'SchoolClassNode'
};
store.writeQuery({query, data});
}
}
},
}
}

View File

@ -8,7 +8,8 @@ export default {
id: ''
},
permissions: [],
schoolClasses: []
schoolClasses: [],
isTeacher: false
},
showPopover: false
}
@ -17,12 +18,10 @@ export default {
apollo: {
me: {
query: ME_QUERY,
manual: true,
result({data, loading, networkStatus}) {
if (!loading) {
this.me = this.$getRidOfEdges(data).me;
}
}
update(data) {
return this.$getRidOfEdges(data).me;
},
fetchPolicy: 'cache-first'
},
},
}

View File

@ -3,11 +3,13 @@ import TOGGLE_SIDEBAR from '@/graphql/gql/local/mutations/toggleSidebar.gql';
export default {
methods: {
openSidebar() {
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: true
}
this.$nextTick(() => { // we don't want this to happen instantly, only almost instantly. Otherwise the click-outside-directive won't work
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: true
}
});
});
},
},

View File

@ -0,0 +1,24 @@
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass';
export default {
apollo: {
me: {
query: MY_SCHOOL_CLASS_QUERY,
update(data) {
return this.$getRidOfEdges(data).me
}
}
},
data() {
return {
me: {
isTeacher: false,
selectedClass: {
name: '',
members: []
}
}
}
}
}

View File

@ -0,0 +1,29 @@
import SIDEBAR from '@/graphql/gql/local/sidebar.gql';
import TOGGLE_SIDEBAR from '@/graphql/gql/local/mutations/toggleSidebar.gql';
export default {
methods: {
closeSidebar() {
if (this.sidebar.open) {
this.$apollo.mutate({
mutation: TOGGLE_SIDEBAR,
variables: {
open: false
}
});
}
},
},
apollo: {
sidebar: {
query: SIDEBAR
}
},
data: () => ({
sidebar: {
open: false
}
})
}

View File

@ -0,0 +1,30 @@
import ME_QUERY from '@/graphql/gql/meQuery.gql';
import UPDATE_USER_SETTING from '@/graphql/gql/mutations/updateUserSetting.gql';
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass.gql';
export default {
methods: {
updateSelectedClass(selectedClass) {
return this.$apollo.mutate({
mutation: UPDATE_USER_SETTING,
variables: {
input: {
id: selectedClass.id
}
},
update(store, data) {
let meData = store.readQuery({query: ME_QUERY});
meData.me.selectedClass = selectedClass;
store.writeQuery({query: ME_QUERY, data: meData});
},
refetchQueries: [{
query: MY_SCHOOL_CLASS_QUERY
}]
}).catch((error) => {
console.warn('failed to update selected class', error)
});
}
},
}

View File

@ -0,0 +1,83 @@
<template>
<div class="create-class">
<h1 class="create-class__title">Klasse erfassen</h1>
<div>
<div class="skillboxform-input">
<label for="class-name" class="skillboxform-input__label">Name</label>
<input
id="class-name"
class="skillbox-input skillboxform-input__input"
:class="{'skillboxform-input__input--error': error}"
data-cy="input-class-name"
:value="name"
@input="updateName">
<small
v-if="error"
class="skillboxform-input__error"
data-cy="email-local-errors"
>{{ error }}
</small>
</div>
<div>
<a class="button button--primary button--big" data-cy="create-class" @click="createClass(name)">Klasse
erfassen</a>
<a class="button button--big" data-cy="create-class-cancel" @click="cancel">Abbrechen</a>
</div>
</div>
</div>
</template>
<script>
import addSchoolClassMixin from '@/mixins/add-school-class';
import CREATE_CLASS_MUTATION from '@/graphql/gql/mutations/createClass.gql';
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass';
export default {
mixins: [addSchoolClassMixin],
data: () => ({
name: '',
error: ''
}),
methods: {
updateName(event) {
this.name = event.target.value;
this.error = '';
},
createClass(name) {
let self = this;
this.$apollo.mutate({
mutation: CREATE_CLASS_MUTATION,
variables: {
input: {
name
}
},
update(store, {data: {createSchoolClass: {schoolClass}}}) {
self.addSchoolClass(store, schoolClass);
self.$router.push({
name: 'my-class'
});
},
refetchQueries: [{
query: MY_SCHOOL_CLASS_QUERY
}]
});
},
cancel() {
this.$router.go(-1);
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.create-class {
}
</style>

View File

@ -2,15 +2,15 @@
<div class="instrument">
<h1 class="instrument__title">{{instrument.title}}</h1>
<content-component v-for="component in instrument.contents"
:key="component.id"
:component="component"
:root="instrument.slug"
:parent="instrument"
:bookmarks="instrument.bookmarks"
:notes="instrument.notes"
>
</content-component>
<content-component v-for="component in instrument.contents"
:key="component.id"
:component="component"
:root="instrument.slug"
:parent="instrument"
:bookmarks="instrument.bookmarks"
:notes="instrument.notes"
>
</content-component>
</div>
</template>
@ -59,19 +59,32 @@
& p {
margin-bottom: 40px;
}
& ul {
padding-left: 25px;
}
& p + ul {
margin-top: -30px;
}
& li {
list-style: disc;
line-height: 1.5;
}
& b {
font-weight: 600;
}
.brand {
color: $color-brand;
font-weight: 600;
}
.secondary {
color: $color-accent-2;
font-weight: 600;
}
}
}

View File

@ -30,9 +30,13 @@
<script>
import JOIN_CLASS_MUTATION from '@/graphql/gql/mutations/joinClass.gql';
import ME_QUERY from '@/graphql/gql/meQuery.gql';
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass';
import addSchoolClassMixin from '@/mixins/add-school-class';
export default {
mixins: [addSchoolClassMixin],
data: () => ({
code: '',
error: ''
@ -44,6 +48,7 @@
this.error = '';
},
joinClass(code) {
let self = this;
this.$apollo.mutate({
mutation: JOIN_CLASS_MUTATION,
variables: {
@ -52,20 +57,13 @@
}
},
update(store, {data: {joinClass: {schoolClass}}}) {
if (schoolClass) {
const data = store.readQuery({query: ME_QUERY});
if (data) {
data.me.schoolClasses.edges.push({
node: schoolClass,
__typename: 'SchoolClassNode'
});
store.writeQuery({query: ME_QUERY, data});
}
}
}
self.addSchoolClass(store, schoolClass);
self.$router.push({name: 'my-class'});
},
refetchQueries: [{query: MY_SCHOOL_CLASS_QUERY}]
})
.then(() => {
this.$router.push({name: 'my-classes'});
})
.catch(e => {
console.debug(e);

View File

@ -19,7 +19,7 @@
@import "@/styles/_mixins.scss";
.module-page {
display: -ms-grid;
display: flex;
@supports (display: grid) {
display: grid;
}

View File

@ -0,0 +1,105 @@
<template>
<div class="my-class">
<h1 class="my-class__header" data-cy="class-list-title">Klassenliste</h1>
<router-link class="my-class__code-link button button--primary"
v-if="me.isTeacher"
:to="{name: 'show-code'}">Zugangscode anzeigen
</router-link>
<class-list
class="my-class__class"
:name="me.selectedClass.name"
:members="me.selectedClass.members"
:teacher="me.isTeacher"
:id="me.selectedClass.id"
@remove="remove"
@add="add"
></class-list>
</div>
</template>
<script>
import ClassList from '@/components/profile/ClassList';
import MY_SCHOOL_CLASS_QUERY from '@/graphql/gql/mySchoolClass.gql';
import ADD_REMOVE_MEMBER_MUTATION from '@/graphql/gql/mutations/addRemoveMember.gql';
import selectedClassMixin from '@/mixins/selected-class';
export default {
mixins: [selectedClassMixin],
components: {
ClassList
},
methods: {
changeMember(member, active) {
this.$apollo.mutate({
mutation: ADD_REMOVE_MEMBER_MUTATION,
variables: {
input: {
member: member.id,
schoolClass: this.me.selectedClass.id,
active
}
},
update(store, {data: {addRemoveMember: {success}}}) {
if (success) {
const query = MY_SCHOOL_CLASS_QUERY;
const data = store.readQuery({query});
let memberIndex = data.me.selectedClass.members.findIndex(m => m.id === member.id);
data.me.selectedClass.members = [
...data.me.selectedClass.members.slice(0, memberIndex),
{...member, active},
...data.me.selectedClass.members.slice(memberIndex + 1),
];
store.writeQuery({query, data});
}
}
});
},
add(member) {
this.changeMember(member, true);
},
remove(member) {
this.$modal.open('deactivate-person', {
myself: member.id === this.me.id,
name: `${member.firstName} ${member.lastName}`,
className: this.me.selectedClass.name,
})
.then(() => {
this.changeMember(member, false);
})
.catch(() => {
});
}
},
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.my-class {
display: grid;
grid-template-columns: auto auto;
grid-template-rows: auto auto;
grid-template-areas: "h b" "c c";
&__header {
grid-area: h;
}
&__code-link {
grid-area: b;
justify-self: end;
align-self: center;
}
&__class {
grid-area: c;
width: 100%;
margin-bottom: $large-spacing;
}
}
</style>

View File

@ -1,44 +0,0 @@
<template>
<div class="myclasses">
<h1 class="myclasses__header" data-cy="class-list-title">Klassenliste</h1>
<classlist v-for="schoolClass in schoolClasses" v-bind="schoolClass" :key="schoolClass.name" class="myclasses__class"></classlist>
</div>
</template>
<script>
import MY_SCHOOL_CLASSES_QUERY from '@/graphql/gql/mySchoolClasses.gql';
import Classlist from '@/components/profile/Classlist';
export default {
components: {
Classlist
},
apollo: {
schoolClasses: {
query: MY_SCHOOL_CLASSES_QUERY,
update(data) {
return this.$getRidOfEdges(data).me.schoolClasses
}
}
},
data() {
return {
schoolClasses: []
}
}
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.myclasses {
&__class {
margin-bottom: $large-spacing;
}
}
</style>

View File

@ -0,0 +1,55 @@
<template>
<div class="old-classes">
<h1 class="old-classes__title">Alte Klassen</h1>
<ul class="old-classes__list simple-list">
<li class="simple-list__item" v-for="schoolClass in me.oldClasses" :key="schoolClass.id" data-cy="old-class-item"><span
class="old-classes__class-name">{{schoolClass.name}}</span> <a
class="simple-list__action" @click="updateSelectedClassAndGoToClassList(schoolClass)">Anzeigen</a>
</li>
</ul>
</div>
</template>
<script>
import OLD_CLASSES_QUERY from '@/graphql/gql/oldClasses.gql';
import updateSelectedClassMixin from '@/mixins/updateSelectedClass';
export default {
mixins: [updateSelectedClassMixin],
methods: {
updateSelectedClassAndGoToClassList(selectedClass) {
this.updateSelectedClass(selectedClass).then(() => {
this.$router.push({name: 'my-class'});
});
}
},
// todo: test this in front- and backend
apollo: {
me: {
query: OLD_CLASSES_QUERY,
update(data) {
return this.$getRidOfEdges(data).me;
}
}
},
data: () => ({
me: {
oldClasses: []
}
})
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
.old-classes {
&__class-name {
font-family: $sans-serif-font-family;
}
}
</style>

View File

@ -1,19 +1,5 @@
<template>
<div class="profile">
<nav class="top-navigation profile-submenu profile__submenu">
<router-link to="/me/activity" active-class="top-navigation__link--active"
class="top-navigation__link profile-submenu__item submenu-item">Aktivität
</router-link>
<router-link to="/me/myclasses" active-class="top-navigation__link--active"
class="top-navigation__link profile-submenu__item submenu-item">Klassenliste
</router-link>
<router-link to="/me/profile" active-class="top-navigation__link--active"
class="top-navigation__link profile-submenu__item submenu-item">Profil
</router-link>
<router-link :to="{name:'join-class'}" active-class="top-navigation__link--active" data-cy="join-class-link"
class="top-navigation__link profile-submenu__item submenu-item">Klasse beitreten
</router-link>
</nav>
<router-view></router-view>
</div>
</template>
@ -24,26 +10,15 @@
@import "@/styles/_mixins.scss";
.profile {
padding: $medium-spacing;
padding: $large-spacing;
max-width: 640px;
margin: 0 auto;
width: 100%;
box-sizing: border-box;
@include desktop {
max-width: 1024px;
margin: 0;
}
&__submenu {
margin-bottom: $medium-spacing;
margin-left: -$medium-spacing;
max-width: 800px;
margin: 0 auto;
}
}
.profile-submenu {
&__item {
font-family: $sans-serif-font-family;
font-size: toRem(14px);
}
}
</style>

View File

@ -0,0 +1,32 @@
<template>
<div class="show-code">
<h2 class="show-code__title">Zugangscode Klasse {{me.selectedClass.name}}</h2>
<h1 class="show-code__code">{{me.selectedClass.code}}</h1>
</div>
</template>
<script>
import selectedClassMixin from '@/mixins/selected-class';
export default {
mixins: [selectedClassMixin],
}
</script>
<style scoped lang="scss">
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.show-code {
&__title {
@include regular-text;
margin-bottom: 2*$large-spacing;
}
&__code {
font-size: toRem(120px);
letter-spacing: toRem(20px);
font-weight: 600;
}
}
</style>

View File

@ -38,6 +38,8 @@
</div>
<div class="start-page__news news">
<h2 class="news__title">News</h2>
<news-teaser date="11. März 2020" title="Brexit"
url="https://myskillbox-abu-news.webflow.io/brexit"></news-teaser>
<news-teaser date="20. Dezember 2019" title="Blockchain"
url="https://myskillbox-abu-news.webflow.io/blockchain"></news-teaser>
<news-teaser date="9. September 2019" title="Klima was sonst?"

View File

@ -3,7 +3,7 @@
<h1 class="survey-page__title">{{title}}</h1>
<survey :survey='survey'></survey>
<solution :value="solution" v-if="module.solutionsEnabled || isTeacher"></solution>
<solution :value="solution" v-if="showSolution"></solution>
<div v-if="surveyComplete">
<a class="button button--primary" @click="reopen">Übung bearbeiten</a>
</div>
@ -50,16 +50,31 @@
surveyComplete() {
return this.survey && this.survey.isCompleted
},
showSolution() {
return (module.solutionsEnabled || isTeacher) && !this.survey.isCompleted
},
solution() {
return {
text: this.answers.reduce((previous, answer) => {
if (!answer.answer) {
return previous
}
let answerText;
if (typeof answer.answer === 'object') {
// this means the answer comes from a matrix, where the keys are the labels and the values are the respective answers
let answerObject = answer.answer;
let keysAndValues = [];
for (let prop of Object.keys(answerObject)) {
keysAndValues.push(`${prop}: ${answerObject[prop]}`);
}
answerText = keysAndValues.join(', ');
} else {
answerText = answer.answer;
}
return `
${previous}
<h2 class="solution-text__heading">${answer.title}</h2>
<p class="solution-text__answer">${answer.answer}</p>
<p class="solution-text__answer">${answerText}</p>
`
}, '')
}

View File

@ -4,9 +4,16 @@
<p class="topic__teaser">
{{topic.teaser}}
</p>
<div v-if="topic.vimeoId" class="topic__video-link" @click="openVideo">
<play class="topic__video-link-icon"></play>
<span class="topic__video-link-description">Video schauen</span>
<div class="topic__links">
<div v-if="topic.vimeoId" class="topic__video-link topic__link" @click="openVideo">
<play-icon class="topic__video-link-icon topic__link-icon"></play-icon>
<span class="topic__link-description">Video schauen</span>
</div>
<a target="_blank" :href="topic.instructions" v-if="me.isTeacher && topic.instructions" class="topic__instruction-link topic__link">
<bulb-icon class="topic__instruction-icon topic__link-icon"></bulb-icon>
<span class="topic__link-description">Anweisungen zum Thema anzeigen</span>
</a>
</div>
<div class="topic__modules">
<module-teaser v-for="module in modules" :key="module.id" v-bind="module"></module-teaser>
@ -16,15 +23,20 @@
<script>
import ModuleTeaser from '@/components/modules/ModuleTeaser.vue';
import Play from '@/components/icons/Play';
import PlayIcon from '@/components/icons/Play';
import BulbIcon from '@/components/icons/BulbIcon';
import TOPIC_QUERY from '@/graphql/gql/topicQuery.gql';
import me from '@/mixins/me';
export default {
components: {
ModuleTeaser,
Play
PlayIcon,
BulbIcon
},
mixins: [me],
apollo: {
topic() {
return {
@ -75,19 +87,28 @@
margin-bottom: $large-spacing;
}
&__video-link {
&__links {
margin-bottom: $large-spacing;
display: flex;
}
&__link {
cursor: pointer;
display: flex;
align-items: center;
}
&__video-link-icon {
&__video-link {
margin-right: $large-spacing;
}
&__link-icon {
width: 40px;
height: 40px;
margin-right: $medium-spacing;
}
&__video-link-description {
&__link-description {
@include heading-3;
}

View File

@ -0,0 +1,28 @@
const getRidOfEdges = (collection) => {
if (typeof collection === 'object' && collection && !Array.isArray(collection)) {
let newObj = {};
for (const k in collection) {
if (collection.hasOwnProperty(k)) {
if (k === 'edges') {
return collection.edges.map(edge => getRidOfEdges(edge.node));
} else {
newObj[k] = getRidOfEdges(collection[k]);
if (newObj[k]) {
// delete newObj[k]['__typename']
}
}
}
}
return newObj
} else {
return collection
}
};
const EdgesPlugin = {
install(Vue, options) {
Vue.prototype.$getRidOfEdges = getRidOfEdges;
}
};
export default EdgesPlugin;

View File

@ -0,0 +1,57 @@
// adapted from
// https://stackoverflow.com/questions/41791193/vuejs-reactive-binding-for-a-plugin-how-to/41801107#41801107
import Vue from 'vue';
class ModalStore {
constructor(data = {}) {
this.vm = new Vue({
data: () => ({
component: '',
payload: {}
})
});
}
get state() {
return this.vm.$data;
}
}
const ModalPlugin = {
install(Vue, options) {
const store = new ModalStore({});
const reset = () => {
store.state.component = '';
store.state.payload = {};
};
Vue.prototype.$modal = {
state: store.state,
component: store.state.component,
payload: store.state.payload,
open: (component, payload) => {
store.state.payload = payload;
store.state.component = component;
return new Promise((resolve, reject) => {
this._resolve = resolve;
this._reject = reject;
});
},
confirm: () => {
reset();
this._resolve();
},
cancel: () => {
reset();
this._reject();
},
_resolve: () => {
},
_reject: () => {
},
};
}
};
export default ModalPlugin;

View File

@ -19,7 +19,7 @@ import portfolio from '@/pages/portfolio'
import project from '@/pages/project'
import profilePage from '@/pages/profile'
import profile from '@/components/profile/Profile'
import myClasses from '@/pages/myClasses'
import myClass from '@/pages/myClass'
import activity from '@/pages/activity'
import Router from 'vue-router'
import editProject from '@/pages/editProject'
@ -37,6 +37,9 @@ import emailVerification from '@/pages/email-verification'
import licenseActivation from '@/pages/license-activation'
import forgotPassword from '@/pages/forgot-password'
import joinClass from '@/pages/joinClass'
import oldClasses from '@/pages/oldClasses';
import createClass from '@/pages/createClass';
import showCode from '@/pages/showCode';
import store from '@/store/index';
@ -132,9 +135,17 @@ const routes = [
component: profilePage,
children: [
{path: 'profile', name: 'profile', component: profile, meta: {isProfile: true}},
{path: 'myclasses', name: 'my-classes', component: myClasses, meta: {isProfile: true}},
{path: 'my-class', name: 'my-class', component: myClass, meta: {isProfile: true}},
{path: 'activity', name: 'activity', component: activity, meta: {isProfile: true}},
{path: '', name: 'profile-activity', component: activity, meta: {isProfile: true}},
{
path: 'old-classes',
name: 'old-classes',
component: oldClasses,
meta: {isProfile: true}
},
{path: 'create-class', name: 'create-class', component: createClass, meta: {layout: 'simple'}},
{path: 'show-code', name: 'show-code', component: showCode, meta: {layout: 'simple'}},
]
},
{path: 'join-class', name: 'join-class', component: joinClass, meta: {layout: 'simple'}},

View File

@ -1,7 +1,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
Vue.use(Vuex);
// WARNING fixme todo: please do not use this anymore, use the local GraphQL cache
export default new Vuex.Store({
@ -19,7 +19,6 @@ export default new Vuex.Store({
currentRoomEntry: '',
parentRoom: null,
parentModule: '',
objectiveGroupType: '',
currentObjectiveGroup: '',
parentProject: null,
currentNote: null,
@ -34,7 +33,10 @@ export default new Vuex.Store({
scrollToAssignmentId: '',
scrollToAssignmentReady: false,
scrollingToAssignment: false,
editModule: false
editModule: false,
modulePayload: [],
modalResolve: () => {},
modalReject: () => {},
},
getters: {
@ -51,12 +53,21 @@ export default new Vuex.Store({
currentNote: state => state.currentNote,
currentNoteParent: state => state.currentNoteParent,
noteType: state => state.noteType,
modulePayload: state => state.modulePayload
},
actions: {
setSpecialContainerClass({commit}, payload) {
commit('setSpecialContainerClass', payload);
},
confirmModal({dispatch, state}) {
dispatch('hideModal');
state.modalResolve();
},
cancelModal({dispatch, state}) {
dispatch('hideModal');
state.modalReject();
},
hideModal({commit, dispatch}) {
document.body.classList.remove('no-scroll'); // won't get at the body any other way
commit('setModal', false);
@ -70,8 +81,6 @@ export default new Vuex.Store({
commit('setContentBlockPosition', {});
commit('setParentRoom', null);
commit('setParentModule', '');
// todo: remove
commit('setObjectiveGroupType', '');
commit('setCurrentObjectiveGroup', '');
commit('setParentProject', null);
commit('setCurrentProjectEntry', null);
@ -83,6 +92,7 @@ export default new Vuex.Store({
commit('setVimeoId', null);
commit('setCurrentNote', null);
commit('setNoteType', '');
commit('setModulePayload', []);
},
resetContentBlockPosition({commit}) {
commit('setContentBlockPosition', {});
@ -110,19 +120,14 @@ export default new Vuex.Store({
commit('setCurrentRoomEntry', payload);
dispatch('showModal', 'edit-room-entry-wizard');
},
// todo: remove
addObjectiveGroup({commit, dispatch}, {module, type}) {
commit('setParentModule', module);
commit('setObjectiveGroupType', type);
dispatch('showModal', 'new-objective-group-wizard');
},
editObjectiveGroup({commit, dispatch}, payload) {
commit('setCurrentObjectiveGroup', payload);
dispatch('showModal', 'edit-objective-group-wizard');
},
showModal({commit}, payload) {
document.body.classList.add('no-scroll'); // won't get at the body any other way
commit('setModal', payload);
return new Promise((resolve, reject) => {
commit('setModalResolve', resolve);
commit('setModalReject', reject);
})
},
addProjectEntry({commit, dispatch}, payload) {
commit('setParentProject', payload);
@ -179,6 +184,13 @@ export default new Vuex.Store({
},
editModule({commit}, payload) {
commit('setEditModule', payload)
},
editClassName({dispatch}, payload) {
dispatch('showModal', 'edit-class-name-wizard');
},
deactivateUser({commit, dispatch}, payload) {
commit('setModulePayload', payload);
return dispatch('showModal', 'deactivate-person');
}
},
@ -216,10 +228,6 @@ export default new Vuex.Store({
setParentModule(state, payload) {
state.parentModule = payload;
},
// todo: remove
setObjectiveGroupType(state, payload) {
state.objectiveGroupType = payload;
},
setCurrentObjectiveGroup(state, payload) {
state.currentObjectiveGroup = payload;
},
@ -258,6 +266,15 @@ export default new Vuex.Store({
},
setNoteType(state, payload) {
state.noteType = payload;
},
setModulePayload(state, payload) {
state.modulePayload = payload;
},
setModalResolve(state, payload) {
state.modalResolve = payload;
},
setModalReject(state, payload) {
state.modalReject = payload;
}
}
})

View File

@ -0,0 +1,21 @@
.book-subnavigation {
&__item {
@include small-text;
margin-bottom: $small-spacing;
cursor: pointer;
color: $color-silver-dark;
&--mobile {
color: $color-white;
}
&:last-of-type {
margin-bottom: 0;
}
&--active {
color: $color-brand;
}
}
}

View File

@ -7,6 +7,7 @@
font-weight: $font-weight-regular;
display: inline-flex;
cursor: pointer;
@include small-text;
&--active {
border-color: $color-brand;

View File

@ -1,23 +1,30 @@
@import "@/styles/_variables.scss";
@import "@/styles/_mixins.scss";
.skillbox {
.layout {
$footer-height: 287px;
margin: 0 auto;
width: 100%;
/*
* For IE10+
*/
display: flex;
flex-direction: column;
@supports (display: grid) {
display: grid;
}
grid-template-rows: auto 1fr;
grid-template-rows: auto 1fr auto;
grid-template-areas: "h" "c" "f";
min-height: 100vh;
grid-auto-rows: 1fr;
grid-template-areas: "h" "c";
padding-bottom: 50px;
&--show-filter {
grid-template-rows: auto auto 1fr;
-ms-grid-rows: 50px 50px 30px 1fr; // 1 extra row for gap
grid-template-areas: "h" "." "c";
grid-template-rows: auto auto 1fr $footer-height;
-ms-grid-rows: 50px 50px 30px 1fr $footer-height; // 1 extra row for gap
grid-template-areas: "h" "." "c" "f";
}
/*
@ -34,39 +41,15 @@
-ms-grid-column: 1;
}
/*
* For IE10+
*/
display: -ms-grid;
-ms-grid-rows: 50px 30px auto; // 1 extra row for gap
-ms-grid-columns: 1fr;
@include skillbox-colors;
&__header {
grid-area: h;
-ms-grid-row: 1;
}
&__content {
-ms-grid-row: 3;
-ms-grid-column: 1;
}
&__footer {
grid-area: f;
display: none;
}
/*
* For IE10+
*/
& > :nth-child(2) {
}
& > :nth-child(3) {
-ms-grid-row: 4;
-ms-grid-column: 1;
margin-top: 3*$large-spacing;
}
}

View File

@ -154,4 +154,13 @@ $icon-size: 20px;
margin-top: 1px;
}
}
&--matrix {
margin: 0;
#{$base}__label-container {
display: flex;
justify-content: flex-start;
}
}
}

View File

@ -117,6 +117,16 @@
font-size: toRem(16px);
}
@mixin aside-text {
@include regular-text;
font-size: toRem(14px);
}
@mixin aside-with-cheese {
@include aside-text;
font-weight: 600;
}
@mixin meta-title {
color: $color-silver-dark;
font-size: toRem(36px);
@ -146,6 +156,7 @@
font-family: $sans-serif-font-family;
font-weight: $font-weight-regular;
color: $color-silver-dark;
cursor: pointer;
&--active {
color: $color-brand;

View File

@ -0,0 +1,24 @@
@import "variables";
.simple-list {
border-top: 1px solid $color-silver-dark;
&--active {
margin-bottom: 2*$large-spacing;
}
&__item {
line-height: $list-height;
height: $list-height;
border-bottom: 1px solid $color-silver-dark;
display: flex;
flex-direction: row;
justify-content: space-between;
}
&__action {
@include default-link;
color: $color-brand;
}
}

View File

@ -2,6 +2,7 @@
&__page-title {
@include main-title;
margin-bottom: $large-spacing*2;
span {
@include main-title;
}
@ -22,6 +23,7 @@
&__question-title {
@include heading-4;
margin-bottom: $medium-spacing;
> span > span { // weird survey.js html structure
@include heading-4;
line-height: $default-line-height;
@ -57,6 +59,7 @@
}
$progress-margin-right: 140px;
&__progress {
background-color: $color-silver-light;
height: 0.3em;
@ -67,6 +70,10 @@
margin-right: $progress-margin-right;
box-sizing: border-box;
display: flex;
> span {
display: none;
}
}
&__radiogroup-group, &__checkbox-group {
@ -102,11 +109,58 @@
&__completed-text {
@include regular-text;
}
&__matrix {
width: 100%;
}
}
.matrix {
margin-bottom: $large-spacing;
&__row {
display: table-row;
border-top: 1px solid $color-silver;
}
&__cell {
display: table-cell;
padding: $medium-spacing 0;
text-align: left;
vertical-align: middle;
@include small-text;
span {
line-height: 1.5;
}
}
thead {
th {
text-align: left;
@include small-text;
vertical-align: bottom;
padding: $small-spacing/2 $small-spacing/2 $small-spacing/2 0;
> span {
margin-right: $small-spacing;
}
}
}
&__radio {
margin: 0;
}
&__label {
display: flex;
}
}
.question {
$question: &;
&--error #{$question}__input {
border-color: $color-error;
box-shadow: none;

Some files were not shown because too many files have changed in this diff Show More