diff --git a/app/controllers/admin/content_modules_controller.rb b/app/controllers/admin/content_modules_controller.rb index c78c544..4539d2f 100644 --- a/app/controllers/admin/content_modules_controller.rb +++ b/app/controllers/admin/content_modules_controller.rb @@ -6,7 +6,7 @@ def index @active_program = @programs.find { |p| p.id.to_s == params[:program_id] } || @programs.first @modules_by_level = @active_program .content_modules.ordered - .includes(:links) + .includes(:contents) .group_by(&:level) end @@ -25,6 +25,7 @@ def create end def edit + @contents = @content_module.contents.includes(:contentable) end def update diff --git a/app/controllers/admin/contents_controller.rb b/app/controllers/admin/contents_controller.rb new file mode 100644 index 0000000..4b11b31 --- /dev/null +++ b/app/controllers/admin/contents_controller.rb @@ -0,0 +1,13 @@ +class Admin::ContentsController < AdminController + before_action :set_content, only: %i[destroy] + + def destroy + @content.destroy! + redirect_to edit_admin_content_module_path(@content.content_module), notice: "Content was successfully removed.", status: :see_other + end + + private + def set_content + @content = Content.find(params.expect(:id)) + end +end diff --git a/app/controllers/admin/links_controller.rb b/app/controllers/admin/links_controller.rb index be7aa74..fed37dd 100644 --- a/app/controllers/admin/links_controller.rb +++ b/app/controllers/admin/links_controller.rb @@ -1,6 +1,6 @@ class Admin::LinksController < AdminController before_action :set_content_module, only: %i[new create] - before_action :set_link, only: %i[edit update destroy] + before_action :set_link, only: %i[edit update] def new @link = Link.new @@ -29,12 +29,6 @@ def update end end - def destroy - content_module = @link.content_module - @link.destroy! - redirect_to edit_admin_content_module_path(content_module), notice: "Link was successfully deleted.", status: :see_other - end - private def set_content_module @content_module = ContentModule.find(params.expect(:content_module_id)) diff --git a/app/views/admin/content_modules/_content_module.html.erb b/app/views/admin/content_modules/_content_module.html.erb new file mode 100644 index 0000000..eb7a9f8 --- /dev/null +++ b/app/views/admin/content_modules/_content_module.html.erb @@ -0,0 +1,13 @@ +<%# locals: (content_module:) %> +<%= tag.tr id: dom_id(content_module) do %> + <%= content_module.name %> + <%= content_module.contents.size %> + +
+ <%= link_to "Edit", edit_admin_content_module_path(content_module), class: "btn btn-sm btn-primary" %> + <%= button_to "Delete", admin_content_module_path(content_module), method: :delete, + data: { "turbo-confirm": "Delete this module?" }, + class: "btn btn-sm btn-error" %> +
+ +<% end %> diff --git a/app/views/admin/content_modules/edit.html.erb b/app/views/admin/content_modules/edit.html.erb index ad81a80..cfe4a6f 100644 --- a/app/views/admin/content_modules/edit.html.erb +++ b/app/views/admin/content_modules/edit.html.erb @@ -6,6 +6,9 @@
  • Edit Module
  • + +

    <%= notice %>

    +

    <%= alert %>

    @@ -17,11 +20,13 @@
    -
    -

    Links

    - <%= link_to "Add link", new_admin_content_module_link_path(@content_module), class: "btn btn-sm btn-primary" %> +
    +

    Contents

    +
    + <%= link_to "Add link", new_admin_content_module_link_path(@content_module), class: "btn btn-sm btn-primary" %> +
    - <% if @content_module.links.any? %> + <% if @contents.any? %> @@ -31,59 +36,11 @@ - <% @content_module.links.each do |link| %> - - - - - - <% end %> + <%= render @contents %>
    <%= link.title %> ↗<%= link.link_type.humanize %> -
    - <%= link_to "Edit", edit_admin_link_path(link), class: "btn btn-xs btn-primary" %> - <%= button_to "Delete", admin_link_path(link), method: :delete, - data: { "turbo-confirm": "Delete this link?" }, - class: "btn btn-xs btn-error" %> -
    -
    <% else %> -

    No links yet.

    - <% end %> -
    -
    - -
    -
    -
    -

    Games

    -
    - <% if @content_module.games.any? %> - - - - - - - - - <% @content_module.games.each do |game| %> - - - - - <% end %> - -
    TitleActions
    <%= game.title %> -
    - <%= link_to "Edit", edit_admin_game_path(game), class: "btn btn-xs btn-primary" %> - <%= button_to "Delete", admin_game_path(game), method: :delete, - data: { "turbo-confirm": "Delete this game?" }, - class: "btn btn-xs btn-error" %> -
    -
    - <% else %> -

    No games yet.

    +

    No contents yet.

    <% end %>
    diff --git a/app/views/admin/content_modules/index.html.erb b/app/views/admin/content_modules/index.html.erb index a91748a..496f7e7 100644 --- a/app/views/admin/content_modules/index.html.erb +++ b/app/views/admin/content_modules/index.html.erb @@ -29,25 +29,12 @@ Name - Links + Contents Actions - <% modules.each do |mod| %> - - <%= mod.name %> - <%= mod.links.size %> - -
    - <%= link_to "Edit", edit_admin_content_module_path(mod), class: "btn btn-sm btn-primary" %> - <%= button_to "Delete", admin_content_module_path(mod), method: :delete, - data: { "turbo-confirm": "Delete this module?" }, - class: "btn btn-sm btn-error" %> -
    - - - <% end %> + <%= render partial: "admin/content_modules/content_module", collection: modules %>
    diff --git a/app/views/admin/contents/_content.html.erb b/app/views/admin/contents/_content.html.erb new file mode 100644 index 0000000..29edf75 --- /dev/null +++ b/app/views/admin/contents/_content.html.erb @@ -0,0 +1,19 @@ +<%# locals: (content:) %> +<% contentable = content.contentable %> +<%= tag.tr id: dom_id(content) do %> + <%= render "admin/contents/contentables/#{content.contentable_name}", contentable: contentable %> + +
    + <%= link_to "Edit", edit_polymorphic_path([:admin, contentable]), class: "btn btn-xs btn-primary" %> + <% if contentable.owned_by_content? %> + <%= button_to "Delete", admin_content_path(content), method: :delete, + data: { "turbo-confirm": "Delete this link? It will be removed from the module and deleted." }, + class: "btn btn-xs btn-error" %> + <% else %> + <%= button_to "Remove", admin_content_path(content), method: :delete, + data: { "turbo-confirm": "Remove this game from the module? The game itself is kept." }, + class: "btn btn-xs btn-error" %> + <% end %> +
    + +<% end %> diff --git a/app/views/admin/contents/contentables/_game.html.erb b/app/views/admin/contents/contentables/_game.html.erb new file mode 100644 index 0000000..0c91c9b --- /dev/null +++ b/app/views/admin/contents/contentables/_game.html.erb @@ -0,0 +1,3 @@ +<%# locals: (contentable:) %> +<%= contentable.title %> +Game diff --git a/app/views/admin/contents/contentables/_link.html.erb b/app/views/admin/contents/contentables/_link.html.erb new file mode 100644 index 0000000..c81dd48 --- /dev/null +++ b/app/views/admin/contents/contentables/_link.html.erb @@ -0,0 +1,3 @@ +<%# locals: (contentable:) %> +<%= link_to "#{contentable.title} ↗", safe_external_url(contentable.url), target: "_blank", rel: "noopener noreferrer", class: "link inline-flex items-center gap-1" %> +<%= contentable.link_type.humanize %> diff --git a/config/routes.rb b/config/routes.rb index cdf9e3e..b5269d3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -23,7 +23,8 @@ post :csv_import, to: "csv#import" end resources :content_modules, except: [ :show ] do - resources :links, shallow: true, except: %i[index show] + resources :links, shallow: true, except: %i[index show destroy] + resources :contents, shallow: true, only: :destroy end resources :classroom_modules, only: %i[update] end diff --git a/test/controllers/admin/content_modules_controller_test.rb b/test/controllers/admin/content_modules_controller_test.rb index 62e74e5..c24309e 100644 --- a/test/controllers/admin/content_modules_controller_test.rb +++ b/test/controllers/admin/content_modules_controller_test.rb @@ -31,16 +31,6 @@ class Admin::ContentModulesControllerTest < ActionDispatch::IntegrationTest assert_redirected_to admin_content_modules_url end - test "create appends the module and ignores a submitted position" do - ContentModule.create!(program: programs(:one), level: "moderate", name: "Existing") - - post admin_content_modules_url, params: { - content_module: { name: "New Module", program_id: programs(:one).id, level: "moderate", position: 99 } - } - - assert_equal 2, ContentModule.find_by!(name: "New Module").position - end - test "should not create with missing name" do assert_no_difference "ContentModule.count" do post admin_content_modules_url, params: { @@ -57,15 +47,24 @@ class Admin::ContentModulesControllerTest < ActionDispatch::IntegrationTest test "edit lists links ordered by position" do content_module = ContentModule.create!(program: programs(:one), level: "basic", name: "Ordered Module") - last, first = [ - content_module.contents.create!(contentable: Link.new(title: "Last Link", url: "https://example.com/2", link_type: "survey",), position: 2), - content_module.contents.create!(contentable: Link.new(title: "First Link", url: "https://example.com/1", link_type: "survey"), position: 1) - ] + last = content_module.contents.create!(contentable: Link.new(title: "Last Link", url: "https://example.com/2", link_type: "survey")) + first = content_module.contents.create!(contentable: Link.new(title: "First Link", url: "https://example.com/1", link_type: "survey")) + first.move(:up) get edit_admin_content_module_url(content_module) - hrefs = css_select("table tbody tr td:first-child a").map { |link| link["href"] } - assert_equal [ last.contentable.url, first.contentable.url ], hrefs + row_ids = css_select("tbody tr").map { |row| row["id"] } + assert_equal [ dom_id(first), dom_id(last) ], row_ids + end + + test "create appends the module and ignores a submitted position" do + ContentModule.create!(program: programs(:one), level: "moderate", name: "Existing") + + post admin_content_modules_url, params: { + content_module: { name: "New Module", program_id: programs(:one).id, level: "moderate", position: 99 } + } + + assert_equal 2, ContentModule.find_by!(name: "New Module").position end test "should update content module" do diff --git a/test/controllers/admin/contents_controller_test.rb b/test/controllers/admin/contents_controller_test.rb new file mode 100644 index 0000000..ae9b5ea --- /dev/null +++ b/test/controllers/admin/contents_controller_test.rb @@ -0,0 +1,41 @@ +require "test_helper" + +class Admin::ContentsControllerTest < ActionDispatch::IntegrationTest + setup do + @content_module = ContentModule.create!(program: programs(:one), level: "basic", name: "Module With Contents") + sign_in_as users(:one) + end + + test "destroy removes a game from the module but keeps the game" do + content = @content_module.contents.create!(contentable: games(:one)) + + assert_difference "Content.count", -1 do + assert_no_difference "Game.count" do + delete admin_content_url(content) + end + end + + assert_redirected_to edit_admin_content_module_url(@content_module) + end + + test "destroy deletes the link behind a link content" do + content = @content_module.contents.create!( + contentable: Link.new(title: "Survey", url: "https://example.com/survey", link_type: "survey") + ) + + assert_difference [ "Content.count", "Link.count" ], -1 do + delete admin_content_url(content) + end + + assert_redirected_to edit_admin_content_module_url(@content_module) + end + + test "destroy requires admin sign in" do + sign_out + + assert_no_difference "Content.count" do + delete admin_content_url(contents(:one)) + end + assert_redirected_to new_admin_session_url + end +end diff --git a/test/controllers/admin/links_controller_test.rb b/test/controllers/admin/links_controller_test.rb index 72ed1b4..916b79d 100644 --- a/test/controllers/admin/links_controller_test.rb +++ b/test/controllers/admin/links_controller_test.rb @@ -41,11 +41,4 @@ class Admin::LinksControllerTest < ActionDispatch::IntegrationTest assert_redirected_to edit_admin_content_module_url(@mod) assert_equal "Updated Title", @link.reload.title end - - test "should destroy link" do - assert_difference "Link.count", -1 do - delete admin_link_url(@link) - end - assert_redirected_to edit_admin_content_module_url(@mod) - end end