Merged in feature/new-start-page (pull request #69)
Feature/new start page Approved-by: Christian Cueni
This commit is contained in:
commit
6238be62bc
|
|
@ -16,6 +16,10 @@ definitions:
|
|||
image: postgres
|
||||
variables:
|
||||
POSTGRES_HOST_AUTH_METHOD: trust
|
||||
caches:
|
||||
npm: $HOME/.npm
|
||||
cypress: $HOME/.cache/Cypress
|
||||
|
||||
|
||||
aliases:
|
||||
- &lint
|
||||
|
|
@ -39,6 +43,7 @@ aliases:
|
|||
caches:
|
||||
- pip
|
||||
- node
|
||||
- npm
|
||||
artifacts:
|
||||
- client/cypress/**/*.png
|
||||
- client/cypress/**/*.mp4
|
||||
|
|
@ -47,8 +52,8 @@ aliases:
|
|||
script:
|
||||
- echo "This pipeline rules!"
|
||||
- *setup-tests
|
||||
- npm install --prefix client
|
||||
# - npm run "install:cypress" --prefix client
|
||||
- npm ci --prefix client
|
||||
- npm run "install:cypress" --prefix client
|
||||
- psql -U $DATABASE_USER -h $DATABASE_HOST -c "create database $DATABASE_NAME"
|
||||
- python server/manage.py dummy_data
|
||||
- python server/manage.py runserver &
|
||||
|
|
|
|||
|
|
@ -0,0 +1,263 @@
|
|||
{
|
||||
"lohn-und-budget": {
|
||||
"id": "TW9kdWxlTm9kZToyOA==",
|
||||
"title": "Lohn und Budget",
|
||||
"metaTitle": "Modul 1",
|
||||
"teaser": "Die Berufsbildung ist ein neuer Lebensabschnit",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung übernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "lohn-und-budget",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": {
|
||||
"note": null,
|
||||
"__typename": "ModuleBookmarkNode"
|
||||
},
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ==",
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"solution": null,
|
||||
"submission": {
|
||||
"id": "U3R1ZGVudFN1Ym1pc3Npb25Ob2RlOjE=",
|
||||
"text": "Hir ist ein Feler gewesen",
|
||||
"final": false,
|
||||
"document": "",
|
||||
"submissionFeedback": {
|
||||
"id": "U3VibWlzc2lvbkZlZWRiYWNrTm9kZTox",
|
||||
"text": "🙂😐🤬👍🤢🤢🤢🤢😮🤗",
|
||||
"teacher": {
|
||||
"firstName": "Nico",
|
||||
"lastName": "Zickgraf",
|
||||
"__typename": "UserNode"
|
||||
},
|
||||
"__typename": "SubmissionFeedbackNode"
|
||||
},
|
||||
"__typename": "StudentSubmissionNode"
|
||||
},
|
||||
"__typename": "AssignmentNode"
|
||||
},
|
||||
"__typename": "AssignmentNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MTg=",
|
||||
"title": "1.1 Lehrbeginn",
|
||||
"description": "Wie sieht Ihr Konsumverhalten aus?",
|
||||
"bookmark": null,
|
||||
"contentBlocks": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q29udGVudEJsb2NrTm9kZToxOQ==",
|
||||
"slug": "assignment",
|
||||
"title": "Assignment",
|
||||
"type": "NORMAL",
|
||||
"contents": [
|
||||
{
|
||||
"type": "assignment",
|
||||
"value": {
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ=="
|
||||
},
|
||||
"id": "df8212ee-3e82-49fa-977e-c4b60789163e"
|
||||
}
|
||||
],
|
||||
"userCreated": false,
|
||||
"mine": false,
|
||||
"bookmarks": [
|
||||
],
|
||||
"hiddenFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"visibleFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"__typename": "ContentBlockNode"
|
||||
},
|
||||
"__typename": "ContentBlockNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
},
|
||||
"geld": {
|
||||
"id": "TW9kdWxlTm9kZTo0Mg==",
|
||||
"title": "Geld",
|
||||
"metaTitle": "Modul 2",
|
||||
"teaser": " Geld braucht jeder von uns im t\u00e4glichen Leben.",
|
||||
"intro": "\n <p>Jeder B\u00fcrger nutzt es. Nahezu jeden Tag. Kaum ein Tag vergeht, an dem wir nicht mit M\u00fcnzen oder Geldscheinen bezahlen, bargeldlose \u00dcberweisungen t\u00e4tigen oder andere Zahlungsmethoden verwenden. Doch was genau befindet sich da eigentlich in unserem Geldbeutel? Was ist das, was auf unseren Konten liegt und die Bezeichnung Geld tr\u00e4gt?</p>\n ",
|
||||
"slug": "geld",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MzI=",
|
||||
"title": "2.1 Eine Welt ohne Geld?",
|
||||
"description": "",
|
||||
"bookmark": null,
|
||||
"contentBlocks": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q29udGVudEJsb2NrTm9kZToxOQ==",
|
||||
"slug": "assignment",
|
||||
"title": "Assignment",
|
||||
"type": "NORMAL",
|
||||
"contents": [
|
||||
{
|
||||
"type": "assignment",
|
||||
"value": {
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ=="
|
||||
},
|
||||
"id": "df8212ee-3e82-49fa-977e-c4b60789163e"
|
||||
}
|
||||
],
|
||||
"userCreated": false,
|
||||
"mine": false,
|
||||
"bookmarks": [
|
||||
],
|
||||
"hiddenFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"visibleFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"__typename": "ContentBlockNode"
|
||||
},
|
||||
"__typename": "ContentBlockNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
},
|
||||
"lerntipps": {
|
||||
"id": "TW9kdWxlTm9kZTo3MA==",
|
||||
"title": "Lerntipps",
|
||||
"metaTitle": "Modul 4",
|
||||
"teaser": "Lerntipps",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung übernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "lerntipps",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": {
|
||||
"note": null,
|
||||
"__typename": "ModuleBookmarkNode"
|
||||
},
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MTg=",
|
||||
"title": "1.1 Lehrbeginn",
|
||||
"description": "Wie sieht Ihr Konsumverhalten aus?",
|
||||
"bookmark": null,
|
||||
"contentBlocks": {
|
||||
"edges": [],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
},
|
||||
"random": {
|
||||
"id": "TW9kdWxlTm9kZTo1NA==",
|
||||
"title": "Random",
|
||||
"metaTitle": "Modul 5",
|
||||
"teaser": "Random",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung übernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "random",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": {
|
||||
"note": null,
|
||||
"__typename": "ModuleBookmarkNode"
|
||||
},
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MTg=",
|
||||
"title": "1.1 Lehrbeginn",
|
||||
"description": "Wie sieht Ihr Konsumverhalten aus?",
|
||||
"bookmark": null,
|
||||
"contentBlocks": {
|
||||
"edges": [],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
{
|
||||
"topic": {
|
||||
"id": "VG9waWNOb2RlOjU=",
|
||||
"title": "Geld und Kauf",
|
||||
"teaser": "Die berufliche Grundbildung lehrt Sie, den Arbeitsalltag erfolgreich zu bew\u00e4ltigen, Ihre F\u00e4higkeiten zu entwickeln und beruflich flexibel zu sein. Ebenso wichtig ist der Umgang mit verschiedensten Mitmenschen. Eine angemessene m\u00fcndliche Kommunikation erleichtert das Zusammenleben und Zusammenarbeiten.",
|
||||
"slug": "geld-und-kauf",
|
||||
"description": "Deserunt in ut.\nAccusamus distinctio necessitatibus similique consequatur molestias. Sed magnam provident distinctio quia. Cumque repellat hic ipsum commodi.",
|
||||
"vimeoId": null,
|
||||
"instructions": null,
|
||||
"modules": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "TW9kdWxlTm9kZTo2",
|
||||
"title": "Einleitung",
|
||||
"metaTitle": "Video",
|
||||
"teaser": "Die Berufsbildung ist ein neuer Lebensabschnit",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung \u00fcbernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "einleitung",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"__typename": "ModuleNodeEdge"
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "TW9kdWxlTm9kZToyOA==",
|
||||
"title": "Lohn und Budget",
|
||||
"metaTitle": "Modul 1",
|
||||
"teaser": "Die Berufsbildung ist ein neuer Lebensabschnit",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung \u00fcbernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "lohn-und-budget",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"__typename": "ModuleNodeEdge"
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "TW9kdWxlTm9kZTo0Mg==",
|
||||
"title": "Geld",
|
||||
"metaTitle": "Modul 2",
|
||||
"teaser": " Geld braucht jeder von uns im t\u00e4glichen Leben.",
|
||||
"intro": "\n <p>Jeder B\u00fcrger nutzt es. Nahezu jeden Tag. Kaum ein Tag vergeht, an dem wir nicht mit M\u00fcnzen oder Geldscheinen bezahlen, bargeldlose \u00dcberweisungen t\u00e4tigen oder andere Zahlungsmethoden verwenden. Doch was genau befindet sich da eigentlich in unserem Geldbeutel? Was ist das, was auf unseren Konten liegt und die Bezeichnung Geld tr\u00e4gt?</p>\n ",
|
||||
"slug": "geld",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"__typename": "ModuleNodeEdge"
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "TW9kdWxlTm9kZTo3MA==",
|
||||
"title": "Lerntipps",
|
||||
"metaTitle": "Modul 4",
|
||||
"teaser": "Wie gehen Sie vor, wenn Sie sich auf eine Pr\u00fcfung vor-bereiten?",
|
||||
"intro": "Ea ullam nam expedita voluptates consequuntur voluptates vitae. Earum eos iste sint mollitia ab.\nVoluptate autem commodi consequuntur enim magni. Incidunt temporibus voluptatibus numquam.",
|
||||
"slug": "lerntipps",
|
||||
"heroImage": "/media/original_images/dummy_PCmN1m5.jpg",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "berufliche-grundbildung",
|
||||
"title": "Berufliche Grundbildung",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"__typename": "ModuleNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ModuleNodeConnection"
|
||||
},
|
||||
"__typename": "TopicNode"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
"pk": 5,
|
||||
"username": "rahel.cueni",
|
||||
"email": "rahel.cueni@skillbox.example",
|
||||
"expiryDate": "3596153600",
|
||||
"firstName": "Rahel",
|
||||
"lastName": "Cueni",
|
||||
"avatarUrl": "",
|
||||
|
|
@ -17,6 +18,11 @@
|
|||
"id": "U2Nob29sQ2xhc3NOb2RlOjI=",
|
||||
"__typename": "SchoolClassNode"
|
||||
},
|
||||
"lastTopic": {
|
||||
"id": "VG9waWNOb2RlOjU=",
|
||||
"slug": "geld-und-kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"schoolClasses": {
|
||||
"edges": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
{
|
||||
"TW9kdWxlTm9kZToyOA==": {
|
||||
"id": "TW9kdWxlTm9kZToyOA==",
|
||||
"title": "Lohn und Budget",
|
||||
"metaTitle": "Modul 1",
|
||||
"teaser": "Die Berufsbildung ist ein neuer Lebensabschnit",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung \u00fcbernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "lohn-und-budget",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"TW9kdWxlTm9kZTo0Mg==": {
|
||||
"id": "TW9kdWxlTm9kZTo0Mg==",
|
||||
"title": "Geld",
|
||||
"metaTitle": "Modul 2",
|
||||
"teaser": " Geld braucht jeder von uns im t\u00e4glichen Leben.",
|
||||
"intro": "\n <p>Jeder B\u00fcrger nutzt es. Nahezu jeden Tag. Kaum ein Tag vergeht, an dem wir nicht mit M\u00fcnzen oder Geldscheinen bezahlen, bargeldlose \u00dcberweisungen t\u00e4tigen oder andere Zahlungsmethoden verwenden. Doch was genau befindet sich da eigentlich in unserem Geldbeutel? Was ist das, was auf unseren Konten liegt und die Bezeichnung Geld tr\u00e4gt?</p>\n ",
|
||||
"slug": "geld",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"TW9kdWxlTm9kZTo3MA==": {
|
||||
"id": "TW9kdWxlTm9kZTo3MA==",
|
||||
"title": "Lerntipps",
|
||||
"metaTitle": "Modul 4",
|
||||
"teaser": "Wie gehen Sie vor, wenn Sie sich auf eine Pr\u00fcfung vor-bereiten?",
|
||||
"intro": "Ea ullam nam expedita voluptates consequuntur voluptates vitae. Earum eos iste sint mollitia ab.\nVoluptate autem commodi consequuntur enim magni. Incidunt temporibus voluptatibus numquam.",
|
||||
"slug": "lerntipps",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
},
|
||||
"TW9kdWxlTm9kZTo1NA==": {
|
||||
"id": "TW9kdWxlTm9kZTo1NA==",
|
||||
"title": "Random",
|
||||
"metaTitle": "Modul 5",
|
||||
"teaser": "Wie gehen Sie vor, wenn Sie sich auf eine Pr\u00fcfung vor-bereiten?",
|
||||
"intro": "Ea ullam nam expedita voluptates consequuntur voluptates vitae. Earum eos iste sint mollitia ab.\nVoluptate autem commodi consequuntur enim magni. Incidunt temporibus voluptatibus numquam.",
|
||||
"slug": "random",
|
||||
"heroImage": "",
|
||||
"solutionsEnabled": false,
|
||||
"topic": {
|
||||
"slug": "geld-und-kauf",
|
||||
"title": "Geld und Kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"topics": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "VG9waWNOb2RlOjU=",
|
||||
"order": 1,
|
||||
"title": "Geld und Kauf",
|
||||
"slug": "geld-und-kauf",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"__typename": "TopicEdge"
|
||||
},
|
||||
{
|
||||
"node": {
|
||||
"id": "VG9waWNOb2RlOjUz",
|
||||
"order": 2,
|
||||
"title": "Berufliche Grundbildung",
|
||||
"slug": "berufliche-grundbildung",
|
||||
"__typename": "TopicNode"
|
||||
},
|
||||
"__typename": "TopicEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "TopicConnection"
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ describe('The Login Page', () => {
|
|||
const password = 'test';
|
||||
cy.visit('/beta-login');
|
||||
cy.login(username, password, true);
|
||||
cy.get('body').contains('Neues Wissen erwerben');
|
||||
cy.assertStartPage();
|
||||
});
|
||||
|
||||
it('user sees error message if username is omitted', () => {
|
||||
|
|
@ -35,7 +35,6 @@ describe('The Login Page', () => {
|
|||
});
|
||||
|
||||
it('logs out then logs in again', () => {
|
||||
|
||||
const user = 'rahel.cueni';
|
||||
const pw = 'test'
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
describe('Bookmarks', () => {
|
||||
beforeEach(() => {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
cy.exec("python ../server/manage.py prepare_bookmarks_for_cypress");
|
||||
cy.exec('python ../server/manage.py prepare_bookmarks_for_cypress');
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.startGraphQLCapture();
|
||||
cy.login('rahel.cueni', 'test', true);
|
||||
cy.get('body').contains('Neues Wissen erwerben');
|
||||
cy.assertStartPage();
|
||||
});
|
||||
|
||||
it('should bookmark content block', () => {
|
||||
|
|
@ -35,5 +35,4 @@ describe('Bookmarks', () => {
|
|||
|
||||
cy.get('[data-cy=modal-save-button]').click();
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { GraphQLError } from "graphql";
|
||||
import { GraphQLError } from 'graphql';
|
||||
|
||||
const schema = require('../fixtures/schema.json');
|
||||
|
||||
|
|
@ -20,23 +20,21 @@ describe('Email Verifcation', () => {
|
|||
}
|
||||
});
|
||||
cy.login('rahel.cueni', 'test', true)
|
||||
cy.get('[data-cy="rooms-link"]').contains('Alle Räume anzeigen');
|
||||
cy.assertStartPage();
|
||||
|
||||
cy.visit('/license-activation');
|
||||
cy.redeemCoupon('12345asfd');
|
||||
cy.get('body').contains('Neues Wissen erwerben');
|
||||
|
||||
cy.assertStartPage();
|
||||
});
|
||||
|
||||
it('displays error if input is missing', () => {
|
||||
cy.viewport('macbook-15');
|
||||
cy.login('rahel.cueni', 'test', true)
|
||||
cy.get('[data-cy="rooms-link"]').contains('Alle Räume anzeigen');
|
||||
cy.assertStartPage();
|
||||
|
||||
cy.visit('/license-activation');
|
||||
cy.redeemCoupon('');
|
||||
cy.get('[data-cy="coupon-local-errors"]').contains('Coupon ist ein Pflichtfeld.');
|
||||
|
||||
});
|
||||
|
||||
it('displays error if coupon input is wrong', () => {
|
||||
|
|
@ -48,12 +46,11 @@ describe('Email Verifcation', () => {
|
|||
}
|
||||
});
|
||||
cy.login('rahel.cueni', 'test', true)
|
||||
cy.get('[data-cy="rooms-link"]').contains('Alle Räume anzeigen');
|
||||
cy.assertStartPage();
|
||||
|
||||
cy.visit('/license-activation');
|
||||
cy.redeemCoupon('12345asfd');
|
||||
cy.get('[data-cy="coupon-remote-errors"]').contains('Der angegebene Coupon-Code ist ungültig.');
|
||||
|
||||
});
|
||||
|
||||
it('displays error if an error occures', () => {
|
||||
|
|
@ -61,16 +58,14 @@ describe('Email Verifcation', () => {
|
|||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
operations: {
|
||||
Coupon: new GraphQLError("unknown_error")
|
||||
Coupon: new GraphQLError('unknown_error')
|
||||
}
|
||||
});
|
||||
cy.login('rahel.cueni', 'test', true)
|
||||
cy.get('[data-cy="rooms-link"]').contains('Alle Räume anzeigen');
|
||||
cy.assertStartPage();
|
||||
|
||||
cy.visit('/license-activation');
|
||||
cy.redeemCoupon('12345asfd');
|
||||
cy.get('[data-cy="coupon-remote-errors"]').contains('Es ist ein Fehler aufgetreten. Bitte versuchen Sie es nochmals oder kontaktieren Sie den Administrator.');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,12 +1,65 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
const assignments = require('../fixtures/assignments.json');
|
||||
const lohnModule = require('../fixtures/module.json');
|
||||
const geldModule = require('../fixtures/module-geld.json');
|
||||
const mePayload = require('../fixtures/me.join-class.json');
|
||||
const topics = require('../fixtures/topics.json');
|
||||
const baseTopic = require('../fixtures/geld-und-kauf.json');
|
||||
|
||||
const moduleTeasers = require('../fixtures/module-teasers.json');
|
||||
const fullModules = require('../fixtures/full-modules.json');
|
||||
|
||||
const topic = {
|
||||
topic: {
|
||||
...baseTopic.topic,
|
||||
modules: {
|
||||
'__typename': 'ModuleNodeConnection',
|
||||
edges: [
|
||||
...Object.values(moduleTeasers).map(module => {
|
||||
return {
|
||||
node: module,
|
||||
__typename: 'ModuleNodeEdge'
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cypress.Commands.add('checkHome', (n, skipHome) => {
|
||||
if (!skipHome) {
|
||||
cy.get('[data-cy="home-link"]').click();
|
||||
}
|
||||
cy.get('[data-cy=start-modules-list]').should('exist');
|
||||
cy.get('[data-cy=start-module-teaser]').should('have.length', n);
|
||||
});
|
||||
|
||||
Cypress.Commands.add('goToModule', (topicTitle, moduleMetaTitle) => {
|
||||
cy.get('[data-cy=open-sidebar-link]').click();
|
||||
cy.contains(topicTitle).click();
|
||||
cy.get('[data-cy=topic-title]').should('exist').should('contain', topicTitle);
|
||||
cy.contains(moduleMetaTitle).click();
|
||||
});
|
||||
|
||||
describe('Current Module', () => {
|
||||
before(() => {
|
||||
cy.server();
|
||||
|
||||
let me = {
|
||||
...mePayload.me,
|
||||
lastModule: {
|
||||
// 'id': 'TW9kdWxlTm9kZToxNw==',
|
||||
'slug': 'lohn-und-budget',
|
||||
'__typename': 'ModuleNode'
|
||||
},
|
||||
lastTopic: {
|
||||
'id': 'VG9waWNOb2RlOjU=',
|
||||
'slug': 'geld-und-kauf',
|
||||
'__typename': 'TopicNode'
|
||||
},
|
||||
recentModules: {
|
||||
'edges': [],
|
||||
'__typename': 'ModuleNodeConnection'
|
||||
},
|
||||
};
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
// endpoint: '/api/graphql'
|
||||
|
|
@ -14,16 +67,7 @@ describe('Current Module', () => {
|
|||
MeQuery: variables => {
|
||||
return {
|
||||
me: {
|
||||
'lastModule': {
|
||||
// 'id': 'TW9kdWxlTm9kZToxNw==',
|
||||
'slug': 'lohn-und-budget',
|
||||
'__typename': 'ModuleNode'
|
||||
},
|
||||
'lastTopic': {
|
||||
'id': 'VG9waWNOb2RlOjU=',
|
||||
'slug': 'geld-und-kauf',
|
||||
'__typename': 'TopicNode'
|
||||
},
|
||||
...me,
|
||||
'__typename': 'UserNode',
|
||||
'permissions': []
|
||||
}
|
||||
|
|
@ -33,28 +77,22 @@ describe('Current Module', () => {
|
|||
assignments
|
||||
},
|
||||
ModulesQuery: variables => {
|
||||
let module;
|
||||
if (variables.slug === 'lohn-und-budget') {
|
||||
module = lohnModule;
|
||||
} else {
|
||||
module = geldModule
|
||||
}
|
||||
return {
|
||||
module
|
||||
module: fullModules[variables.slug]
|
||||
}
|
||||
},
|
||||
TopicsQuery: topics,
|
||||
Topic: topic,
|
||||
UpdateLastTopic: {
|
||||
'updateLastTopic': {
|
||||
'topic': topic.topic,
|
||||
'__typename': 'UpdateLastTopicPayload'
|
||||
}
|
||||
},
|
||||
UpdateLastModule: variables => {
|
||||
let module;
|
||||
if (variables.input.id === 'TW9kdWxlTm9kZToxNw==') {
|
||||
module = lohnModule
|
||||
} else {
|
||||
module = geldModule
|
||||
}
|
||||
|
||||
return {
|
||||
updateLastModule: {
|
||||
module,
|
||||
errors: null,
|
||||
lastModule: moduleTeasers[variables.input.id],
|
||||
__typename: 'UpdateLastModulePayload'
|
||||
}
|
||||
}
|
||||
|
|
@ -67,21 +105,50 @@ describe('Current Module', () => {
|
|||
cy.viewport('macbook-15');
|
||||
|
||||
cy.apolloLogin('nico.zickgraf', 'test');
|
||||
cy.visit('/book/topic/geld-und-kauf');
|
||||
cy.contains('Modul 1').click();
|
||||
cy.visit('/');
|
||||
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
||||
// module list exists, but does not have anything in it
|
||||
cy.checkHome(0, true);
|
||||
cy.get('[data-cy=no-modules-yet]').should('exist').should('contain', 'Sie haben sich noch kein Modul angeschaut. Legen Sie jetzt los!');
|
||||
|
||||
cy.get('[data-cy="home-link"]').click();
|
||||
cy.get('[data-cy="current-module-link"]').click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
||||
|
||||
cy.visit('/book/topic/geld-und-kauf');
|
||||
cy.contains('Modul 2').click();
|
||||
cy.goToModule('Geld und Kauf', 'Modul 2');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld');
|
||||
cy.checkHome(1);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
|
||||
|
||||
cy.get('[data-cy="home-link"]').click();
|
||||
cy.get('[data-cy="current-module-link"]').click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld')
|
||||
cy.goToModule('Geld und Kauf', 'Modul 1');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
||||
cy.checkHome(2);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lohn und Budget');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
|
||||
|
||||
cy.goToModule('Geld und Kauf', 'Modul 4');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
|
||||
cy.checkHome(3);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lohn und Budget');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
|
||||
|
||||
// module list is full, should switch only the order around
|
||||
cy.goToModule('Geld und Kauf', 'Modul 2');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld');
|
||||
cy.checkHome(3);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Geld');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Lerntipps');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lohn und Budget');
|
||||
|
||||
cy.goToModule('Geld und Kauf', 'Modul 5');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Random');
|
||||
cy.checkHome(3);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Random');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Geld');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Lerntipps');
|
||||
|
||||
cy.get('[data-cy=start-module-teaser]').last().click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lerntipps');
|
||||
cy.checkHome(3);
|
||||
cy.get('[data-cy=start-module-teaser]').first().should('contain', 'Lerntipps');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(1).should('contain', 'Random');
|
||||
cy.get('[data-cy=start-module-teaser]').eq(2).should('contain', 'Geld');
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
// import 'cypress-graphql-mock';
|
||||
import '@iam4x/cypress-graphql-mock';
|
||||
|
||||
|
||||
Cypress.Commands.add('apolloLogin', (username, password) => {
|
||||
const payload = {
|
||||
'operationName': 'BetaLogin',
|
||||
|
|
@ -47,12 +46,10 @@ Cypress.Commands.add('apolloLogin', (username, password) => {
|
|||
url: '/api/graphql-public/',
|
||||
body: payload
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
// todo: replace with apollo call
|
||||
Cypress.Commands.add("login", (username, password, visitLogin = false) => {
|
||||
Cypress.Commands.add('login', (username, password, visitLogin = false) => {
|
||||
if (visitLogin) {
|
||||
cy.visit('/beta-login');
|
||||
}
|
||||
|
|
@ -67,7 +64,7 @@ Cypress.Commands.add("login", (username, password, visitLogin = false) => {
|
|||
cy.get('[data-cy=login-button]').click();
|
||||
});
|
||||
|
||||
Cypress.Commands.add("logout", () => {
|
||||
Cypress.Commands.add('logout', () => {
|
||||
cy.get('[data-cy=user-icon]').click();
|
||||
cy.get('[data-cy=logout]').click();
|
||||
});
|
||||
|
|
@ -122,7 +119,6 @@ Cypress.Commands.add('enterPassword', (password) => {
|
|||
});
|
||||
|
||||
Cypress.Commands.add('register', (prefix, firstname, lastname, street, city, postcode, password, passwordConfirmation, acceptTerms) => {
|
||||
|
||||
let selection = prefix === 1 ? 'Herr' : 'Frau';
|
||||
|
||||
cy.get('[data-cy="prefix-selection"]').select(selection);
|
||||
|
|
@ -153,7 +149,7 @@ Cypress.Commands.add('register', (prefix, firstname, lastname, street, city, pos
|
|||
if (acceptTerms) {
|
||||
cy.get('[data-cy="acceptedTerms-input"] > input').first().check({force: true}).then(() => {
|
||||
cy.get('[data-cy="acceptedTerms-input"] > input:checkbox').should('be.checked');
|
||||
});;
|
||||
});
|
||||
}
|
||||
|
||||
cy.get('[data-cy="passwordConfirmation-input"]').type(passwordConfirmation);
|
||||
|
|
@ -167,3 +163,6 @@ Cypress.Commands.add('redeemCoupon', coupon => {
|
|||
cy.get('[data-cy="coupon-button"]').click();
|
||||
})
|
||||
|
||||
Cypress.Commands.add('assertStartPage', () => {
|
||||
cy.get('[data-cy=start-modules-list]').should('exist');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2514,6 +2514,86 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@cypress/request": {
|
||||
"version": "2.88.5",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz",
|
||||
"integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.12.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz",
|
||||
"integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tough-cookie": {
|
||||
"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.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@cypress/xvfb": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
|
||||
|
|
@ -2969,6 +3049,12 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.1.tgz",
|
||||
"integrity": "sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw=="
|
||||
},
|
||||
"@types/sinonjs__fake-timers": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz",
|
||||
"integrity": "sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/sizzle": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
|
||||
|
|
@ -3395,9 +3481,9 @@
|
|||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
|
||||
},
|
||||
"arch": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz",
|
||||
"integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==",
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/arch/-/arch-2.1.2.tgz",
|
||||
"integrity": "sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ==",
|
||||
"dev": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
|
|
@ -7032,41 +7118,42 @@
|
|||
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
|
||||
},
|
||||
"cypress": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-4.2.0.tgz",
|
||||
"integrity": "sha512-8LdreL91S/QiTCLYLNbIjLL8Ht4fJmu/4HGLxUI20Tc7JSfqEfCmXELrRfuPT0kjosJwJJZacdSji9XSRkPKUw==",
|
||||
"version": "4.9.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-4.9.0.tgz",
|
||||
"integrity": "sha512-qGxT5E0j21FPryzhb0OBjCdhoR/n1jXtumpFFSBPYWsaZZhNaBvc3XlBUDEZKkkXPsqUFYiyhWdHN/zo0t5FcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cypress/listr-verbose-renderer": "0.4.1",
|
||||
"@cypress/request": "2.88.5",
|
||||
"@cypress/xvfb": "1.2.4",
|
||||
"@types/sinonjs__fake-timers": "6.0.1",
|
||||
"@types/sizzle": "2.3.2",
|
||||
"arch": "2.1.1",
|
||||
"arch": "2.1.2",
|
||||
"bluebird": "3.7.2",
|
||||
"cachedir": "2.3.0",
|
||||
"chalk": "2.4.2",
|
||||
"check-more-types": "2.24.0",
|
||||
"cli-table3": "0.5.1",
|
||||
"commander": "4.1.0",
|
||||
"commander": "4.1.1",
|
||||
"common-tags": "1.8.0",
|
||||
"debug": "4.1.1",
|
||||
"eventemitter2": "4.1.2",
|
||||
"eventemitter2": "6.4.2",
|
||||
"execa": "1.0.0",
|
||||
"executable": "4.1.1",
|
||||
"extract-zip": "1.6.7",
|
||||
"extract-zip": "1.7.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"getos": "3.1.4",
|
||||
"getos": "3.2.1",
|
||||
"is-ci": "2.0.0",
|
||||
"is-installed-globally": "0.1.0",
|
||||
"is-installed-globally": "0.3.2",
|
||||
"lazy-ass": "1.6.0",
|
||||
"listr": "0.14.3",
|
||||
"lodash": "4.17.15",
|
||||
"log-symbols": "3.0.0",
|
||||
"minimist": "1.2.2",
|
||||
"moment": "2.24.0",
|
||||
"minimist": "1.2.5",
|
||||
"moment": "2.26.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": "7.1.0",
|
||||
"tmp": "0.1.0",
|
||||
|
|
@ -7075,18 +7162,6 @@
|
|||
"yauzl": "2.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"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": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
|
|
@ -7116,9 +7191,9 @@
|
|||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.0.tgz",
|
||||
"integrity": "sha512-NIQrwvv9V39FHgGFm36+U9SMQzbiHvU79k+iADraJTpmrFFfx7Ds0IvDoAdZsDrknlkRk14OYoWXb57uTh7/sw==",
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
|
|
@ -7158,12 +7233,6 @@
|
|||
"strip-eof": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"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",
|
||||
|
|
@ -7187,22 +7256,6 @@
|
|||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
|
|
@ -7219,9 +7272,15 @@
|
|||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.2.tgz",
|
||||
"integrity": "sha512-rIqbOrKb8GJmx/5bc2M0QchhUouMXSpd1RTclXsB41JdL+VtnojfaJR+h7F9k18/4kHUsBFgk80Uk+q569vjPA==",
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.26.0",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
|
||||
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
|
|
@ -7230,12 +7289,6 @@
|
|||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pump": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||
|
|
@ -7246,33 +7299,6 @@
|
|||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"request": {
|
||||
"version": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
|
||||
"from": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
|
||||
|
|
@ -7307,16 +7333,6 @@
|
|||
"requires": {
|
||||
"rimraf": "^2.6.3"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"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.28",
|
||||
"punycode": "^2.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -8348,9 +8364,9 @@
|
|||
}
|
||||
},
|
||||
"eventemitter2": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
|
||||
"integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=",
|
||||
"version": "6.4.2",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.2.tgz",
|
||||
"integrity": "sha512-r/Pwupa5RIzxIHbEKCkNXqpEQIIT4uQDxmP4G/Lug/NokVUWj0joz/WzWl3OxRpC5kDrH/WdiUJoR+IrwvXJEw==",
|
||||
"dev": true
|
||||
},
|
||||
"eventemitter3": {
|
||||
|
|
@ -8705,15 +8721,15 @@
|
|||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
|
||||
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
|
||||
"integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-stream": "1.6.2",
|
||||
"debug": "2.6.9",
|
||||
"mkdirp": "0.5.1",
|
||||
"yauzl": "2.4.1"
|
||||
"concat-stream": "^1.6.2",
|
||||
"debug": "^2.6.9",
|
||||
"mkdirp": "^0.5.4",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
|
|
@ -8725,13 +8741,19 @@
|
|||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
|
||||
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fd-slicer": "~1.0.1"
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -8779,9 +8801,9 @@
|
|||
}
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
|
||||
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pend": "~1.2.0"
|
||||
|
|
@ -9072,9 +9094,9 @@
|
|||
},
|
||||
"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==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
|
||||
"integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
|
||||
"dev": true
|
||||
},
|
||||
"jsonfile": {
|
||||
|
|
@ -9685,12 +9707,12 @@
|
|||
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
|
||||
},
|
||||
"getos": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmjs.org/getos/-/getos-3.1.4.tgz",
|
||||
"integrity": "sha512-UORPzguEB/7UG5hqiZai8f0vQ7hzynMQyJLxStoQ8dPGAcmgsfXOPA4iE/fGtweHYkK+z4zc9V0g+CIFRf5HYw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz",
|
||||
"integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"async": "^3.1.0"
|
||||
"async": "^3.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"async": {
|
||||
|
|
@ -9783,12 +9805,12 @@
|
|||
}
|
||||
},
|
||||
"global-dirs": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
|
||||
"integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
|
||||
"integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ini": "^1.3.4"
|
||||
"ini": "^1.3.5"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
|
|
@ -10705,13 +10727,21 @@
|
|||
}
|
||||
},
|
||||
"is-installed-globally": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
|
||||
"integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
|
||||
"integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"global-dirs": "^0.1.0",
|
||||
"is-path-inside": "^1.0.0"
|
||||
"global-dirs": "^2.0.1",
|
||||
"is-path-inside": "^3.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-path-inside": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
|
||||
"integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
|
|
@ -17915,9 +17945,9 @@
|
|||
}
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
|
||||
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
|
||||
"version": "6.5.5",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
|
||||
"integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
|
|
@ -20729,17 +20759,6 @@
|
|||
"requires": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zen-observable": {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@
|
|||
"babel-core": "^7.0.0-bridge.0",
|
||||
"babel-jest": "^24.8.0",
|
||||
"canvas": "^2.5.0",
|
||||
"cypress": "^4.2.0",
|
||||
"cypress": "^4.9.0",
|
||||
"jest": "^24.8.0",
|
||||
"jest-serializer-vue": "^2.0.2",
|
||||
"jest-transform-graphql": "^2.1.0",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
<script>
|
||||
import DefaultLayout from '@/layouts/DefaultLayout';
|
||||
import SimpleLayout from '@/layouts/SimpleLayout';
|
||||
import BlankLayout from '@/layouts/BlankLayout';
|
||||
import FullScreenLayout from '@/layouts/FullScreenLayout';
|
||||
import PublicLayout from '@/layouts/PublicLayout';
|
||||
import Modal from '@/components/Modal';
|
||||
|
|
@ -47,7 +46,6 @@
|
|||
ScrollUp,
|
||||
DefaultLayout,
|
||||
SimpleLayout,
|
||||
BlankLayout,
|
||||
FullScreenLayout,
|
||||
PublicLayout,
|
||||
Modal,
|
||||
|
|
@ -87,6 +85,7 @@
|
|||
|
||||
body {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<header class="header-bar">
|
||||
<a
|
||||
class="header-bar__sidebar-link"
|
||||
data-cy="open-sidebar-link"
|
||||
@click="openSidebar('navigation')">
|
||||
<hamburger class="header-bar__sidebar-icon"/>
|
||||
</a>
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
<template>
|
||||
<div class="news-teasers">
|
||||
<div
|
||||
:key="teaser.id"
|
||||
class="news-teasers__teaser teaser"
|
||||
v-for="teaser in newsTeasers">
|
||||
<a :href="teaser.newsArticleUrl">
|
||||
<img
|
||||
:src="teaser.imageUrl"
|
||||
class="teaser__image">
|
||||
<p class="teaser__image-source">
|
||||
<a
|
||||
:href="teaser.imageSource"
|
||||
class="tiny-text">Quelle {{ teaser.imageSource }}</a></p>
|
||||
<h4 class="teaser__title">{{ teaser.title }}</h4>
|
||||
<p class="teaser__description">{{ teaser.description }}</p>
|
||||
<p class="teaser__date">{{ teaser.displayDate }}</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NEWS_TEASER_QUERY from '@/graphql/gql/newsTeasersQuery.gql';
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
|
||||
data() {
|
||||
return {
|
||||
newsTeasers: []
|
||||
};
|
||||
},
|
||||
|
||||
apollo: {
|
||||
$client: 'publicClient',
|
||||
newsTeasers: {
|
||||
query: NEWS_TEASER_QUERY,
|
||||
update(data) {
|
||||
return this.$getRidOfEdges(data).newsTeasers;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_functions.scss";
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
$news_width: 550px;
|
||||
$image_height: 254px;
|
||||
|
||||
.teasers {
|
||||
display: block;
|
||||
|
||||
@include desktop {
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
display: -ms-grid;
|
||||
}
|
||||
|
||||
grid-template-columns: repeat(auto-fit, minmax(320px, $news_width));
|
||||
grid-gap: 40px;
|
||||
grid-auto-rows: minmax(400px, auto);
|
||||
grid-template-rows: auto auto;
|
||||
-ms-grid-columns: $news_width $news_width;
|
||||
}
|
||||
}
|
||||
|
||||
.teaser {
|
||||
margin-bottom: $large-spacing;
|
||||
position: relative;
|
||||
|
||||
&__image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
|
||||
@include desktop {
|
||||
max-width: $news_width;
|
||||
}
|
||||
}
|
||||
|
||||
&__image-source {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
margin-bottom: $large-spacing;
|
||||
}
|
||||
|
||||
&__date {
|
||||
font-family: $sans-serif-font-family;
|
||||
font-weight: $font-weight-regular;
|
||||
color: $color-silver-dark;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -56,6 +56,7 @@
|
|||
cursor: pointer;
|
||||
background-color: $color-white;
|
||||
border: 1px solid $color-silver;
|
||||
z-index: 2;
|
||||
|
||||
&__icon {
|
||||
width: 50px;
|
||||
|
|
|
|||
|
|
@ -90,20 +90,6 @@
|
|||
Logo
|
||||
},
|
||||
|
||||
computed: {
|
||||
topicRoute() {
|
||||
if (this.me.lastTopic && this.me.lastTopic.slug) {
|
||||
return {
|
||||
name: 'topic',
|
||||
params: {
|
||||
topicSlug: this.me.lastTopic.slug
|
||||
}
|
||||
}
|
||||
}
|
||||
return '/book/topic/berufliche-grundbildung'
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
isActive(linkName) {
|
||||
return linkName === 'book' && this.$route.path.indexOf('module') > -1;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
import {withoutOwnerFirst} from '@/helpers/sorting';
|
||||
import BookmarkActions from '@/components/notes/BookmarkActions';
|
||||
import meMixin from '@/mixins/me';
|
||||
|
||||
export default {
|
||||
|
||||
|
|
@ -65,20 +66,15 @@
|
|||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
mixins: [meMixin],
|
||||
|
||||
components: {
|
||||
BookmarkActions,
|
||||
ObjectiveGroups,
|
||||
Chapter
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
me: {
|
||||
permissions: []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
languageCommunicationObjectiveGroups() {
|
||||
return this.module.objectiveGroups ? this.module.objectiveGroups
|
||||
|
|
@ -114,11 +110,26 @@
|
|||
id: moduleId
|
||||
}
|
||||
},
|
||||
update(store, {data: {updateLastModule: {module}}}) {
|
||||
if (module) {
|
||||
update(store, {data: {updateLastModule: {lastModule}}}) {
|
||||
if (lastModule) {
|
||||
const data = store.readQuery({query: ME_QUERY});
|
||||
if (data) {
|
||||
data.me.lastModule = module;
|
||||
data.me.lastModule = lastModule;
|
||||
let recentModules = data.me.recentModules.edges;
|
||||
let newRecentModules;
|
||||
let index = recentModules.findIndex(element => element.node.id === lastModule.id);
|
||||
if (index > -1) {
|
||||
newRecentModules = [...recentModules.slice(0, index), ...recentModules.slice(index + 1)]
|
||||
} else if (recentModules.length >= 3) {
|
||||
newRecentModules = recentModules.slice(0, recentModules.length - 1);
|
||||
} else {
|
||||
newRecentModules = recentModules;
|
||||
}
|
||||
newRecentModules.unshift({
|
||||
__typename: 'ModuleNodeEdge',
|
||||
node: lastModule
|
||||
});
|
||||
data.me.recentModules.edges = newRecentModules;
|
||||
store.writeQuery({query: ME_QUERY, data});
|
||||
}
|
||||
}
|
||||
|
|
@ -199,12 +210,6 @@
|
|||
this.$store.dispatch('editNote', this.module.bookmark.note);
|
||||
},
|
||||
},
|
||||
|
||||
apollo: {
|
||||
me: {
|
||||
query: ME_QUERY,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<template>
|
||||
<router-link
|
||||
:to="moduleLink"
|
||||
:class="['module-teaser', {'module-teaser--small': !teaser}]"
|
||||
tag="div"
|
||||
class="module-teaser">
|
||||
>
|
||||
<div
|
||||
:style="{backgroundImage: 'url('+heroImage+')'}"
|
||||
class="module-teaser__image"/>
|
||||
|
|
@ -46,6 +47,10 @@
|
|||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
|
||||
&--small {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
&__image {
|
||||
width: 100%;
|
||||
max-height: 150px;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div class="news-teaser">
|
||||
<a :href="teaser.newsArticleUrl">
|
||||
<img
|
||||
:src="teaser.imageUrl"
|
||||
class="news-teaser__image">
|
||||
<p class="news-teaser__image-source">
|
||||
<a
|
||||
:href="teaser.imageSource"
|
||||
class="tiny-text">Quelle {{ teaser.imageSource }}</a></p>
|
||||
<h4 class="news-teaser__title">{{ teaser.title }}</h4>
|
||||
<p class="news-teaser__description">{{ teaser.description }}</p>
|
||||
<p class="news-teaser__date">{{ teaser.displayDate }}</p>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
teaser: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_functions.scss";
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
.news-teaser {
|
||||
position: relative;
|
||||
padding-bottom: $large-spacing;
|
||||
|
||||
&__image {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
|
||||
@include desktop {
|
||||
max-width: $news_width;
|
||||
}
|
||||
}
|
||||
|
||||
&__image-source {
|
||||
line-height: 25px;
|
||||
}
|
||||
|
||||
&__description {
|
||||
margin-bottom: $large-spacing;
|
||||
}
|
||||
|
||||
&__date {
|
||||
font-family: $sans-serif-font-family;
|
||||
font-weight: $font-weight-regular;
|
||||
color: $color-silver-dark;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
<template>
|
||||
<div class="news-teasers">
|
||||
<news-teaser
|
||||
:key="teaser.id"
|
||||
:teaser="teaser"
|
||||
class="news-teasers__teaser teaser"
|
||||
v-for="teaser in newsTeasers"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NewsTeaser from '@/components/news/NewsTeaser';
|
||||
|
||||
import news from '@/mixins/news'
|
||||
|
||||
export default {
|
||||
mixins: [news],
|
||||
|
||||
components: {
|
||||
NewsTeaser
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_functions.scss";
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
$image_height: 254px;
|
||||
|
||||
.news-teasers {
|
||||
display: -ms-grid;
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
}
|
||||
margin-bottom: $large-spacing;
|
||||
grid-gap: 40px;
|
||||
|
||||
@include desktop {
|
||||
grid-column-gap: 40px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(320px, $news_width));
|
||||
grid-auto-rows: minmax(400px, auto);
|
||||
grid-template-rows: auto auto;
|
||||
-ms-grid-columns: $news_width $news_width;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#import "./schoolClassParts.gql"
|
||||
#import "./moduleParts.gql"
|
||||
fragment UserParts on UserNode {
|
||||
id
|
||||
pk
|
||||
|
|
@ -19,6 +20,13 @@ fragment UserParts on UserNode {
|
|||
selectedClass {
|
||||
id
|
||||
}
|
||||
recentModules(orderBy: "-visited") {
|
||||
edges {
|
||||
node {
|
||||
...ModuleParts
|
||||
}
|
||||
}
|
||||
}
|
||||
schoolClasses {
|
||||
edges {
|
||||
node {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
#import "../fragments/moduleParts.gql"
|
||||
mutation UpdateLastModule($input: UpdateLastModuleInput!) {
|
||||
updateLastModule(input: $input) {
|
||||
module {
|
||||
lastModule {
|
||||
...ModuleParts
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
<template>
|
||||
<div class="blank-layout">
|
||||
<profile-sidebar/>
|
||||
<navigation-sidebar/>
|
||||
<router-view/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.blank-layout {
|
||||
/*
|
||||
For IE11
|
||||
*/
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ProfileSidebar from '@/components/profile/ProfileSidebar';
|
||||
import NavigationSidebar from '@/components/book-navigation/NavigationSidebar';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ProfileSidebar,
|
||||
NavigationSidebar
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
@ -15,6 +15,20 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
topicRoute() {
|
||||
if (this.me.lastTopic && this.me.lastTopic.slug) {
|
||||
return {
|
||||
name: 'topic',
|
||||
params: {
|
||||
topicSlug: this.me.lastTopic.slug
|
||||
}
|
||||
}
|
||||
}
|
||||
return '/book/topic/berufliche-grundbildung'
|
||||
}
|
||||
},
|
||||
|
||||
apollo: {
|
||||
me: {
|
||||
query: ME_QUERY,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
import NEWS_TEASER_QUERY from '@/graphql/gql/newsTeasersQuery.gql';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
newsTeasers: []
|
||||
};
|
||||
},
|
||||
apollo: {
|
||||
newsTeasers: {
|
||||
query: NEWS_TEASER_QUERY,
|
||||
update(data) {
|
||||
return this.$getRidOfEdges(data).newsTeasers;
|
||||
},
|
||||
client: 'publicClient',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<div class="news">
|
||||
<h1 class="news__heading">News</h1>
|
||||
<NewsTeasers />
|
||||
<news-teasers />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import NewsTeasers from '@/components/NewsTeasers';
|
||||
import NewsTeasers from '@/components/news/NewsTeasers';
|
||||
|
||||
export default {
|
||||
components: {NewsTeasers},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,259 @@
|
|||
<template>
|
||||
<div class="start-page">
|
||||
<header-bar class="start-page__header"/>
|
||||
|
||||
<div class="start-page__sections start-sections">
|
||||
|
||||
<section-block
|
||||
:link-text="moduleText"
|
||||
:route="moduleRoute"
|
||||
class="start-sections__section"
|
||||
title="Inhalte"
|
||||
subtitle="Neues Wissen erwerben"
|
||||
data-cy="current-module-link"
|
||||
>
|
||||
<contents-illustration/>
|
||||
</section-block>
|
||||
<section-block
|
||||
class="start-sections__section"
|
||||
title="Räume"
|
||||
subtitle="Beiträge mit der Klasse teilen"
|
||||
data-cy="rooms-link"
|
||||
link-text="Alle Räume anzeigen"
|
||||
route="/rooms"
|
||||
>
|
||||
<rooms-illustration/>
|
||||
</section-block>
|
||||
<section-block
|
||||
class="start-sections__section"
|
||||
title="Portfolio"
|
||||
subtitle="Projekt dokumentieren und reflektieren"
|
||||
link-text="Portfolio anzeigen"
|
||||
route="/portfolio"
|
||||
>
|
||||
<portfolio-illustration/>
|
||||
</section-block>
|
||||
</div>
|
||||
<div class="start-page__news news">
|
||||
<h2 class="news__title">News</h2>
|
||||
<news-teaser
|
||||
date="27. Mai 2020"
|
||||
title="Lockdown"
|
||||
url="https://myskillbox-abu-news.webflow.io/lockdown"/>
|
||||
<news-teaser
|
||||
date="11. März 2020"
|
||||
title="Brexit"
|
||||
url="https://myskillbox-abu-news.webflow.io/brexit"/>
|
||||
<news-teaser
|
||||
date="20. Dezember 2019"
|
||||
title="Blockchain"
|
||||
url="https://myskillbox-abu-news.webflow.io/blockchain"/>
|
||||
<!--<news-teaser date="31. Oktober 2018" title="Sommerzeit - Festivalzeit"-->
|
||||
<!--url="https://abunews.webflow.io/"></news-teaser>-->
|
||||
<div class="news__more">Mehr...</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import SectionBlock from '@/components/SectionBlock.vue';
|
||||
import NewsTeaser from '@/components/news/NewsTeaserOld.vue';
|
||||
import HeaderBar from '@/components/HeaderBar';
|
||||
|
||||
import ContentsIllustration from '@/components/illustrations/ContentsIllustration';
|
||||
import PortfolioIllustration from '@/components/illustrations/PortfolioIllustration';
|
||||
import RoomsIllustration from '@/components/illustrations/RoomsIllustration';
|
||||
|
||||
import MobileHeader from '@/components/MobileHeader';
|
||||
|
||||
import meMixin from '@/mixins/me';
|
||||
|
||||
export default {
|
||||
|
||||
mixins: [meMixin],
|
||||
components: {
|
||||
MobileHeader,
|
||||
HeaderBar,
|
||||
SectionBlock,
|
||||
NewsTeaser,
|
||||
ContentsIllustration,
|
||||
PortfolioIllustration,
|
||||
RoomsIllustration
|
||||
},
|
||||
|
||||
computed: {
|
||||
moduleRoute() {
|
||||
if (this.me.lastModule && this.me.lastModule.slug) {
|
||||
return `/module/${this.me.lastModule.slug}`;
|
||||
}
|
||||
return '/book/topic/berufliche-grundbildung';
|
||||
},
|
||||
moduleText() {
|
||||
if (this.me.lastModule && this.me.lastModule.slug) {
|
||||
return 'Aktuelles Modul anzeigen';
|
||||
}
|
||||
return 'Alle Inhalte anzeigen'
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@import "@/styles/_variables.scss";
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
.start-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
justify-content: stretch;
|
||||
}
|
||||
grid-template-rows: auto 1fr auto;
|
||||
min-height: 100vh;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
|
||||
&__header {
|
||||
|
||||
}
|
||||
|
||||
&__title {
|
||||
color: $color-brand;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid $color-silver-light;
|
||||
padding-bottom: 30px;
|
||||
margin-left: 30px;
|
||||
margin-right: 30px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
&__my {
|
||||
color: $color-white;
|
||||
/*font-size: 2rem;*/
|
||||
font-weight: 800;
|
||||
-webkit-text-stroke: 1px $color-brand;
|
||||
/*text-shadow: -1px -1px 0 $color-brand,
|
||||
1px -1px 0 $color-brand,
|
||||
-1px 1px 0 $color-brand,
|
||||
1px 1px 0 $color-brand;*/
|
||||
}
|
||||
}
|
||||
|
||||
.start-sections {
|
||||
margin: 0 30px;
|
||||
@include desktop {
|
||||
padding-left: 120px;
|
||||
padding-right: 120px;
|
||||
}
|
||||
display: -ms-grid;
|
||||
-ms-grid-column-align: center;
|
||||
-ms-grid-columns: 1fr 1fr 1fr;
|
||||
margin-bottom: 90px;
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
}
|
||||
@include desktop {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
grid-row-gap: 15px;
|
||||
grid-column-gap: 50px;
|
||||
justify-items: start;
|
||||
align-items: center;
|
||||
|
||||
/*
|
||||
* For IE10+
|
||||
*/
|
||||
& > :nth-child(1) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 1;
|
||||
}
|
||||
|
||||
& > :nth-child(2) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 2;
|
||||
}
|
||||
|
||||
& > :nth-child(3) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.news {
|
||||
background-color: $color-charcoal-dark;
|
||||
color: $color-white;
|
||||
padding-top: $large-spacing;
|
||||
padding-bottom: $large-spacing;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
-ms-grid-columns: 1fr 1fr 1fr;
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
grid-row-gap: $large-spacing;
|
||||
|
||||
@include desktop {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
}
|
||||
|
||||
/*
|
||||
* For IE10+
|
||||
*/
|
||||
& > :nth-child(1) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 1;
|
||||
}
|
||||
|
||||
& > :nth-child(2) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 2;
|
||||
}
|
||||
|
||||
& > :nth-child(3) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 3;
|
||||
}
|
||||
|
||||
& > :nth-child(4) {
|
||||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 4;
|
||||
}
|
||||
|
||||
@include desktop {
|
||||
/*padding-left: 120px;*/
|
||||
/*padding-right: 120px;*/
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-family: $sans-serif-font-family;
|
||||
font-weight: $font-weight-bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 2.1875rem;
|
||||
padding-bottom: 24px;
|
||||
text-align: center;
|
||||
color: inherit;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&__more {
|
||||
color: $color-white;
|
||||
font-family: $sans-serif-font-family;
|
||||
line-height: $default-line-height;
|
||||
padding-left: $medium-spacing;
|
||||
font-weight: $font-weight-bold;
|
||||
text-align: center;
|
||||
|
||||
@include desktop {
|
||||
text-align: left;
|
||||
border-left: 1px solid $color-silver-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,63 +1,55 @@
|
|||
<template>
|
||||
<div class="start-page">
|
||||
<header-bar class="start-page__header"/>
|
||||
<div class="start-page__content">
|
||||
<div
|
||||
class="start-page__modules start-sections"
|
||||
data-cy="start-modules-list">
|
||||
<h2 class="start-page__heading">Letzte Module</h2>
|
||||
<h3
|
||||
class="start-page__no-modules"
|
||||
data-cy="no-modules-yet"
|
||||
v-if="!me.recentModules.length">Sie haben sich noch kein Modul angeschaut. Legen Sie jetzt los!</h3>
|
||||
<div class="start-page__modules-list">
|
||||
<module-teaser
|
||||
:key="index"
|
||||
:meta-title="module.metaTitle"
|
||||
:title="module.title"
|
||||
:hero-image="module.heroImage"
|
||||
:slug="module.slug"
|
||||
data-cy="start-module-teaser"
|
||||
v-for="(module, index) in me.recentModules"/>
|
||||
|
||||
<div class="start-page__sections start-sections">
|
||||
|
||||
<section-block
|
||||
:link-text="moduleText"
|
||||
:route="moduleRoute"
|
||||
class="start-sections__section"
|
||||
title="Inhalte"
|
||||
subtitle="Neues Wissen erwerben"
|
||||
data-cy="current-module-link"
|
||||
>
|
||||
<contents-illustration/>
|
||||
</section-block>
|
||||
<section-block
|
||||
class="start-sections__section"
|
||||
title="Räume"
|
||||
subtitle="Beiträge mit der Klasse teilen"
|
||||
data-cy="rooms-link"
|
||||
link-text="Alle Räume anzeigen"
|
||||
route="/rooms"
|
||||
>
|
||||
<rooms-illustration/>
|
||||
</section-block>
|
||||
<section-block
|
||||
class="start-sections__section"
|
||||
title="Portfolio"
|
||||
subtitle="Projekt dokumentieren und reflektieren"
|
||||
link-text="Portfolio anzeigen"
|
||||
route="/portfolio"
|
||||
>
|
||||
<portfolio-illustration/>
|
||||
</section-block>
|
||||
</div>
|
||||
<router-link
|
||||
:to="topicRoute"
|
||||
tag="div"
|
||||
class="button">Alle Module anzeigen
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="start-page__news news">
|
||||
<h2 class="news__title">News</h2>
|
||||
<h2 class="start-page__heading">News</h2>
|
||||
<div class="news__list">
|
||||
<news-teaser
|
||||
date="27. Mai 2020"
|
||||
title="Lockdown"
|
||||
url="https://myskillbox-abu-news.webflow.io/lockdown"/>
|
||||
<news-teaser
|
||||
date="11. März 2020"
|
||||
title="Brexit"
|
||||
url="https://myskillbox-abu-news.webflow.io/brexit"/>
|
||||
<news-teaser
|
||||
date="20. Dezember 2019"
|
||||
title="Blockchain"
|
||||
url="https://myskillbox-abu-news.webflow.io/blockchain"/>
|
||||
<!--<news-teaser date="31. Oktober 2018" title="Sommerzeit - Festivalzeit"-->
|
||||
<!--url="https://abunews.webflow.io/"></news-teaser>-->
|
||||
<div class="news__more">Mehr...</div>
|
||||
:teaser="teaser"
|
||||
:key="teaser.id"
|
||||
v-for="teaser in teasers"/>
|
||||
</div>
|
||||
|
||||
<router-link
|
||||
:to="{name: 'news'}"
|
||||
class="button">Alle News anzeigen
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import SectionBlock from '@/components/SectionBlock.vue';
|
||||
import NewsTeaser from '@/components/NewsTeaser.vue';
|
||||
import NewsTeaser from '@/components/news/NewsTeaser.vue';
|
||||
import NewsTeasers from '@/components/news/NewsTeasers.vue';
|
||||
import HeaderBar from '@/components/HeaderBar';
|
||||
import ModuleTeaser from '@/components/modules/ModuleTeaser';
|
||||
|
||||
import ContentsIllustration from '@/components/illustrations/ContentsIllustration';
|
||||
import PortfolioIllustration from '@/components/illustrations/PortfolioIllustration';
|
||||
|
|
@ -65,19 +57,23 @@
|
|||
|
||||
import MobileHeader from '@/components/MobileHeader';
|
||||
|
||||
import meMixin from '@/mixins/me';
|
||||
import meQuery from '@/mixins/me';
|
||||
import news from '@/mixins/news';
|
||||
|
||||
export default {
|
||||
|
||||
mixins: [meMixin],
|
||||
mixins: [meQuery, news],
|
||||
|
||||
components: {
|
||||
MobileHeader,
|
||||
HeaderBar,
|
||||
SectionBlock,
|
||||
NewsTeaser,
|
||||
NewsTeasers,
|
||||
ContentsIllustration,
|
||||
PortfolioIllustration,
|
||||
RoomsIllustration
|
||||
RoomsIllustration,
|
||||
ModuleTeaser
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
@ -92,6 +88,9 @@
|
|||
return 'Aktuelles Modul anzeigen';
|
||||
}
|
||||
return 'Alle Inhalte anzeigen'
|
||||
},
|
||||
teasers() {
|
||||
return this.newsTeasers.slice(0, 2);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -109,17 +108,13 @@
|
|||
justify-content: space-between;
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
justify-content: stretch;
|
||||
justify-content: center;
|
||||
}
|
||||
grid-template-rows: auto 1fr auto;
|
||||
min-height: 100vh;
|
||||
width: 100vw;
|
||||
box-sizing: border-box;
|
||||
|
||||
&__header {
|
||||
|
||||
}
|
||||
|
||||
&__title {
|
||||
color: $color-brand;
|
||||
text-align: center;
|
||||
|
|
@ -130,33 +125,43 @@
|
|||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
&__my {
|
||||
color: $color-white;
|
||||
/*font-size: 2rem;*/
|
||||
font-weight: 800;
|
||||
-webkit-text-stroke: 1px $color-brand;
|
||||
/*text-shadow: -1px -1px 0 $color-brand,
|
||||
1px -1px 0 $color-brand,
|
||||
-1px 1px 0 $color-brand,
|
||||
1px 1px 0 $color-brand;*/
|
||||
&__heading {
|
||||
width: 100%;
|
||||
@include meta-title;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding-top: 2*$large-spacing;
|
||||
box-sizing: border-box;
|
||||
max-width: 100%;
|
||||
@include desktop {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.start-sections {
|
||||
margin: 0 30px;
|
||||
@include desktop {
|
||||
padding-left: 120px;
|
||||
padding-right: 120px;
|
||||
&__no-modules {
|
||||
@include heading-3;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&__modules {
|
||||
margin-bottom: $large-spacing;
|
||||
}
|
||||
|
||||
&__modules-list {
|
||||
display: -ms-grid;
|
||||
-ms-grid-column-align: center;
|
||||
-ms-grid-columns: 1fr 1fr 1fr;
|
||||
margin-bottom: 90px;
|
||||
width: 100%;
|
||||
margin-bottom: $large-spacing;
|
||||
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
}
|
||||
@include desktop {
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: max-content;
|
||||
}
|
||||
|
||||
grid-row-gap: 15px;
|
||||
|
|
@ -181,26 +186,28 @@
|
|||
-ms-grid-row: 1;
|
||||
-ms-grid-column: 3;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.news {
|
||||
background-color: $color-charcoal-dark;
|
||||
color: $color-white;
|
||||
padding-top: $large-spacing;
|
||||
padding-bottom: $large-spacing;
|
||||
|
||||
&__list {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
-ms-grid-columns: 1fr 1fr 1fr;
|
||||
|
||||
grid-row-gap: $large-spacing;
|
||||
grid-column-gap: $large-spacing;
|
||||
|
||||
margin-bottom: $large-spacing;
|
||||
|
||||
@supports (display: grid) {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
grid-row-gap: $large-spacing;
|
||||
|
||||
@include desktop {
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
</div>
|
||||
|
||||
<div class="topic__content">
|
||||
<h1 class="topic__title">{{ topic.title }}</h1>
|
||||
<h1
|
||||
data-cy="topic-title"
|
||||
class="topic__title">{{ topic.title }}</h1>
|
||||
<p class="topic__teaser">
|
||||
{{ topic.teaser }}
|
||||
</p>
|
||||
|
|
|
|||
|
|
@ -46,8 +46,7 @@ const routes = [
|
|||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: start,
|
||||
meta: {layout: 'blank'}
|
||||
component: start
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
|
|
|
|||
|
|
@ -77,3 +77,4 @@ $default-heading-line-height: 1.2;
|
|||
$popover-default-bottom: -110px;
|
||||
|
||||
$footer-width: 800px;
|
||||
$news_width: 550px;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# Generated by Django 2.2.12 on 2020-06-23 09:52
|
||||
|
||||
import datetime
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('books', '0021_auto_20200520_0954'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='RecentModule',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('visited', models.DateTimeField(default=datetime.datetime.now)),
|
||||
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='books.Module')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList
|
||||
|
|
@ -58,3 +59,12 @@ class Module(StrictHierarchyPage):
|
|||
|
||||
def get_child_ids(self):
|
||||
return self.get_children().values_list('id', flat=True)
|
||||
|
||||
|
||||
class RecentModule(models.Model):
|
||||
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='recent_modules')
|
||||
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
|
||||
visited = models.DateTimeField(default=datetime.now)
|
||||
|
||||
class Meta:
|
||||
get_latest_by = 'visited'
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from datetime import datetime
|
||||
|
||||
import graphene
|
||||
from graphene import relay
|
||||
|
||||
from api.utils import get_errors, get_object
|
||||
from books.models import Module, Topic
|
||||
from books.models import Module, Topic, RecentModule
|
||||
from books.schema.queries import ModuleNode, TopicNode
|
||||
|
||||
|
||||
|
|
@ -47,12 +49,10 @@ class UpdateLastModule(relay.ClientIDMutation):
|
|||
# todo: use slug here too
|
||||
id = graphene.ID()
|
||||
|
||||
module = graphene.Field(ModuleNode)
|
||||
errors = graphene.List(graphene.String)
|
||||
last_module = graphene.Field(ModuleNode)
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, root, info, **args):
|
||||
try:
|
||||
user = info.context.user
|
||||
id = args.get('id')
|
||||
|
||||
|
|
@ -60,17 +60,19 @@ class UpdateLastModule(relay.ClientIDMutation):
|
|||
if not module:
|
||||
raise Module.DoesNotExist
|
||||
|
||||
user.last_module = module
|
||||
user.save()
|
||||
try:
|
||||
same_module = RecentModule.objects.get(user=user, module=module)
|
||||
same_module.visited = datetime.now()
|
||||
same_module.save()
|
||||
return cls(last_module=same_module.module)
|
||||
except RecentModule.DoesNotExist:
|
||||
recent_modules = RecentModule.objects.filter(user=user)
|
||||
while recent_modules.all().count() >= 3:
|
||||
recent_modules.earliest().delete()
|
||||
|
||||
return cls(module=module)
|
||||
last_module = RecentModule.objects.create(user=user, module=module)
|
||||
|
||||
except Module.DoesNotExist:
|
||||
return cls(errors=['Module not found'])
|
||||
|
||||
except Exception as e:
|
||||
errors = ['Error: {}'.format(e)]
|
||||
return cls(errors=errors)
|
||||
return cls(last_module=last_module.module)
|
||||
|
||||
|
||||
class UpdateLastTopic(relay.ClientIDMutation):
|
||||
|
|
@ -93,4 +95,3 @@ class UpdateLastTopic(relay.ClientIDMutation):
|
|||
user.save()
|
||||
|
||||
return cls(topic=topic)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ from notes.schema import ContentBlockBookmarkNode, ChapterBookmarkNode, ModuleBo
|
|||
from rooms.models import ModuleRoomSlug
|
||||
from surveys.models import Answer
|
||||
from surveys.schema import AnswerNode
|
||||
from ..models import Book, Topic, Module, Chapter, ContentBlock
|
||||
from ..models import Book, Topic, Module, Chapter, ContentBlock, RecentModule
|
||||
|
||||
|
||||
def process_module_room_slug_block(content):
|
||||
|
|
@ -187,6 +187,12 @@ class ModuleNode(DjangoObjectType):
|
|||
.prefetch_related('objectives__objective_progress')
|
||||
|
||||
|
||||
class RecentModuleNode(DjangoObjectType):
|
||||
class Meta:
|
||||
model = RecentModule
|
||||
interfaces = (relay.Node,)
|
||||
|
||||
|
||||
class TopicNode(DjangoObjectType):
|
||||
pk = graphene.Int()
|
||||
modules = DjangoFilterConnectionField(ModuleNode)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
from django.test import TestCase, RequestFactory
|
||||
from graphene.test import Client
|
||||
from graphql_relay import to_global_id
|
||||
|
||||
from api.schema import schema
|
||||
from api.utils import get_object
|
||||
from books.models import ContentBlock, Chapter
|
||||
from books.factories import ModuleFactory, BookFactory
|
||||
from core.factories import UserFactory
|
||||
from users.services import create_users
|
||||
|
||||
|
||||
class RecentModulesTest(TestCase):
|
||||
def setUp(self):
|
||||
create_users()
|
||||
_, topic, self.module1, chapter, _ = BookFactory.create_default_structure()
|
||||
|
||||
self.modules = []
|
||||
for i in range(1, 5):
|
||||
module = ModuleFactory.create(parent=topic,
|
||||
title=f"Another module {i}",
|
||||
meta_title=f"Modul {i}",
|
||||
teaser="Whatever",
|
||||
intro="<p>Hello</p>")
|
||||
self.modules.append(module)
|
||||
|
||||
user = UserFactory(username='aschi')
|
||||
|
||||
request = RequestFactory().get('/')
|
||||
request.user = user
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
def _update_last_module(self, module):
|
||||
mutation = """
|
||||
mutation UpdateLastModule($input: UpdateLastModuleInput!) {
|
||||
updateLastModule(input: $input) {
|
||||
lastModule {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
result = self.client.execute(mutation, variables={
|
||||
'input': {
|
||||
'id': to_global_id('ModuleNode', module.id)
|
||||
}
|
||||
})
|
||||
self.assertIsNone(result.get('errors'))
|
||||
|
||||
def _get_recent_modules(self):
|
||||
recent_modules_query = """
|
||||
query RecentModulesQuery {
|
||||
me {
|
||||
recentModules(orderBy: "-visited") {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
return list(map(lambda x: x['node'], self.client.execute(recent_modules_query).get('data').get('me').get('recentModules').get('edges')))
|
||||
|
||||
def test_no_recent_modules(self):
|
||||
edges = self._get_recent_modules()
|
||||
|
||||
self.assertEqual(len(edges), 0)
|
||||
|
||||
def test_update_last_module(self):
|
||||
self._update_last_module(self.module1)
|
||||
|
||||
def test_recent_modules(self):
|
||||
module1, module2, module3, module4 = self.modules
|
||||
|
||||
self._update_last_module(module1)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 1)
|
||||
self.assertEqual(recent_modules[0].get('title'), module1.title)
|
||||
|
||||
# same module twice
|
||||
self._update_last_module(module1)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 1)
|
||||
|
||||
self._update_last_module(module2)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 2)
|
||||
self.assertEqual(recent_modules[0].get('title'), module2.title)
|
||||
self.assertEqual(recent_modules[1].get('title'), module1.title)
|
||||
|
||||
# same module as before again
|
||||
self._update_last_module(module1)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 2)
|
||||
self.assertEqual(recent_modules[0].get('title'), module1.title)
|
||||
self.assertEqual(recent_modules[1].get('title'), module2.title)
|
||||
|
||||
|
||||
self._update_last_module(module3)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 3)
|
||||
self.assertEqual(recent_modules[0].get('title'), module3.title)
|
||||
self.assertEqual(recent_modules[1].get('title'), module1.title)
|
||||
self.assertEqual(recent_modules[2].get('title'), module2.title)
|
||||
|
||||
self._update_last_module(module4)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 3)
|
||||
self.assertEqual(recent_modules[0].get('title'), module4.title)
|
||||
self.assertEqual(recent_modules[1].get('title'), module3.title)
|
||||
self.assertEqual(recent_modules[2].get('title'), module1.title)
|
||||
|
||||
# same again
|
||||
self._update_last_module(module4)
|
||||
recent_modules = self._get_recent_modules()
|
||||
self.assertEqual(len(recent_modules), 3)
|
||||
self.assertEqual(recent_modules[0].get('title'), module4.title)
|
||||
self.assertEqual(recent_modules[1].get('title'), module3.title)
|
||||
self.assertEqual(recent_modules[2].get('title'), module1.title)
|
||||
|
||||
|
||||
|
|
@ -1,15 +1,6 @@
|
|||
from .settings import *
|
||||
|
||||
|
||||
class DisableMigrations(object):
|
||||
def __contains__(self, item):
|
||||
return True
|
||||
|
||||
def __getitem__(self, item):
|
||||
return None
|
||||
|
||||
|
||||
MIGRATION_MODULES = DisableMigrations()
|
||||
MIGRATION_MODULES = {}
|
||||
|
||||
# Email Settings
|
||||
SENDGRID_API_KEY = ""
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
set -e
|
||||
|
||||
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
python -m coverage run manage.py test $1
|
||||
python -m coverage run manage.py test --settings=core.settings_test $1
|
||||
|
||||
coverage_python=`coverage report -m | tail -n1 | awk '{print $4}'`
|
||||
commit=`git rev-parse HEAD`
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.2.12 on 2020-06-23 09:52
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('books', '0022_recentmodule'),
|
||||
('users', '0019_userdata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='user',
|
||||
name='recent_modules',
|
||||
field=models.ManyToManyField(related_name='_user_recent_modules_+', through='books.RecentModule', to='books.Module'),
|
||||
),
|
||||
]
|
||||
|
|
@ -17,6 +17,7 @@ DEFAULT_SCHOOL_ID = 1
|
|||
|
||||
class User(AbstractUser):
|
||||
last_module = models.ForeignKey('books.Module', related_name='+', on_delete=models.SET_NULL, null=True)
|
||||
recent_modules = models.ManyToManyField('books.Module', related_name='+', through='books.RecentModule')
|
||||
last_topic = models.ForeignKey('books.Topic', related_name='+', on_delete=models.SET_NULL, null=True)
|
||||
avatar_url = models.CharField(max_length=254, blank=True, default='')
|
||||
email = models.EmailField(_('email address'), unique=True)
|
||||
|
|
@ -97,7 +98,6 @@ class User(AbstractUser):
|
|||
user_settings.selected_class = school_class
|
||||
user_settings.save()
|
||||
|
||||
|
||||
@property
|
||||
def full_name(self):
|
||||
return self.get_full_name()
|
||||
|
|
@ -255,7 +255,8 @@ class License(models.Model):
|
|||
return self.for_role.key == RoleManager.TEACHER_KEY
|
||||
|
||||
def is_valid(self):
|
||||
return HepClient.is_product_active(datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
|
||||
return HepClient.is_product_active(
|
||||
datetime(self.expire_date.year, self.expire_date.month, self.expire_date.day),
|
||||
self.for_role.key)
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -266,4 +267,3 @@ class SchoolClassMember(models.Model):
|
|||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
school_class = models.ForeignKey(SchoolClass, on_delete=models.CASCADE)
|
||||
active = models.BooleanField(default=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from datetime import datetime
|
|||
|
||||
import graphene
|
||||
from django.db.models import Q
|
||||
from django_filters import FilterSet, OrderingFilter
|
||||
from graphene import relay, ObjectType
|
||||
from graphene_django import DjangoObjectType
|
||||
from graphene_django.filter import DjangoFilterConnectionField
|
||||
|
|
@ -10,7 +11,7 @@ from graphql_relay import to_global_id
|
|||
|
||||
from basicknowledge.models import BasicKnowledge
|
||||
from basicknowledge.queries import InstrumentNode
|
||||
from books.models import Module
|
||||
from books.models import Module, RecentModule
|
||||
from books.schema.queries import ModuleNode
|
||||
from users.models import User, SchoolClass, SchoolClassMember
|
||||
|
||||
|
|
@ -39,6 +40,18 @@ class SchoolClassNode(DjangoObjectType):
|
|||
return self.code
|
||||
|
||||
|
||||
class RecentModuleFilter(FilterSet):
|
||||
class Meta:
|
||||
model = Module
|
||||
fields = ('recent_modules',)
|
||||
|
||||
order_by = OrderingFilter(
|
||||
fields=(
|
||||
('recent_modules__visited', 'visited'),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class UserNode(DjangoObjectType):
|
||||
pk = graphene.Int()
|
||||
permissions = graphene.List(graphene.String)
|
||||
|
|
@ -46,6 +59,7 @@ class UserNode(DjangoObjectType):
|
|||
expiry_date = graphene.String()
|
||||
is_teacher = graphene.Boolean()
|
||||
old_classes = DjangoFilterConnectionField(SchoolClassNode)
|
||||
recent_modules = DjangoFilterConnectionField(ModuleNode, filterset_class=RecentModuleFilter)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
|
@ -82,6 +96,10 @@ class UserNode(DjangoObjectType):
|
|||
def resolve_old_classes(self, info):
|
||||
return SchoolClass.objects.filter(schoolclassmember__active=False, schoolclassmember__user=self)
|
||||
|
||||
def resolve_recent_modules(self, info, **kwargs):
|
||||
# see https://docs.graphene-python.org/projects/django/en/latest/filtering/
|
||||
return RecentModuleFilter(kwargs).qs.filter(recent_modules__user=self)
|
||||
|
||||
|
||||
class ClassMemberNode(ObjectType):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue