Merge pull request #248 from openHPI/improve_groups
Improve groups with a view and always create a group
This commit is contained in:
@ -161,8 +161,11 @@ module Lti
|
|||||||
|
|
||||||
|
|
||||||
def set_study_group_membership
|
def set_study_group_membership
|
||||||
return if mooc_course
|
if mooc_course
|
||||||
|
group = StudyGroup.find_or_create_by(name: @provider.context_title, external_id: @provider.context_id, consumer: @consumer)
|
||||||
|
else
|
||||||
group = StudyGroup.find_or_create_by(external_id: @provider.resource_link_id, consumer: @consumer)
|
group = StudyGroup.find_or_create_by(external_id: @provider.resource_link_id, consumer: @consumer)
|
||||||
|
end
|
||||||
group.users |= [@current_user] # add current user if not already member of the group
|
group.users |= [@current_user] # add current user if not already member of the group
|
||||||
group.save
|
group.save
|
||||||
end
|
end
|
||||||
|
48
app/controllers/study_groups_controller.rb
Normal file
48
app/controllers/study_groups_controller.rb
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
class StudyGroupsController < ApplicationController
|
||||||
|
include CommonBehavior
|
||||||
|
|
||||||
|
before_action :set_group, only: MEMBER_ACTIONS
|
||||||
|
|
||||||
|
def index
|
||||||
|
@search = StudyGroup.search(params[:q])
|
||||||
|
@study_groups = @search.result.includes(:consumer).order(:name).paginate(page: params[:page])
|
||||||
|
authorize!
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@search = @study_group.users.search(params[:q])
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
@search = @study_group.users.search(params[:q])
|
||||||
|
@members = StudyGroupMembership.where(user: @search.result)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
myparams = study_group_params
|
||||||
|
myparams[:users] = StudyGroupMembership.find(myparams[:study_group_membership_ids].reject(&:empty?)).map(&:user)
|
||||||
|
myparams.delete(:study_group_membership_ids)
|
||||||
|
update_and_respond(object: @study_group, params: myparams)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
destroy_and_respond(object: @study_group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def study_group_params
|
||||||
|
params[:study_group].permit(:id, :name, :study_group_membership_ids => []) if params[:study_group].present?
|
||||||
|
end
|
||||||
|
private :study_group_params
|
||||||
|
|
||||||
|
def set_group
|
||||||
|
@study_group = StudyGroup.find(params[:id])
|
||||||
|
authorize!
|
||||||
|
end
|
||||||
|
private :set_group
|
||||||
|
|
||||||
|
def authorize!
|
||||||
|
authorize(@study_groups || @study_group)
|
||||||
|
end
|
||||||
|
private :authorize!
|
||||||
|
|
||||||
|
end
|
@ -1,7 +1,8 @@
|
|||||||
class Consumer < ApplicationRecord
|
class Consumer < ApplicationRecord
|
||||||
has_many :users
|
has_many :users
|
||||||
|
|
||||||
scope :with_users, -> { where('id IN (SELECT consumer_id FROM internal_users)') }
|
scope :with_internal_users, -> { where('id IN (SELECT DISTINCT consumer_id FROM internal_users)') }
|
||||||
|
scope :with_study_groups, -> { where('id IN (SELECT DISTINCT consumer_id FROM study_groups)') }
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :oauth_key, presence: true, uniqueness: true
|
validates :oauth_key, presence: true, uniqueness: true
|
||||||
|
21
app/policies/study_group_policy.rb
Normal file
21
app/policies/study_group_policy.rb
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
class StudyGroupPolicy < AdminOnlyPolicy
|
||||||
|
def index?
|
||||||
|
admin? || teacher?
|
||||||
|
end
|
||||||
|
|
||||||
|
[:show?, :destroy?, :edit?, :update?].each do |action|
|
||||||
|
define_method(action) { admin? || @user.teacher? && @record.users.include?(@user) }
|
||||||
|
end
|
||||||
|
|
||||||
|
class Scope < Scope
|
||||||
|
def resolve
|
||||||
|
if @user.admin?
|
||||||
|
@scope.all
|
||||||
|
elsif @user.teacher?
|
||||||
|
@scope.joins(:study_group_memberships).where('user_id = ? AND user_type = ?', @user.id, @user.class.name)
|
||||||
|
else
|
||||||
|
@scope.none
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -13,6 +13,7 @@
|
|||||||
models: [Exercise, ExerciseCollection, ProxyExercise, Tag, Submission], link: exercises_path, cached: true)
|
models: [Exercise, ExerciseCollection, ProxyExercise, Tag, Submission], link: exercises_path, cached: true)
|
||||||
= render('navigation_submenu', title: t('navigation.sections.users'), models: [InternalUser, ExternalUser],
|
= render('navigation_submenu', title: t('navigation.sections.users'), models: [InternalUser, ExternalUser],
|
||||||
cached: true)
|
cached: true)
|
||||||
|
= render('navigation_collection_link', model: StudyGroup, cached: true)
|
||||||
= render('navigation_collection_link', model: ExecutionEnvironment, cached: true)
|
= render('navigation_collection_link', model: ExecutionEnvironment, cached: true)
|
||||||
= render('navigation_submenu', title: t('navigation.sections.errors'),
|
= render('navigation_submenu', title: t('navigation.sections.errors'),
|
||||||
models: [ErrorTemplate, ErrorTemplateAttribute], cached: true)
|
models: [ErrorTemplate, ErrorTemplateAttribute], cached: true)
|
||||||
|
@ -3,7 +3,7 @@ h1 = InternalUser.model_name.human(count: 2)
|
|||||||
= render(layout: 'shared/form_filters') do |f|
|
= render(layout: 'shared/form_filters') do |f|
|
||||||
.form-group
|
.form-group
|
||||||
= f.label(:consumer_id_eq, t('activerecord.attributes.internal_user.consumer'), class: 'sr-only')
|
= f.label(:consumer_id_eq, t('activerecord.attributes.internal_user.consumer'), class: 'sr-only')
|
||||||
= f.collection_select(:consumer_id_eq, Consumer.with_users, :id, :name, class: 'form-control', prompt: t('activerecord.attributes.internal_user.consumer'))
|
= f.collection_select(:consumer_id_eq, Consumer.with_internal_users, :id, :name, class: 'form-control', prompt: t('activerecord.attributes.internal_user.consumer'))
|
||||||
.form-group
|
.form-group
|
||||||
= f.label(:email_cont, t('activerecord.attributes.internal_user.email'), class: 'sr-only')
|
= f.label(:email_cont, t('activerecord.attributes.internal_user.email'), class: 'sr-only')
|
||||||
= f.search_field(:email_cont, class: 'form-control', placeholder: t('activerecord.attributes.internal_user.email'))
|
= f.search_field(:email_cont, class: 'form-control', placeholder: t('activerecord.attributes.internal_user.email'))
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
- content_for :head do
|
|
||||||
// Force a full page reload, see https://github.com/turbolinks/turbolinks/issues/326.
|
|
||||||
Otherwise, code might not be highlighted correctly (race condition)
|
|
||||||
meta name='turbolinks-visit-control' content='reload'
|
|
||||||
= javascript_pack_tag('highlight', 'data-turbolinks-track': true)
|
|
||||||
= stylesheet_pack_tag('highlight', media: 'all', 'data-turbolinks-track': true)
|
|
||||||
|
|
||||||
h1
|
h1
|
||||||
= @proxy_exercise.title
|
= @proxy_exercise.title
|
||||||
= render('shared/edit_button', object: @proxy_exercise)
|
= render('shared/edit_button', object: @proxy_exercise)
|
||||||
|
19
app/views/study_groups/_form.html.slim
Normal file
19
app/views/study_groups/_form.html.slim
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
= form_for(@study_group) do |f|
|
||||||
|
= render('shared/form_errors', object: @study_group)
|
||||||
|
.form-group
|
||||||
|
= f.label(:name)
|
||||||
|
= f.text_field(:name, class: 'form-control', required: true)
|
||||||
|
|
||||||
|
h3 = t('activerecord.attributes.study_group.members')
|
||||||
|
.table-responsive
|
||||||
|
table.table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th = t('activerecord.attributes.exercise.selection')
|
||||||
|
th = sort_link(@search, :name, t('navigation.sections.users'))
|
||||||
|
= collection_check_boxes :study_group, :study_group_membership_ids, @members, :id, :id do |b|
|
||||||
|
tr
|
||||||
|
td = b.check_box
|
||||||
|
td = link_to_if(policy(b.object.user).show?, b.object.user.displayname, b.object.user)
|
||||||
|
|
||||||
|
.actions = render('shared/submit_button', f: f, object: @study_group)
|
3
app/views/study_groups/edit.html.slim
Normal file
3
app/views/study_groups/edit.html.slim
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
h1 = @study_group
|
||||||
|
|
||||||
|
= render('form')
|
32
app/views/study_groups/index.html.slim
Normal file
32
app/views/study_groups/index.html.slim
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
h1 = StudyGroup.model_name.human(count: 2)
|
||||||
|
|
||||||
|
= render(layout: 'shared/form_filters') do |f|
|
||||||
|
.form-group
|
||||||
|
= f.label(:consumer_id_eq, t('activerecord.attributes.internal_user.consumer'), class: 'sr-only')
|
||||||
|
= f.collection_select(:consumer_id_eq, Consumer.with_study_groups, :id, :name, class: 'form-control', prompt: t('activerecord.attributes.internal_user.consumer'))
|
||||||
|
.form-group
|
||||||
|
= f.label(:name_cont, t('activerecord.attributes.study_group.name'), class: 'sr-only')
|
||||||
|
= f.search_field(:name_cont, class: 'form-control', placeholder: t('activerecord.attributes.study_group.name'))
|
||||||
|
|
||||||
|
.table-responsive
|
||||||
|
table.table.mt-4
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th = t('activerecord.attributes.study_group.name')
|
||||||
|
th = t('activerecord.attributes.study_group.external_id')
|
||||||
|
th = t('activerecord.attributes.study_group.consumer')
|
||||||
|
th = t('activerecord.attributes.study_group.member_count')
|
||||||
|
th colspan=3 = t('shared.actions')
|
||||||
|
tbody
|
||||||
|
- @study_groups.each do |group|
|
||||||
|
tr
|
||||||
|
td = link_to_if(policy(group).show?, group.to_s, group)
|
||||||
|
td
|
||||||
|
code = group.external_id
|
||||||
|
td = link_to_if(policy(group.consumer).show?, group.consumer, group.consumer)
|
||||||
|
td = group.users.count
|
||||||
|
td = link_to(t('shared.show'), group) if policy(group).show?
|
||||||
|
td = link_to(t('shared.edit'), edit_study_group_path(group)) if policy(group).edit?
|
||||||
|
td = link_to(t('shared.destroy'), group, data: {confirm: t('shared.confirm_destroy')}, method: :delete) if policy(group).destroy?
|
||||||
|
|
||||||
|
= render('shared/pagination', collection: @study_groups)
|
21
app/views/study_groups/show.html.slim
Normal file
21
app/views/study_groups/show.html.slim
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
h1
|
||||||
|
= @study_group
|
||||||
|
- if policy(@study_group).edit?
|
||||||
|
= render('shared/edit_button', object: @study_group)
|
||||||
|
|
||||||
|
= row(label: 'study_group.name', value: @study_group.name)
|
||||||
|
= row(label: 'study_group.external_id') do
|
||||||
|
code = @study_group.external_id
|
||||||
|
= row(label: 'study_group.consumer', value: link_to_if(policy(@study_group).show?, @study_group.consumer, @study_group.consumer))
|
||||||
|
= row(label: 'study_group.member_count', value: @study_group.users.count)
|
||||||
|
|
||||||
|
|
||||||
|
h2.mt-4 = t('activerecord.attributes.study_group.members')
|
||||||
|
.table-responsive
|
||||||
|
table.table
|
||||||
|
thead
|
||||||
|
tr
|
||||||
|
th = sort_link(@search, :name, t('navigation.sections.users'))
|
||||||
|
- @study_group.users.each do |user|
|
||||||
|
tr
|
||||||
|
td = link_to_if(policy(user).show?, user.displayname, user)
|
@ -101,6 +101,12 @@ de:
|
|||||||
files: Dateien
|
files: Dateien
|
||||||
score: Punktzahl
|
score: Punktzahl
|
||||||
user: Autor
|
user: Autor
|
||||||
|
study_group:
|
||||||
|
name: Name
|
||||||
|
external_id: Externe ID
|
||||||
|
consumer: Konsument
|
||||||
|
members: Mitglieder
|
||||||
|
member_count: Anzahl der Mitglieder
|
||||||
tag:
|
tag:
|
||||||
name: Name
|
name: Name
|
||||||
usage: Verwendet
|
usage: Verwendet
|
||||||
@ -181,6 +187,9 @@ de:
|
|||||||
submission:
|
submission:
|
||||||
one: Abgabe
|
one: Abgabe
|
||||||
other: Abgaben
|
other: Abgaben
|
||||||
|
study_group:
|
||||||
|
one: Lerngruppe
|
||||||
|
other: Lerngruppen
|
||||||
tag:
|
tag:
|
||||||
one: Tag
|
one: Tag
|
||||||
other: Tags
|
other: Tags
|
||||||
|
@ -101,6 +101,12 @@ en:
|
|||||||
files: Files
|
files: Files
|
||||||
score: Score
|
score: Score
|
||||||
user: Author
|
user: Author
|
||||||
|
study_group:
|
||||||
|
name: Name
|
||||||
|
external_id: External ID
|
||||||
|
consumer: Consumer
|
||||||
|
members: Members
|
||||||
|
member_count: Member Count
|
||||||
tag:
|
tag:
|
||||||
name: Name
|
name: Name
|
||||||
usage: Used
|
usage: Used
|
||||||
@ -181,6 +187,9 @@ en:
|
|||||||
submission:
|
submission:
|
||||||
one: Submission
|
one: Submission
|
||||||
other: Submissions
|
other: Submissions
|
||||||
|
study_group:
|
||||||
|
one: Study Group
|
||||||
|
other: Study Groups
|
||||||
tag:
|
tag:
|
||||||
one: Tag
|
one: Tag
|
||||||
other: Tags
|
other: Tags
|
||||||
|
@ -145,6 +145,8 @@ Rails.application.routes.draw do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :study_groups, only: [:index, :show, :edit, :destroy, :update]
|
||||||
|
|
||||||
resources :events, only: [:create]
|
resources :events, only: [:create]
|
||||||
|
|
||||||
post "/evaluate", to: 'remote_evaluation#evaluate', via: [:post]
|
post "/evaluate", to: 'remote_evaluation#evaluate', via: [:post]
|
||||||
|
Reference in New Issue
Block a user