Add hidden setting to puzzles
All checks were successful
CI / scan_ruby (push) Successful in 16s
CI / scan_js (push) Successful in 13s
CI / lint (push) Successful in 14s
CI / test (push) Successful in 36s

#19
This commit is contained in:
sto
2025-12-04 11:35:41 +01:00
parent a2a8a9fcef
commit 51e55f0828
11 changed files with 36 additions and 10 deletions

View File

@@ -149,7 +149,7 @@ class ContestantsController < ApplicationController
end end
@contest = @contestant.contest @contest = @contestant.contest
I18n.locale = @contest.lang I18n.locale = @contest.lang
@puzzles = @contest.puzzles @puzzles = @contest.puzzles.where(hidden: false).or(@contest.puzzles.where(hidden: nil)).order(:id)
@completion = Completion.new @completion = Completion.new
@completion.completed = true @completion.completed = true
@public = true @public = true

View File

@@ -99,7 +99,7 @@ class ContestsController < ApplicationController
if params.key?(:hide_offline) && params[:hide_offline] == "true" if params.key?(:hide_offline) && params[:hide_offline] == "true"
@contestants = @contestants.select { |contestant| !contestant.offline.present? } @contestants = @contestants.select { |contestant| !contestant.offline.present? }
end end
@puzzles = @contest.puzzles.order(:id) @puzzles = @contest.puzzles.where(hidden: false).or(@contest.puzzles.where(hidden: nil)).order(:id)
if params.key?(:hide_offline) && params.key?(:category) if params.key?(:hide_offline) && params.key?(:category)
@action_path = "/public/#{@contest.friendly_id}?hide_offline=#{params[:hide_offline]}&category=#{params[:category]}" @action_path = "/public/#{@contest.friendly_id}?hide_offline=#{params[:hide_offline]}&category=#{params[:category]}"
elsif params.key?(:category) elsif params.key?(:category)

View File

@@ -59,6 +59,6 @@ class PuzzlesController < ApplicationController
end end
def puzzle_params def puzzle_params
params.expect(puzzle: [ :brand, :name, :image, :pieces ]) params.expect(puzzle: [ :brand, :name, :image, :pieces, :hidden ])
end end
end end

View File

@@ -4,6 +4,7 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# brand :string # brand :string
# hidden :boolean
# name :string # name :string
# pieces :integer not null # pieces :integer not null
# created_at :datetime not null # created_at :datetime not null

View File

@@ -9,7 +9,7 @@ css:
- if @contest.puzzles.size <= 1 - if @contest.puzzles.size <= 1
.row.small-screen-image style="display: none" .row.small-screen-image style="display: none"
- @contest.puzzles.each do |puzzle| - @puzzles.each do |puzzle|
.d-flex.flex-column.justify-content-center.mb-5 .d-flex.flex-column.justify-content-center.mb-5
= image_tag(puzzle.image, style: "max-height: 200px; object-fit: contain") if puzzle.image.attached? = image_tag(puzzle.image, style: "max-height: 200px; object-fit: contain") if puzzle.image.attached?
.mt-2.fs-6 style="text-align: center" .mt-2.fs-6 style="text-align: center"
@@ -54,7 +54,7 @@ css:
= contestant.display_time = contestant.display_time
.col-1 .col-1
.col-5 .col-5
- @contest.puzzles.each do |puzzle| - @puzzles.each do |puzzle|
= image_tag(puzzle.image, class: "img-fluid ms-3 me-3") if puzzle.image.attached? = image_tag(puzzle.image, class: "img-fluid ms-3 me-3") if puzzle.image.attached?
.mt-3.fs-4 style="margin-left: 15px" .mt-3.fs-4 style="margin-left: 15px"
= puzzle.name = puzzle.name
@@ -76,7 +76,7 @@ css:
th th
th th
th th
- @contest.puzzles.each do |puzzle| - @puzzles.each do |puzzle|
th scope="col" th scope="col"
= image_tag(puzzle.image, class: "img-fluid", style: "max-height: 64px;") if puzzle.image.attached? = image_tag(puzzle.image, class: "img-fluid", style: "max-height: 64px;") if puzzle.image.attached?
tr tr
@@ -88,7 +88,7 @@ css:
= t("activerecord.attributes.contestant.completions") = t("activerecord.attributes.contestant.completions")
th scope="col" th scope="col"
= t("activerecord.attributes.contestant.display_time") = t("activerecord.attributes.contestant.display_time")
- @contest.puzzles.each do |puzzle| - @puzzles.each do |puzzle|
th scope="col" th scope="col"
= puzzle.name = puzzle.name
tbody tbody
@@ -102,7 +102,7 @@ css:
= contestant.completions.where(remaining_pieces: nil).length = contestant.completions.where(remaining_pieces: nil).length
td td
= contestant.completions.size > 0 && contestant.completions[-1].remaining_pieces ? "#{contestant.completions.map{|completion| completion.puzzle.pieces}.sum - contestant.completions[-1].remaining_pieces}p" : contestant.display_time = contestant.completions.size > 0 && contestant.completions[-1].remaining_pieces ? "#{contestant.completions.map{|completion| completion.puzzle.pieces}.sum - contestant.completions[-1].remaining_pieces}p" : contestant.display_time
- @contest.puzzles.each do |puzzle| - @puzzles.each do |puzzle|
td td
- contestant.completions.each do |completion| - contestant.completions.each do |completion|
- if completion.puzzle == puzzle - if completion.puzzle == puzzle

