Add indicator for processed messages
All checks were successful
CI / scan_ruby (push) Successful in 17s
CI / scan_js (push) Successful in 12s
CI / lint (push) Successful in 14s
CI / test (push) Successful in 36s

This commit is contained in:
sto 2025-06-18 18:42:04 +02:00
parent 96b8553b1f
commit 67d2ef41b3
13 changed files with 42 additions and 11 deletions

View File

@ -70,6 +70,6 @@ class CompletionsController < ApplicationController
end
def completion_params
params.expect(completion: [ :display_time_from_start, :contestant_id, :puzzle_id ])
params.expect(completion: [ :display_time_from_start, :contestant_id, :message_id, :puzzle_id ])
end
end

View File

@ -26,6 +26,6 @@ module CompletionsConcern
display_relative_time: display_time(completion.time_seconds - current_time_from_start))
current_time_from_start = completion.time_seconds
end
contestant.update(display_time: display_time(current_time_from_start))
contestant.update(display_time: display_time(current_time_from_start), time_seconds: current_time_from_start)
end
end

View File

@ -10,28 +10,32 @@
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer not null
# message_id :integer
# puzzle_id :integer not null
#
# Indexes
#
# index_completions_on_contest_id (contest_id)
# index_completions_on_contestant_id (contestant_id)
# index_completions_on_message_id (message_id)
# index_completions_on_puzzle_id (puzzle_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
# message_id (message_id => messages.id)
# puzzle_id (puzzle_id => puzzles.id)
#
class Completion < ApplicationRecord
belongs_to :contest
belongs_to :contestant
belongs_to :puzzle
belongs_to :message, optional: true
before_save :add_time_seconds
validates :display_time_from_start, presence: true, format: { with: /\A((\d\d|\d):\d\d|\d\d|\d):\d\d\z/ }
validates :display_time_from_start, presence: true, format: { with: /\A(((\d\d|\d):\d\d|\d\d|\d):\d\d|\d\d|\d)\z/ }
validates :puzzle_id, uniqueness: { scope: :contestant }
def add_time_seconds

View File

@ -27,7 +27,7 @@ class Contest < ApplicationRecord
has_many :completions, dependent: :destroy
has_many :contestants, dependent: :destroy
has_many :puzzles, dependent: :destroy
has_many :messages
has_many :messages, dependent: :destroy
friendly_id :name, use: :slugged

View File

@ -21,6 +21,7 @@
#
class Message < ApplicationRecord
belongs_to :contest
has_many :completions, dependent: :nullify
validates :author, presence: true
validates :text, presence: true

View File

@ -1,5 +1,6 @@
= form_with model: completion, url: url, method: method do |form|
- if @message
= form.hidden_field :message_id, value: @message.id
.row.mb-3
.col
h4 = t("messages.singular").capitalize

View File

@ -18,7 +18,7 @@
= link_to "#{message_url}?token=#{@contest.generate_token_for(:token)}"
.row.mb-4
.col-6
.col-7
.row
.col
h4
@ -38,7 +38,7 @@
- @puzzles.each do |puzzle|
tr.align-middle scope="row"
td
= image_tag(puzzle.image, class: "img-fluid", style: "max-width: 140px;") if puzzle.image.attached?
= image_tag(puzzle.image, class: "img-fluid", style: "max-height: 48px;") if puzzle.image.attached?
td
= puzzle.name
td
@ -57,15 +57,24 @@
table.table.table-striped.table-hover
thead
tr
th scope="col" style="white-space: nowrap"
= t("activerecord.attributes.message.processed")
th scope="col"
= t("activerecord.attributes.message.time")
th scope="col"
= t("activerecord.attributes.message.author")
th scope="col"
th.w-25 scope="col"
= t("activerecord.attributes.message.text")
th.w-25 scope="col"
tbody
- @messages.each do |message|
tr.align-middle scope="row"
td style="text-align: center"
- if message.completions.size > 0
<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
= message.display_time
td
@ -81,7 +90,7 @@
= t("helpers.buttons.add_completion")
td
= link_to t("helpers.buttons.delete"), contest_message_path(@contest, message), data: { turbo_method: :delete }, class: "btn btn-sm btn-danger"
.col-6
.col-5
.row
.col
h4

View File

@ -48,6 +48,7 @@ en:
name: "Name"
message:
author: "Author"
processed: "Processed?"
text: "Content"
time: "Time"
puzzle:
@ -64,7 +65,7 @@ en:
completion:
attributes:
display_time_from_start:
invalid: "Allowed formats: xx:xx:xx, x:xx:xx, xx:xx, x:xx"
invalid: "Allowed formats: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx"
puzzle_id:
taken: "This contestant has already completed this puzzle"
csv_import:

View File

@ -19,6 +19,7 @@ fr:
name: "Nom"
message:
author: "Auteur.ice"
processed: "Traité ?"
text: "Contenu"
time: "Temps"
puzzle:
@ -35,7 +36,7 @@ fr:
completion:
attributes:
display_time_from_start:
invalid: "Formats autorisés: xx:xx:xx, x:xx:xx, xx:xx, x:xx"
invalid: "Formats autorisés: xx:xx:xx, x:xx:xx, xx:xx, x:xx, xx"
puzzle_id:
taken: "Ce.tte participant.e a déjà complété ce puzzle"
csv_import:

View File

@ -0,0 +1,5 @@
class AddMessageRefToCompletion < ActiveRecord::Migration[8.0]
def change
add_reference :completions, :message, foreign_key: true
end
end

5
db/schema.rb generated
View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.0].define(version: 2025_06_18_122655) do
ActiveRecord::Schema[8.0].define(version: 2025_06_18_155041) do
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
@ -48,8 +48,10 @@ ActiveRecord::Schema[8.0].define(version: 2025_06_18_122655) do
t.integer "contest_id", null: false
t.string "display_time_from_start"
t.string "display_relative_time"
t.integer "message_id"
t.index ["contest_id"], name: "index_completions_on_contest_id"
t.index ["contestant_id"], name: "index_completions_on_contestant_id"
t.index ["message_id"], name: "index_completions_on_message_id"
t.index ["puzzle_id"], name: "index_completions_on_puzzle_id"
end
@ -138,6 +140,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_06_18_122655) do
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "completions", "contestants"
add_foreign_key "completions", "contests"
add_foreign_key "completions", "messages"
add_foreign_key "completions", "puzzles"
add_foreign_key "contestants", "contests"
add_foreign_key "contests", "users"

View File

@ -12,18 +12,21 @@
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer not null
# message_id :integer
# puzzle_id :integer not null
#
# Indexes
#
# index_completions_on_contest_id (contest_id)
# index_completions_on_contestant_id (contestant_id)
# index_completions_on_message_id (message_id)
# index_completions_on_puzzle_id (puzzle_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
# message_id (message_id => messages.id)
# puzzle_id (puzzle_id => puzzles.id)
#
completion_one:

View File

@ -10,18 +10,21 @@
# updated_at :datetime not null
# contest_id :integer not null
# contestant_id :integer not null
# message_id :integer
# puzzle_id :integer not null
#
# Indexes
#
# index_completions_on_contest_id (contest_id)
# index_completions_on_contestant_id (contestant_id)
# index_completions_on_message_id (message_id)
# index_completions_on_puzzle_id (puzzle_id)
#
# Foreign Keys
#
# contest_id (contest_id => contests.id)
# contestant_id (contestant_id => contestants.id)
# message_id (message_id => messages.id)
# puzzle_id (puzzle_id => puzzles.id)
#
require "test_helper"