diff --git a/Gemfile b/Gemfile index d24e6e02c..40e321295 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,7 @@ gem "rails", "~> 7.0.4.3" # Use dalli for caching to memcached in production gem "dalli", ">= 2.7" # Ruby wrapper for UglifyJS JavaScript compressor -gem "uglifier" +gem "terser" # Use nulldb adapter for assets precompilation in production gem "activerecord-nulldb-adapter" # Use sqlite3 as the database for Active Record @@ -60,7 +60,7 @@ gem "cancancan" gem "jquery-rails" gem "jquery-ui-rails" gem "js-routes", '1.4.9' -gem "bootstrap", "~>4" +gem "bootstrap", "~>5" gem "bootstrap_form" gem "devise-bootstrap-views" gem "fuzzy-string-match" diff --git a/Gemfile.lock b/Gemfile.lock index 5f8fb5465..52c30e913 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -152,9 +152,9 @@ GEM bindex (0.8.1) bootsnap (1.16.0) msgpack (~> 1.2) - bootstrap (4.6.2) + bootstrap (5.2.1) autoprefixer-rails (>= 9.1.0) - popper_js (>= 1.16.1, < 2) + popper_js (>= 2.11.6, < 3) sassc-rails (>= 2.0.0) bootstrap_form (5.1.0) actionpack (>= 5.2) @@ -389,7 +389,7 @@ GEM ttfunk pg (1.4.6) pgreset (0.3) - popper_js (1.16.1) + popper_js (2.11.6) pr_geohash (1.0.0) premailer (1.21.0) addressable @@ -591,6 +591,8 @@ GEM sync (0.5.0) term-ansicolor (1.7.1) tins (~> 1.0) + terser (1.1.14) + execjs (>= 0.3.0, < 3) thor (1.2.1) thredded (1.1.0) active_record_union (>= 1.3.0) @@ -626,8 +628,6 @@ GEM turbolinks-source (5.2.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - uglifier (4.2.0) - execjs (>= 0.3.0, < 3) unf (0.1.4) unf_ext unf_ext (0.0.8.2) @@ -668,7 +668,7 @@ DEPENDENCIES acts_as_votable barby bootsnap (>= 1.4.2) - bootstrap (~> 4) + bootstrap (~> 5) bootstrap_form byebug cancancan @@ -739,11 +739,11 @@ DEPENDENCIES streamio-ffmpeg sunspot_rails! sunspot_solr - thredded + terser + thredded! thredded-markdown_katex! trix-rails turbolinks (~> 5) - uglifier web-console (>= 3.3.0) webdrivers webpacker (~> 5.x) diff --git a/app/assets/javascripts/_selectize_turbolinks_fix.js b/app/assets/javascripts/_selectize_turbolinks_fix.js index 9c4939071..eaef1d817 100644 --- a/app/assets/javascripts/_selectize_turbolinks_fix.js +++ b/app/assets/javascripts/_selectize_turbolinks_fix.js @@ -84,28 +84,6 @@ this.fillOptionsByAjax = function($selectizedSelection) { maxOptions: null, placeholder: placeholder, closeAfterSelect: true, - dropdownParent: parent, - onInitialize:function(){ - this.popper = Popper.createPopper(this.control,this.dropdown, { - placement: "bottom-start", - modifiers: [ - { - name: "sameWidth", - enabled: true, - fn: ({ state }) => { - state.styles.popper.width = `${state.rects.reference.width}px`; - }, - phase: "beforeWrite", - requires: ["computeStyles"], - } - ] - - }); - - }, - onDropdownOpen:function(){ - this.popper.update(); - }, load: function(query, callback) { var url; if (send_data || !loaded) { diff --git a/app/assets/javascripts/bootstrap_modal_turbolinks_fix.coffee b/app/assets/javascripts/bootstrap_modal_turbolinks_fix.coffee index 252e62ad7..6df7fdc78 100644 --- a/app/assets/javascripts/bootstrap_modal_turbolinks_fix.coffee +++ b/app/assets/javascripts/bootstrap_modal_turbolinks_fix.coffee @@ -7,6 +7,11 @@ $(document).on 'turbolinks:load', -> $('.activeModal').modal('show') # remove active status (this needs to be reestablished before caching) $('.activeModal').removeClass('activeModal') + + popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')) + popoverList = popoverTriggerList.map (popoverTriggerEl) -> + return new bootstrap.Popover(popoverTriggerEl) + return $(document).on 'turbolinks:before-cache', -> diff --git a/app/assets/javascripts/lectures.coffee b/app/assets/javascripts/lectures.coffee index 7fe308c6e..721bd0222 100644 --- a/app/assets/javascripts/lectures.coffee +++ b/app/assets/javascripts/lectures.coffee @@ -6,13 +6,13 @@ disableExceptOrganizational = -> $('#lecture-organizational-warning').show() $('.fa-edit').hide() $('.new-in-lecture').hide() - $('[data-toggle="collapse"]').prop('disabled', true).removeClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', true).removeClass('clickable') return $(document).on 'turbolinks:load', -> # activate all popovers - $('[data-toggle="popover"]').popover() + $('[data-bs-toggle="popover"]').popover() # if any input is given to the lecture form (for people in lecture), # disable other input @@ -20,13 +20,13 @@ $(document).on 'turbolinks:load', -> $('#lecture-basics-warning').show() $('.fa-edit:not(#update-teacher-button,#update-editors-button)').hide() $('.new-in-lecture').hide() - $('[data-toggle="collapse"]').prop('disabled', true).removeClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', true).removeClass('clickable') return # if any input is given to the preferences form, disable other input $('#lecture-preferences-form :input').on 'change', -> $('#lecture-preferences-warning').show() - $('[data-toggle="collapse"]').prop('disabled', true).removeClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', true).removeClass('clickable') $('.fa-edit').hide() $('.new-in-lecture').hide() return @@ -34,7 +34,7 @@ $(document).on 'turbolinks:load', -> # if any input is given to the comments form, disable other input $('#lecture-comments-form :input').on 'change', -> $('#lecture-comments-warning').show() - $('[data-toggle="collapse"]').prop('disabled', true).removeClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', true).removeClass('clickable') $('.fa-edit').hide() $('.new-in-lecture').hide() return @@ -42,7 +42,7 @@ $(document).on 'turbolinks:load', -> # if any input is given to the assignments form, disable other input $('#lecture-assignments-form :input').on 'change', -> $('#lecture-assignments-warning').show() - $('[data-toggle="collapse"]').prop('disabled', true).removeClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', true).removeClass('clickable') $('.new-in-lecture').hide() return @@ -90,7 +90,7 @@ $(document).on 'turbolinks:load', -> # restore assignments form if lecture assignments editing is cancelled $('#cancel-lecture-assignments').on 'click', -> $('#lecture-assignments-warning').hide() - $('[data-toggle="collapse"]').prop('disabled', false).addClass('clickable') + $('[data-bs-toggle="collapse"]').prop('disabled', false).addClass('clickable') $('.new-in-lecture').show() maxSize = $('#lecture_submission_max_team_size').data('value') $('#lecture_submission_max_team_size').val(maxSize) @@ -117,59 +117,57 @@ $(document).on 'turbolinks:load', -> if this.dataset.type == 'Lesson' lessonId = this.dataset.id $('.lecture-lesson[data-id="'+lessonId+'"]') - .removeClass('badge-secondary') - .addClass('badge-info') + .removeClass('bg-secondary') + .addClass('bg-info') tags = $(this).data('tags') for t in tags - $('.lecture-tag[data-id="'+t+'"]').removeClass('badge-light') - .addClass('badge-warning') + $('.lecture-tag[data-id="'+t+'"]').removeClass('bg-light') + .addClass('bg-warning') return # mouseleave over lesson -> restore original color of lessons and tags $('[id^="lecture-medium_"]').on 'mouseleave', -> if this.dataset.type == 'Lesson' lessonId = this.dataset.id - $('.lecture-lesson[data-id="'+lessonId+'"]').removeClass('badge-info') - .addClass('badge-secondary') + $('.lecture-lesson[data-id="'+lessonId+'"]').removeClass('bg-info') + .addClass('bg-secondary') tags = $(this).data('tags') for t in tags - $('.lecture-tag[data-id="'+t+'"]').removeClass('badge-warning') - .addClass('badge-light') + $('.lecture-tag[data-id="'+t+'"]').removeClass('bg-warning') + .addClass('bg-light') return # mouseenter over lesson -> colorize tags $('[id^="lecture-lesson_"]').on 'mouseenter', -> tags = $(this).data('tags') for t in tags - $('.lecture-tag[data-id="'+t+'"]').removeClass('badge-light') - .addClass('badge-warning') + $('.lecture-tag[data-id="'+t+'"]').addClass('bg-warning') return # mouseleave over lesson -> restore original color of tags $('[id^="lecture-lesson_"]').on 'mouseleave', -> tags = $(this).data('tags') for t in tags - $('.lecture-tag[data-id="'+t+'"]').removeClass('badge-warning') - .addClass('badge-light') + $('.lecture-tag[data-id="'+t+'"]').removeClass('bg-warning') return # mouseenter over tag -> colorize lessons $('[id^="lecture-tag_"]').on 'mouseenter', -> lessons = $(this).data('lessons') for l in lessons - $('.lecture-lesson[data-id="'+l+'"]').removeClass('badge-secondary') - .addClass('badge-info') + $('.lecture-lesson[data-id="'+l+'"]').removeClass('bg-secondary') + .addClass('bg-info') return # mouseleave over tag -> restore original color of lessons $('[id^="lecture-tag_"]').on 'mouseleave', -> lessons = $(this).data('lessons') for l in lessons - $('.lecture-lesson[data-id="'+l+'"]').removeClass('badge-info') - .addClass('badge-secondary') + $('.lecture-lesson[data-id="'+l+'"]').removeClass('bg-info') + .addClass('bg-secondary') return - $('#edited-media-tab a[data-toggle="tab"]').on 'shown.bs.tab', (e) -> + $('#edited-media-tab a[data-bs-toggle="tab"]').on 'shown.bs.tab', (e) -> sort = e.target.dataset.sort # newly activated tab path = $('#create-new-medium').prop('href') if path @@ -345,7 +343,7 @@ $(document).on 'turbolinks:load', -> # clean up everything before turbolinks caches $(document).on 'turbolinks:before-cache', -> - $('.lecture-tag').removeClass('badge-warning').addClass('badge-light') - $('.lecture-lesson').removeClass('badge-info').addClass('badge-secondary') + $('.lecture-tag').removeClass('bg-warning') + $('.lecture-lesson').removeClass('bg-info').addClass('bg-secondary') $(document).off 'change', '#lecture_course_id' return diff --git a/app/assets/javascripts/lessons.coffee b/app/assets/javascripts/lessons.coffee index 9d23bcd59..dedacc048 100644 --- a/app/assets/javascripts/lessons.coffee +++ b/app/assets/javascripts/lessons.coffee @@ -16,7 +16,7 @@ $(document).on 'turbolinks:load', -> $('#new-lesson-area').empty().hide() $('.fa-edit').show() $('.new-in-lecture').show() - $('[data-toggle="collapse"]').removeClass('disabled') + $('[data-bs-toggle="collapse"]').removeClass('disabled') return $(document).on 'click', '.cancel-lesson-edit', -> diff --git a/app/assets/javascripts/media.coffee b/app/assets/javascripts/media.coffee index a14f72034..d6aaebb90 100644 --- a/app/assets/javascripts/media.coffee +++ b/app/assets/javascripts/media.coffee @@ -18,6 +18,12 @@ fancyTimeFormat = (time) -> $(document).on 'turbolinks:load', -> + # init datetimepicker + $('#release_date').datetimepicker + format: 'd.m.Y H:i' + inline: false + lang: 'en' + # disable/enable search field on the media search page, depending on # whether 'all tags'/'all editors'/... are selected $('[id^="search_all_"]').on 'change', -> @@ -390,10 +396,7 @@ $(document).on 'turbolinks:load', -> $('#release_date').on 'focus', -> $('#medium_release_now_0').prop('checked', true) - $('#release_date').datetimepicker - format: 'd.m.Y H:i' - inline: false - lang: 'en' + $('#release_date').datetimepicker('toggle') return $('#medium_assignment_deadline').on 'focus', -> diff --git a/app/assets/javascripts/sections.coffee b/app/assets/javascripts/sections.coffee index 5b3025f81..12f9e2518 100644 --- a/app/assets/javascripts/sections.coffee +++ b/app/assets/javascripts/sections.coffee @@ -30,7 +30,7 @@ $(document).on 'turbolinks:load', -> $('#new-section-area-' + chapterId).empty().hide() $('.fa-edit').show() $('.new-in-lecture').show() - $('[data-toggle="collapse"]').removeClass('disabled') + $('[data-bs-toggle="collapse"]').removeClass('disabled') return # reload page if editing of section is cancelled diff --git a/app/assets/javascripts/talks.coffee b/app/assets/javascripts/talks.coffee index ccef2a6dc..ddc5c0077 100644 --- a/app/assets/javascripts/talks.coffee +++ b/app/assets/javascripts/talks.coffee @@ -64,7 +64,7 @@ $(document).on 'turbolinks:load', -> $(document).on 'click', '#new-talk-date-button', -> count = $(this).data('count') $('#talk-date-picker') - .append('
') + .append('') $(this).data('count', count + 1) $('#talk-basics-warning').show() return diff --git a/app/assets/javascripts/upload.coffee b/app/assets/javascripts/upload.coffee index 13d35fe29..836f08ecf 100644 --- a/app/assets/javascripts/upload.coffee +++ b/app/assets/javascripts/upload.coffee @@ -340,7 +340,7 @@ directUpload provides an interface to upload (multiple) files to an endpoint single ) -> # update helpdesk - $('[data-toggle="popover"]').popover() + $('[data-bs-toggle="popover"]').popover() hiddenInput = document.getElementById(hiddenInputElement) hiddenInput2 = document.getElementById('upload-userManuscript-hidden2') fileInput =document.getElementById(fileInputElement) @@ -440,7 +440,7 @@ directUpload provides an interface to upload (multiple) files to an endpoint @result = undefined @userManuscriptUpload = (fileInput) -> # update helpdesk - $('[data-toggle="popover"]').popover() + $('[data-bs-toggle="popover"]').popover() hiddenInput = document.getElementById('upload-userManuscript-hidden') hiddenInput2 = document.getElementById('upload-userManuscript-hidden2') fileInput.style.display = 'none' diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index ec1a92641..35f8c0d78 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -68,6 +68,8 @@ $container-max-widths: ( @import "vertices"; @import "trix"; +$badge-color: #545b62; + trix-toolbar .trix-button-row { flex-wrap: wrap; } @@ -80,11 +82,11 @@ trix-toolbar .trix-button-row { padding-left: 1rem; } -.badge-light { +.bg-light { background-color: #dae0e5; } -.badge-light[href]:hover { +.bg-light[href]:hover { background-color: #f8f9fa; } @@ -100,87 +102,79 @@ trix-toolbar .trix-button-row { font-size: 0.75em; } -.quiz -{ +.quiz { font-family: 'Cabin', sans-serif; } -.correct -{ +.correct { color: green; } -.incorrect -{ +.incorrect { color: red; } -.card-xl -{ +.card-xl { max-height: 75vh; overflow-y: scroll; } -.card-large -{ +.card-large { max-height: 70vh; overflow-y: scroll; } -.card-medium -{ +.card-medium { max-height: 60vh; overflow-y: scroll; } -.card-compact -{ +.card-compact { max-height: 50vh; overflow-y: scroll; } -.card-tiny -{ +.card-tiny { max-height: 30vh; overflow-y: scroll; } -.card-fixed-xxl -{ +.card-fixed-xxl { height: 85vh; } -.card-fixed-medium -{ +.card-fixed-medium { height: 65vh; } -.card-fixed-small -{ +.card-fixed-small { height: 20vh; } -.scrollable -{ +.scrollable { overflow-y: scroll; } -$modal-xl: 1140px !default; -$modal-xxl: 1600px !default; +$modal-xl: 1140px !default; +$modal-xxl: 1600px !default; @include media-breakpoint-up(xl) { - .modal-xl { max-width: $modal-xl; } + .modal-xl { + max-width: $modal-xl; + } } @include media-breakpoint-up(xxl) { - .modal-xxl { max-width: $modal-xxl; } + .modal-xxl { + max-width: $modal-xxl; + } } .dropdown-menu a { - text-decoration: none; + text-decoration: none !important; color: black; } @@ -194,34 +188,6 @@ $modal-xxl: 1600px !default; margin-top: -1px; } - -.card-columns { - @include media-breakpoint-only(xxxxl) { - column-count: 2; - } - @include media-breakpoint-only(xxxl) { - column-count: 2; - } - @include media-breakpoint-only(xxxl) { - column-count: 2; - } - @include media-breakpoint-only(xxl) { - column-count: 2; - } - @include media-breakpoint-only(xl) { - column-count: 1; - } - @include media-breakpoint-only(lg) { - column-count: 1; - } - @include media-breakpoint-only(md) { - column-count: 1; - } - @include media-breakpoint-only(sm) { - column-count: 1; - } -} - .assumption { text-decoration: underline; } @@ -238,17 +204,16 @@ $modal-xxl: 1600px !default; display: none; } -.revertCommontator -{ +.revertCommontator { all: unset; } table.submission-table-bordered th { - border:1px solid #c5ccd3; + border: 1px solid #c5ccd3; } table.submission-table-bordered td { - border:1px solid #c5ccd3; + border: 1px solid #c5ccd3; } .exceptionBox { @@ -296,4 +261,45 @@ table.submission-table-bordered td { #main-content-row { min-width: 100%; +} + +a { + text-decoration: none; + + &:hover { + text-decoration: underline; + } +} + +.badge { + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + + &:hover, + &:focus { + text-decoration: none; + background-color: $badge-color !important; + color: white; + } +} + +.btn { + &:hover { + text-decoration: none; + } +} + +.nav-link { + text-decoration: none; + + &:hover { + text-decoration: none !important; + } +} + +.btn-link { + text-decoration: none; + + &:hover { + text-decoration: underline; + } } \ No newline at end of file diff --git a/app/assets/stylesheets/landing.scss b/app/assets/stylesheets/landing.scss index bbd6373b5..ea65b186a 100644 --- a/app/assets/stylesheets/landing.scss +++ b/app/assets/stylesheets/landing.scss @@ -21,7 +21,9 @@ #announcement-box { display: flex; align-items: baseline; + flex-wrap: wrap; margin-bottom: 20px; + margin-top: 20px; padding: 15px; background-color: rgba(255, 255, 255, 0.96); } @@ -30,6 +32,7 @@ position: absolute; top: 0; right: 0; + width: auto; padding: 10px 20px; font-size: 1.2rem; background-color: #00243db8; diff --git a/app/assets/stylesheets/lectures.scss b/app/assets/stylesheets/lectures.scss index 7b2dc8123..6e31dd03d 100644 --- a/app/assets/stylesheets/lectures.scss +++ b/app/assets/stylesheets/lectures.scss @@ -65,4 +65,12 @@ #submission-team-size-buttons { display: none; +} + +.lecture-tag { + background-color: #dae0e5; + + &:hover { + color: white !important; + } } \ No newline at end of file diff --git a/app/assets/stylesheets/media.scss b/app/assets/stylesheets/media.scss index 938a0ec7e..3d06e221f 100644 --- a/app/assets/stylesheets/media.scss +++ b/app/assets/stylesheets/media.scss @@ -35,6 +35,14 @@ justify-content: flex-end; } +.card-header { + padding: 0.75rem 1.25rem; +} + +.card-footer { + padding: 0.75rem 1.25rem; +} + #media-card-subheader { display: flex; justify-content: space-between; diff --git a/app/assets/stylesheets/navbar.scss b/app/assets/stylesheets/navbar.scss index 18bd50825..0a49638d3 100644 --- a/app/assets/stylesheets/navbar.scss +++ b/app/assets/stylesheets/navbar.scss @@ -19,6 +19,7 @@ .navbar { box-shadow: 1px 4px 7px -2px rgba(0, 0, 0, 0.1); z-index: 1000; // place navbar and its shadow on top of everything + padding: 0.5rem 1rem; .new-comment { color: #ffc107 !important; diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index 2d8653eae..490b5103c 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -9,11 +9,8 @@ def current_ability end def home - if user_signed_in? - cookies[:locale] = current_user.locale - end - @announcements = Announcement.where(on_main_page: true, - lecture: nil).pluck(:details).join + cookies[:locale] = current_user.locale if user_signed_in? + get_announcements end def error @@ -46,8 +43,7 @@ def start :term) .sort end - @announcements = Announcement.where(on_main_page: true, - lecture: nil).pluck(:details).join + get_announcements @talks = current_user.talks.includes(lecture: :term) .select { |t| t.visible_for_user?(current_user) } .sort_by do |t| @@ -63,4 +59,10 @@ def check_for_consent redirect_to consent_profile_path unless current_user.consents end + + def get_announcements + @announcements = Announcement.where(on_main_page: true, lecture: nil) + .pluck(:details) + .join('