View File

@@ -21,6 +21,13 @@
.form-floating .form-floating
= form.number_field :pieces, autocomplete: "off", class: "form-control" = form.number_field :pieces, autocomplete: "off", class: "form-control"
= form.label :pieces, class: "required" = form.label :pieces, class: "required"
.row.mb-3
.col
.form-check.form-switch
= form.check_box :hidden, class: "form-check-input"
= form.label :hidden
.form-text
= t("activerecord.attributes.puzzle.hidden_description")
.row.mb-3 .row.mb-3
.col .col
.form-text.mb-1 .form-text.mb-1
@@ -42,7 +49,7 @@
} }
setMaxUploadSize(); setMaxUploadSize();
.row.mt-4 .row.mt-4.mb-5
.col .col
- if method == :patch - if method == :patch
= link_to t("helpers.buttons.delete"), contest_puzzle_path(contest, puzzle), data: { turbo_method: :delete }, class: "btn btn-danger me-2" = link_to t("helpers.buttons.delete"), contest_puzzle_path(contest, puzzle), data: { turbo_method: :delete }, class: "btn btn-danger me-2"

View File

@@ -16,6 +16,8 @@
= t("activerecord.attributes.puzzle.brand") = t("activerecord.attributes.puzzle.brand")
th th
= t("activerecord.attributes.puzzle.pieces") = t("activerecord.attributes.puzzle.pieces")
th
= t("activerecord.attributes.puzzle.hidden")
tbody tbody
- @puzzles.each do |puzzle| - @puzzles.each do |puzzle|
tr.align-middle scope="row" tr.align-middle scope="row"
@@ -27,6 +29,12 @@
= puzzle.brand = puzzle.brand
td td
= puzzle.pieces = puzzle.pieces
td
- if puzzle.hidden?
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-square" viewBox="0 0 16 16">
<path d="M14 1a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1zM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2z"/>
<path d="M10.97 4.97a.75.75 0 0 1 1.071 1.05l-3.992 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425z"/>
</svg>
td td
a.btn.btn-sm.btn-secondary href=edit_contest_puzzle_path(@contest, puzzle) a.btn.btn-sm.btn-secondary href=edit_contest_puzzle_path(@contest, puzzle)
= t("helpers.buttons.edit") = t("helpers.buttons.edit")

View File

@@ -91,6 +91,8 @@ en:
remaining_pieces: Remaining pieces remaining_pieces: Remaining pieces
puzzle: puzzle:
brand: Brand brand: Brand
hidden: hidden
hidden_description: When hidden, a puzzle doesn't appear in the public scoreboard, nor public forms
image: Image image: Image
name: Name name: Name
pieces: Number of pieces pieces: Number of pieces

View File

@@ -62,6 +62,8 @@ fr:
remaining_pieces: Pièces restantes remaining_pieces: Pièces restantes
puzzle: puzzle:
brand: Marque brand: Marque
hidden: Non découvert
hidden_description: Un puzzle non découvert n'apparaît pas dans le classement public, ni dans les formulaires publics
image: Image image: Image
name: Nom name: Nom
pieces: Nombre de pièces pieces: Nombre de pièces

View File

@@ -0,0 +1,5 @@
class AddHiddenToPuzzle < ActiveRecord::Migration[8.0]
def change
add_column :puzzles, :hidden, :boolean
end
end

3
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_11_20_152211) do ActiveRecord::Schema[8.0].define(version: 2025_12_04_100550) do
create_table "active_storage_attachments", force: :cascade do |t| create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false t.string "name", null: false
t.string "record_type", null: false t.string "record_type", null: false
@@ -161,6 +161,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_11_20_152211) do
t.integer "contest_id", null: false t.integer "contest_id", null: false
t.string "brand" t.string "brand"
t.integer "pieces", null: false t.integer "pieces", null: false
t.boolean "hidden"
t.index ["contest_id"], name: "index_puzzles_on_contest_id" t.index ["contest_id"], name: "index_puzzles_on_contest_id"
end end