diff --git a/app/controllers/exercise_collections_controller.rb b/app/controllers/exercise_collections_controller.rb new file mode 100644 index 00000000..4861a062 --- /dev/null +++ b/app/controllers/exercise_collections_controller.rb @@ -0,0 +1,51 @@ +class ExerciseCollectionsController < ApplicationController + include CommonBehavior + + before_action :set_exercise_collection, only: [:show, :edit, :update, :destroy] + + def index + @exercise_collections = ExerciseCollection.all.paginate(:page => params[:page]) + authorize! + end + + def show + end + + def new + @exercise_collection = ExerciseCollection.new + authorize! + end + + def create + @exercise_collection = ExerciseCollection.new(exercise_collection_params) + authorize! + create_and_respond(object: @exercise_collection) + end + + def destroy + authorize! + destroy_and_respond(object: @exercise_collection) + end + + def edit + end + + def update + update_and_respond(object: @exercise_collection, params: exercise_collection_params) + end + + private + + def set_exercise_collection + @exercise_collection = ExerciseCollection.find(params[:id]) + authorize! + end + + def authorize! + authorize(@exercise_collection || @exercise_collections) + end + + def exercise_collection_params + params[:exercise_collection].permit(:name, :exercise_ids => []) + end +end diff --git a/app/models/exercise_collection.rb b/app/models/exercise_collection.rb index 2dca0e9d..10946962 100644 --- a/app/models/exercise_collection.rb +++ b/app/models/exercise_collection.rb @@ -2,4 +2,8 @@ class ExerciseCollection < ActiveRecord::Base has_and_belongs_to_many :exercises -end \ No newline at end of file + def to_s + "#{I18n.t('activerecord.models.exercise_collection.one')}: #{name} (#{id})" + end + +end diff --git a/app/policies/exercise_collection_policy.rb b/app/policies/exercise_collection_policy.rb new file mode 100644 index 00000000..ff150290 --- /dev/null +++ b/app/policies/exercise_collection_policy.rb @@ -0,0 +1,3 @@ +class ExerciseCollectionPolicy < AdminOnlyPolicy + +end diff --git a/app/views/application/_navigation.html.slim b/app/views/application/_navigation.html.slim index fbeca1c3..19f10a85 100644 --- a/app/views/application/_navigation.html.slim +++ b/app/views/application/_navigation.html.slim @@ -8,7 +8,7 @@ - if current_user.admin? li = link_to(t('breadcrumbs.dashboard.show'), admin_dashboard_path) li.divider - - models = [ExecutionEnvironment, Exercise, ProxyExercise, Tag, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser].sort_by { |model| model.model_name.human(count: 2) } + - models = [ExecutionEnvironment, Exercise, ExerciseCollection, ProxyExercise, Tag, Consumer, CodeHarborLink, ExternalUser, FileType, FileTemplate, InternalUser].sort_by { |model| model.model_name.human(count: 2) } - models.each do |model| - if policy(model).index? li = link_to(model.model_name.human(count: 2), send(:"#{model.model_name.collection}_path")) diff --git a/app/views/exercise_collections/_form.html.slim b/app/views/exercise_collections/_form.html.slim new file mode 100644 index 00000000..3c336a62 --- /dev/null +++ b/app/views/exercise_collections/_form.html.slim @@ -0,0 +1,11 @@ +- exercises = Exercise.order(:title) + += form_for(@exercise_collection, data: {exercises: exercises}, multipart: true) do |f| + = render('shared/form_errors', object: @exercise_collection) + .form-group + = f.label(:name) + = f.text_field(:name, class: 'form-control', required: true) + .form-group + = f.label(:exercises) + = f.collection_select(:exercise_ids, exercises, :id, :title, {}, {class: 'form-control', multiple: true}) + .actions = render('shared/submit_button', f: f, object: @exercise_collection) diff --git a/app/views/exercise_collections/edit.html.slim b/app/views/exercise_collections/edit.html.slim new file mode 100644 index 00000000..187f31d2 --- /dev/null +++ b/app/views/exercise_collections/edit.html.slim @@ -0,0 +1,3 @@ +h1 = @exercise_collection + += render('form') diff --git a/app/views/exercise_collections/index.html.slim b/app/views/exercise_collections/index.html.slim new file mode 100644 index 00000000..75a9d011 --- /dev/null +++ b/app/views/exercise_collections/index.html.slim @@ -0,0 +1,24 @@ +h1 = ExerciseCollection.model_name.human(count: 2) + +.table-responsive + table.table + thead + tr + th = t('activerecord.attributes.exercise_collections.id') + th = t('activerecord.attributes.exercise_collections.name') + th = t('activerecord.attributes.exercise_collections.updated_at') + th = t('activerecord.attributes.exercise_collections.exercises') + th colspan=3 = t('shared.actions') + tbody + - @exercise_collections.each do |collection| + tr + td = collection.id + td = link_to(collection.name, collection) + td = collection.updated_at + td = collection.exercises.size + td = link_to(t('shared.show'), collection) + td = link_to(t('shared.edit'), edit_exercise_collection_path(collection)) + td = link_to(t('shared.destroy'), collection, data: {confirm: t('shared.confirm_destroy')}, method: :delete) + += render('shared/pagination', collection: @exercise_collections) +p = render('shared/new_button', model: ExerciseCollection) diff --git a/app/views/exercise_collections/new.html.slim b/app/views/exercise_collections/new.html.slim new file mode 100644 index 00000000..0e48ccd9 --- /dev/null +++ b/app/views/exercise_collections/new.html.slim @@ -0,0 +1,3 @@ +h1 = t('shared.new_model', model: ExerciseCollection.model_name.human) + += render('form') diff --git a/app/views/exercise_collections/show.html.slim b/app/views/exercise_collections/show.html.slim new file mode 100644 index 00000000..65c28283 --- /dev/null +++ b/app/views/exercise_collections/show.html.slim @@ -0,0 +1,11 @@ +h1 + = @exercise_collection + = render('shared/edit_button', object: @exercise_collection) + += row(label: 'exercise_collections.name', value: @exercise_collection.name) += row(label: 'exercise_collections.updated_at', value: @exercise_collection.updated_at) + +h4 = t('activerecord.attributes.exercise_collections.exercises') +ul.list-unstyled + - @exercise_collection.exercises.sort_by{|c| c.title}.each do |exercise| + li = link_to(exercise, exercise) diff --git a/config/locales/de.yml b/config/locales/de.yml index a97023a4..1e2b2337 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -111,6 +111,11 @@ de: name: "Name" file_type: "Dateityp" content: "Code" + exercise_collections: + id: "ID" + name: "Name" + updated_at: "Letzte Änderung" + exercises: "Aufgaben" models: code_harbor_link: one: CodeHarbor-Link @@ -127,6 +132,9 @@ de: exercise: one: Aufgabe other: Aufgaben + exercise_collection: + one: Aufgabesammlung + other: Aufgabensammlungen proxy_exercise: one: Proxy Aufgabe other: Proxy Aufgaben diff --git a/config/locales/en.yml b/config/locales/en.yml index 3d6e6b9c..c55c90b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -111,6 +111,11 @@ en: name: "Name" file_type: "File Type" content: "Content" + exercise_collections: + id: "ID" + name: "Name" + updated_at: "Last Update" + exercises: "Exercises" models: code_harbor_link: one: CodeHarbor Link @@ -127,6 +132,9 @@ en: exercise: one: Exercise other: Exercises + exercise_collection: + one: Exercise Collection + other: Exercise Collections proxy_exercise: one: Proxy Exercise other: Proxy Exercises diff --git a/config/routes.rb b/config/routes.rb index eb243464..7f254f1d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,6 +74,8 @@ Rails.application.routes.draw do end end + resources :exercise_collections + resources :proxy_exercises do member do post :clone diff --git a/test/controllers/exercise_collections_controller_test.rb b/test/controllers/exercise_collections_controller_test.rb new file mode 100644 index 00000000..699c9271 --- /dev/null +++ b/test/controllers/exercise_collections_controller_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class ExerciseCollectionsControllerTest < ActionController::TestCase + test "should get index" do + get :index + assert_response :success + end + + test "should get show" do + get :show + assert_response :success + end + +end