From ac3dc8d30f7ff5c23f28f4163389f21cffc13559 Mon Sep 17 00:00:00 2001 From: Sebastian Serth Date: Tue, 20 Sep 2022 00:12:46 +0200 Subject: [PATCH] Allow platform admins and internal users to switch their current study group --- app/assets/javascripts/editor/editor.js.erb | 6 +++--- app/assets/stylesheets/base.css.scss | 12 +++++++++++ app/assets/stylesheets/editor.css.scss | 12 ----------- app/controllers/sessions_controller.rb | 2 ++ app/controllers/study_groups_controller.rb | 8 ++++++- app/models/internal_user.rb | 4 ++++ app/policies/study_group_policy.rb | 4 ++-- app/views/external_users/show.html.slim | 24 ++++++++++++++++++++- app/views/internal_users/show.html.slim | 21 +++++++++++++++++- config/locales/de.yml | 8 +++++++ config/locales/en.yml | 8 +++++++ config/routes.rb | 6 +++++- 12 files changed, 94 insertions(+), 21 deletions(-) diff --git a/app/assets/javascripts/editor/editor.js.erb b/app/assets/javascripts/editor/editor.js.erb index 05b472cd..e0809247 100644 --- a/app/assets/javascripts/editor/editor.js.erb +++ b/app/assets/javascripts/editor/editor.js.erb @@ -529,7 +529,7 @@ var CodeOceanEditor = { ul.append(li); const sub_ul = document.createElement("ul"); - sub_ul.setAttribute('class', 'error_messages_list'); + sub_ul.setAttribute('class', 'inline_list'); for (let check_run of linter_results) { const sub_li = document.createElement("li"); @@ -559,9 +559,9 @@ var CodeOceanEditor = { // one or more errors? if (errorMessagesToShow.length > 1) { - ul.setAttribute('class', 'error_messages_list'); + ul.setAttribute('class', 'inline_list'); } else { - ul.setAttribute('class', 'single_error_message'); + ul.setAttribute('class', 'single_entry_inline_list'); } targetNode.append(ul); } diff --git a/app/assets/stylesheets/base.css.scss b/app/assets/stylesheets/base.css.scss index 4f5a79f0..fd9fcad7 100644 --- a/app/assets/stylesheets/base.css.scss +++ b/app/assets/stylesheets/base.css.scss @@ -139,3 +139,15 @@ span.caret { .table-row-clickable { cursor: pointer; } + +.inline_list { + list-style-type: disc; + padding-inline-start: 1.25rem; + white-space: pre-wrap; +} + +.single_entry_inline_list { + list-style-type: none; + padding-inline-start: 0; + white-space: pre-wrap; +} diff --git a/app/assets/stylesheets/editor.css.scss b/app/assets/stylesheets/editor.css.scss index 77e4eb2d..3a7b74d0 100644 --- a/app/assets/stylesheets/editor.css.scss +++ b/app/assets/stylesheets/editor.css.scss @@ -161,18 +161,6 @@ margin-left: auto; } -.error_messages_list { - list-style-type: disc; - padding-inline-start: 1.25rem; - white-space: pre-wrap; -} - -.single_error_message { - list-style-type: none; - padding-inline-start: 0; - white-space: pre-wrap; -} - .enforce-top-margin { margin-top: 5px !important; } diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 0bd9898d..38024d37 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -13,6 +13,8 @@ class SessionsController < ApplicationController def create if login(params[:email], params[:password], params[:remember_me]) + # We set the user's default study group to the "internal" group (no external id) for the given consumer. + session[:study_group_id] = current_user.study_groups.find_by(external_id: nil)&.id redirect_back_or_to(:root, notice: t('.success')) else flash.now[:danger] = t('.failure') diff --git a/app/controllers/study_groups_controller.rb b/app/controllers/study_groups_controller.rb index de84a945..2cabd7de 100644 --- a/app/controllers/study_groups_controller.rb +++ b/app/controllers/study_groups_controller.rb @@ -3,7 +3,7 @@ class StudyGroupsController < ApplicationController include CommonBehavior - before_action :set_group, only: MEMBER_ACTIONS + before_action :set_group, only: MEMBER_ACTIONS + %w[set_as_current] def index @search = policy_scope(StudyGroup).ransack(params[:q]) @@ -37,6 +37,12 @@ class StudyGroupsController < ApplicationController end private :study_group_params + def set_as_current + session[:study_group_id] = @study_group.id + current_user.store_current_study_group_id(@study_group.id) + redirect_back(fallback_location: root_path, notice: t('study_groups.set_as_current.success')) + end + def set_group @study_group = StudyGroup.find(params[:id]) authorize! diff --git a/app/models/internal_user.rb b/app/models/internal_user.rb index 5d831967..0b4cab7f 100644 --- a/app/models/internal_user.rb +++ b/app/models/internal_user.rb @@ -37,4 +37,8 @@ class InternalUser < User def displayname name end + + def current_study_group_id + study_groups.find_by(external_id: nil)&.id + end end diff --git a/app/policies/study_group_policy.rb b/app/policies/study_group_policy.rb index f3fe5295..75de5302 100644 --- a/app/policies/study_group_policy.rb +++ b/app/policies/study_group_policy.rb @@ -5,8 +5,8 @@ class StudyGroupPolicy < AdminOnlyPolicy admin? || teacher? end - %i[show? edit? update? stream_la?].each do |action| - define_method(action) { admin? || (@user.teacher? && @record.present? && @user.study_groups.exists?(@record.id)) } + %i[show? edit? update? stream_la? set_as_current?].each do |action| + define_method(action) { admin? || teacher_in_study_group? } end def destroy? diff --git a/app/views/external_users/show.html.slim b/app/views/external_users/show.html.slim index bd896ae7..1bcb87c1 100644 --- a/app/views/external_users/show.html.slim +++ b/app/views/external_users/show.html.slim @@ -7,7 +7,29 @@ h1 = @user.displayname = @user.external_id = row(label: 'external_user.consumer', value: link_to_if(policy(@user.consumer).show?, @user.consumer, @user.consumer)) = row(label: 'external_user.platform_admin', value: @user.platform_admin?) -= row(label: 'external_users.form.study_groups', value: @user.study_groups.map{|sg| "#{sg.name}"}.sort.join(", ")) += row(label: 'users.show.study_groups') do + - visible_memberships = @user.study_group_memberships.select { |study_group_membership| policy(study_group_membership.study_group).show? } + - if visible_memberships.any? + ul.mb-0 class="#{visible_memberships.one? ? 'single_entry_inline_list' : 'inline_list'}" + - visible_memberships = visible_memberships.sort_by{ |study_group_membership| study_group_membership.study_group.name} + - visible_memberships.each do |study_group_membership| + li + => link_to(study_group_membership.study_group.name, study_group_membership.study_group) + | ( + = t("activerecord.attributes.study_group_membership.role_type.#{study_group_membership.role}") + // Only platform admins are allowed to take a shorthand and switch their study group. + - if @user == current_user && current_user.admin? && study_group_membership.role_teacher? + | , + - if study_group_membership.study_group_id == current_user.current_study_group_id + span.text-success =< t('users.show.current_study_group') + - else + =< link_to(t('users.show.set_as_current_study_group'), set_as_current_study_group_path(study_group_membership.study_group), method: :post, class: 'text-muted') + - elsif @user == current_user && study_group_membership.role_teacher? && study_group_membership.study_group_id == current_user.current_study_group_id + | , + span.text-success =< t('users.show.current_study_group') + | ) + - else + = t('users.show.no_groups') h4.mt-4 = link_to(t('.exercise_statistics'), statistics_external_user_path(@user)) if policy(@user).statistics? diff --git a/app/views/internal_users/show.html.slim b/app/views/internal_users/show.html.slim index 934ce827..334e7175 100644 --- a/app/views/internal_users/show.html.slim +++ b/app/views/internal_users/show.html.slim @@ -7,6 +7,25 @@ h1 = row(label: 'internal_user.consumer', value: @user.consumer ? link_to_if(policy(@user.consumer).show?, @user.consumer, @user.consumer) : nil) = row(label: 'internal_user.platform_admin', value: @user.platform_admin?) = row(label: 'internal_user.activated', value: @user.activated?) -= row(label: 'internal_users.form.study_groups', value: @user.study_groups.map{|sg| "#{sg.name}"}.sort.join(", ")) += row(label: 'users.show.study_groups') do + - visible_memberships = @user.study_group_memberships.select { |study_group_membership| policy(study_group_membership.study_group).show? } + - if visible_memberships.any? + ul.mb-0 class="#{visible_memberships.one? ? 'single_entry_inline_list' : 'inline_list'}" + - visible_memberships = visible_memberships.sort_by{ |study_group_membership| study_group_membership.study_group.name} + - visible_memberships.each do |study_group_membership| + li + => link_to(study_group_membership.study_group.name, study_group_membership.study_group) + | ( + = t("activerecord.attributes.study_group_membership.role_type.#{study_group_membership.role}") + // All internal users (except learners) are allowed to switch their study group here. + - if @user == current_user && study_group_membership.role_teacher? + | , + - if study_group_membership.study_group_id == current_user.current_study_group_id + span.text-success =< t('users.show.current_study_group') + - else + =< link_to(t('users.show.set_as_current_study_group'), set_as_current_study_group_path(study_group_membership.study_group), method: :post, class: 'text-muted') + | ) + - else + = t('users.show.no_groups') = row(label: 'codeharbor_link.profile_label', value: @user.codeharbor_link.nil? ? link_to(t('codeharbor_link.new'), new_codeharbor_link_path, class: 'btn btn-secondary') : link_to(t('codeharbor_link.edit'), edit_codeharbor_link_path(@user.codeharbor_link), class: 'btn btn-secondary')) diff --git a/config/locales/de.yml b/config/locales/de.yml index f75ad4dc..10e684c7 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -891,8 +891,16 @@ de: history: Punkteverlauf percentage: Prozentzahl siblings: Dazugehörige Abgaben + study_groups: + set_as_current: + success: Die Lerngruppe wurde erfolgreich gewechselt. users: platform_admin: Plattform Administrator + show: + current_study_group: Aktuelle Lerngruppe + set_as_current_study_group: Als aktuelle Lerngruppe setzen + study_groups: Lerngruppen + no_groups: Diese Person ist keiner Lerngruppe zugeordnet oder Sie sind nicht berechtigt, die Lerngruppen einzusehen. will_paginate: next_label: 'Nächste Seite →' page_gap: '…' diff --git a/config/locales/en.yml b/config/locales/en.yml index 5be19d30..6ae1fcf7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -891,8 +891,16 @@ en: history: Score History percentage: Percentage siblings: Associated Submissions + study_groups: + set_as_current: + success: The study group has been switched successfully. users: platform_admin: Platform Admin + show: + current_study_group: Current Study Group + set_as_current_study_group: Set as Current Study Group + study_groups: Study Groups + no_groups: This user is either not part of any group or you do not have the necessary permissions to view them. will_paginate: next_label: 'Next Page →' page_gap: '…' diff --git a/config/routes.rb b/config/routes.rb index dc276e13..a1a5e0f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -160,7 +160,11 @@ Rails.application.routes.draw do end end - resources :study_groups, only: %i[index show edit destroy update] + resources :study_groups, only: %i[index show edit destroy update] do + member do + post :set_as_current + end + end resources :events, only: [:create]