From 02290e968c923e8b6d17c5a5f1eb6bf1ee348b25 Mon Sep 17 00:00:00 2001 From: Vivek Santayana Date: Wed, 17 Aug 2022 16:32:58 +0100 Subject: [PATCH] Added question viewer functionality Added view questions panel to editor interface Added view questions section of web site Added links to navbars --- nginx/conf.d/ref-test-app.conf | 7 + ref-test/app/__init__.py | 2 + .../templates/admin/components/navbar.html | 7 +- .../templates/admin/settings/questions.html | 23 +- ref-test/app/editor/static/css/editor.css | 18 +- ref-test/app/editor/static/js/editor.js | 163 ++++++++++- .../templates/editor/components/navbar.html | 7 +- .../app/editor/templates/editor/console.html | 11 +- ref-test/app/view/__init__.py | 0 ref-test/app/view/static/css/style.css | 260 ++++++++++++++++++ ref-test/app/view/static/css/view.css | 30 ++ .../app/view/static/js/jquery-3.6.0.min.js | 2 + ref-test/app/view/static/js/script.js | 115 ++++++++ ref-test/app/view/static/js/view.js | 130 +++++++++ .../view/templates/view/components/base.html | 84 ++++++ .../view/components/client-alerts.html | 1 + .../templates/view/components/datatable.html | 28 ++ .../templates/view/components/footer.html | 2 + .../view/components/input-forms.html | 4 + .../templates/view/components/navbar.html | 117 ++++++++ .../templates/view/components/og-meta.html | 18 ++ .../view/components/secondary-navs/tests.html | 23 ++ .../view/components/server-alerts.html | 43 +++ ref-test/app/view/templates/view/console.html | 116 ++++++++ ref-test/app/view/templates/view/index.html | 27 ++ ref-test/app/view/views.py | 41 +++ 26 files changed, 1253 insertions(+), 26 deletions(-) create mode 100644 ref-test/app/view/__init__.py create mode 100644 ref-test/app/view/static/css/style.css create mode 100644 ref-test/app/view/static/css/view.css create mode 100644 ref-test/app/view/static/js/jquery-3.6.0.min.js create mode 100644 ref-test/app/view/static/js/script.js create mode 100644 ref-test/app/view/static/js/view.js create mode 100644 ref-test/app/view/templates/view/components/base.html create mode 100644 ref-test/app/view/templates/view/components/client-alerts.html create mode 100644 ref-test/app/view/templates/view/components/datatable.html create mode 100644 ref-test/app/view/templates/view/components/footer.html create mode 100644 ref-test/app/view/templates/view/components/input-forms.html create mode 100644 ref-test/app/view/templates/view/components/navbar.html create mode 100644 ref-test/app/view/templates/view/components/og-meta.html create mode 100644 ref-test/app/view/templates/view/components/secondary-navs/tests.html create mode 100644 ref-test/app/view/templates/view/components/server-alerts.html create mode 100644 ref-test/app/view/templates/view/console.html create mode 100644 ref-test/app/view/templates/view/index.html create mode 100644 ref-test/app/view/views.py diff --git a/nginx/conf.d/ref-test-app.conf b/nginx/conf.d/ref-test-app.conf index 36c1247..24c2694 100644 --- a/nginx/conf.d/ref-test-app.conf +++ b/nginx/conf.d/ref-test-app.conf @@ -19,6 +19,7 @@ server { include /etc/nginx/ssl.conf; include /etc/nginx/certbot-challenge.conf; + # Define locations for static files to be served by Nginx location ^~ /quiz/static/ { include /etc/nginx/mime.types; alias /usr/share/nginx/html/quiz/static/; @@ -34,6 +35,12 @@ server { alias /usr/share/nginx/html/admin/editor/static/; } + location ^~ /admin/view/static/ { + include /etc/nginx/mime.types; + alias /usr/share/nginx/html/admin/view/static/; + } + + # Proxy to the main app for all other requests location / { include /etc/nginx/conf.d/proxy_headers.conf; proxy_pass http://reftest; diff --git a/ref-test/app/__init__.py b/ref-test/app/__init__.py index 4122f2c..66dfc25 100644 --- a/ref-test/app/__init__.py +++ b/ref-test/app/__init__.py @@ -46,11 +46,13 @@ def create_app(): from .quiz.views import quiz from .views import views from .editor.views import editor + from .view.views import view app.register_blueprint(admin, url_prefix='/admin') app.register_blueprint(api, url_prefix='/api') app.register_blueprint(views) app.register_blueprint(quiz) app.register_blueprint(editor, url_prefix='/admin/editor') + app.register_blueprint(view, url_prefix='/admin/view') return app \ No newline at end of file diff --git a/ref-test/app/admin/templates/admin/components/navbar.html b/ref-test/app/admin/templates/admin/components/navbar.html index 48686d4..4dbe334 100644 --- a/ref-test/app/admin/templates/admin/components/navbar.html +++ b/ref-test/app/admin/templates/admin/components/navbar.html @@ -77,10 +77,13 @@ Users
  • - Question Datasets + Manage Questions
  • - Question Editor + View Questions +
  • +
  • + Edit Questions
  • diff --git a/ref-test/app/admin/templates/admin/settings/questions.html b/ref-test/app/admin/templates/admin/settings/questions.html index eed4611..d9e941a 100644 --- a/ref-test/app/admin/templates/admin/settings/questions.html +++ b/ref-test/app/admin/templates/admin/settings/questions.html @@ -57,28 +57,37 @@ class="btn btn-primary edit-question-dataset" data-id="{{ element.id }}" data-action="download" - title="Download Dataset" + title="Download Questions" > - + + + + - - + + - + {% endfor %} diff --git a/ref-test/app/editor/static/css/editor.css b/ref-test/app/editor/static/css/editor.css index 84544fd..133e762 100644 --- a/ref-test/app/editor/static/css/editor.css +++ b/ref-test/app/editor/static/css/editor.css @@ -71,7 +71,7 @@ margin: 30pt auto; } -.info-panel { +.info-panel, .viewer-panel { display: none; } @@ -84,4 +84,20 @@ #alert-box { margin: 30px auto; max-width: 460px; +} + +.block { + border: 2px solid black; + border-radius: 10px; + margin: 10px; + padding: 5px; +} + +.question-body, .question-block { + padding: 0px 2em; +} + +blockquote { + padding: 0px 2em; + font-style: italic; } \ No newline at end of file diff --git a/ref-test/app/editor/static/js/editor.js b/ref-test/app/editor/static/js/editor.js index 85e9fd1..f7eb64e 100644 --- a/ref-test/app/editor/static/js/editor.js +++ b/ref-test/app/editor/static/js/editor.js @@ -5,24 +5,69 @@ const id = $root.data('id') const $control_panel = $('.control-panel') const $info_panel = $('.info-panel') +const $viewer_panel = $('.viewer-panel') const $editor_panel = $('.editor-panel') +var toggle_info = false +var toggle_viewer = false + var element_index = 0 // Initialise Sortable and trigger renumbering on end of drag Sortable.create($root.get(0), {handle: '.move-handle', onEnd: function(evt) {renumber_blocks()}}) -// Info Button Listener +// Info and Viewer Button Listener $control_panel.find('button').click(function(event){ - if ($info_panel.is(":hidden")) { - $editor_panel.hide() - $info_panel.fadeIn() - $(this).addClass('active') - } else { - $info_panel.hide() - $editor_panel.fadeIn() - $(this).removeClass('active') + var action = $(this).data('action'); + + if (action == 'info') { + if ($info_panel.is(":hidden")) { + if ($viewer_panel.is(":visible")) { + toggle_viewer = true + $viewer_panel.hide() + } + $editor_panel.hide() + $info_panel.fadeIn() + $(window).scrollTop(0) + toggle_info = false + $(this).addClass('active') + } else { + $info_panel.hide() + if (toggle_viewer) { + render_viewer() + $(window).scrollTop(0) + toggle_viewer = false + } else { + $editor_panel.fadeIn() + $(window).scrollTop(0) + } + $(this).removeClass('active') + } + } else if (action == 'view') { + if ($viewer_panel.is(":hidden")) { + if ($info_panel.is(':visible')) { + toggle_info = true + $info_panel.hide() + } + $editor_panel.hide() + render_viewer() + $(window).scrollTop(0) + toggle_viewer = false + $(this).addClass('active') + } else { + $viewer_panel.hide() + if (toggle_info) { + $info_panel.fadeIn() + $(window).scrollTop(0) + toggle_info = false + } else { + $editor_panel.fadeIn() + $(window).scrollTop(0) + } + $(this).removeClass('active') + } } + event.preventDefault() }) @@ -496,4 +541,102 @@ $(window).on('load', function() { console.log(response) } }) -}) \ No newline at end of file +}) + +// Viewer Render Function +function render_viewer() { + $viewer_panel.fadeIn() + $viewer_panel.empty() + var heading = document.createElement('h3') + heading.innerText = 'View Questions' + $viewer_panel.append(heading) + var data = parse_input() + var block + var obj + for (let i = 0; i < data.length; i++) { + block = data[i] + obj = document.createElement('div') + obj.classList = 'block' + if (block['type'] == 'question') { + text = document.createElement('p') + text.innerHTML = `Question ${block['q_no'] + 1}. ${block['text']}` + obj.append(text) + question_body = document.createElement('div') + question_body.className ='question-body' + type = document.createElement('p') + type.innerHTML = `Question Type: ${block['q_type']}` + question_body.append(type) + options = document.createElement('p') + options.innerHTML = 'Options:' + option_list = document.createElement('ul') + for (let _i = 0; _i < block['options'].length; _i++) { + option = document.createElement('li') + option.innerHTML = block['options'][_i] + if (block['correct'] == _i) { + option.innerHTML += ' Correct' + } + option_list.append(option) + } + options.append(option_list) + question_body.append(options) + tags = document.createElement('p') + tags.innerHTML = `Tags:` + tag_list = document.createElement('ul') + for (let _i = 0; _i < block['tags'].length; _i++) { + tag = document.createElement('li') + tag.innerHTML = block['tags'][_i] + tag_list.append(tag) + } + tags.append(tag_list) + question_body.append(tags) + obj.append(question_body) + } else if (block['type'] == 'block') { + meta = document.createElement('p') + meta.innerHTML = `Block ${i+1}. ${block['questions'].length} questions.` + obj.append(meta) + header = document.createElement('blockquote') + header.innerText = block['question_header'] + obj.append(header) + var block_question = document.createElement('div') + var question + block_question.className = 'question-block' + for (let _i = 0; _i < block['questions'].length; _i++) { + question = block['questions'][_i] + text = document.createElement('p') + text.innerHTML = `Question ${question['q_no'] + 1}. ${question['text']}` + block_question.append(text) + question_body = document.createElement('div') + question_body.className ='question-body' + type = document.createElement('p') + type.innerHTML = `Question Type: ${question['q_type']}` + question_body.append(type) + options = document.createElement('p') + options.innerHTML = 'Options:' + option_list = document.createElement('ul') + for (let __i = 0; __i < question['options'].length; __i++) { + option = document.createElement('li') + option.innerHTML = question['options'][__i] + if (question['correct'] == __i) { + option.innerHTML += ' Correct' + } + option_list.append(option) + } + options.append(option_list) + question_body.append(options) + tags = document.createElement('p') + tags.innerHTML = `Tags:` + tag_list = document.createElement('ul') + for (let __i = 0; __i < question['tags'].length; __i++) { + tag = document.createElement('li') + tag.innerHTML = question['tags'][__i] + tag_list.append(tag) + } + tags.append(tag_list) + question_body.append(tags) + block_question.append(question_body) + obj.append(block_question) + } + } + $viewer_panel.append(obj) + } +} \ No newline at end of file diff --git a/ref-test/app/editor/templates/editor/components/navbar.html b/ref-test/app/editor/templates/editor/components/navbar.html index 48686d4..4dbe334 100644 --- a/ref-test/app/editor/templates/editor/components/navbar.html +++ b/ref-test/app/editor/templates/editor/components/navbar.html @@ -77,10 +77,13 @@ Users
  • - Question Datasets + Manage Questions
  • - Question Editor + View Questions +
  • +
  • + Edit Questions
  • diff --git a/ref-test/app/editor/templates/editor/console.html b/ref-test/app/editor/templates/editor/console.html index b532cf5..e244e73 100644 --- a/ref-test/app/editor/templates/editor/console.html +++ b/ref-test/app/editor/templates/editor/console.html @@ -11,11 +11,12 @@

    Editor

    - Use this console to edit the questions in this dataset. For more information on using the editor console, click on the the blue information button. + Use this console to edit the questions in this dataset. For more information on using the editor console, click on the the blue Information button. To preview the questions in the current dataset, click on the green View Questions button.

    - + +

    @@ -77,9 +78,11 @@ In order to show how many questions are remaining inside a block, e.g. to say ‘the next n questions are about a specific scenario’, use the placeholder <block_remaining_questions>.

    +
    +

    - Edit Dataset + Edit Questions