Compare commits

...

4 Commits

Author SHA1 Message Date
Tocho Tochev 89b184f776 Enable addition of slides to event 2024-10-20 17:05:18 +03:00
Petko Bordjukov deebcbc95a New dev-friendly schedule endpoint 2024-10-03 23:25:01 +03:00
Tocho Tochev 5660c3ef53 Update talk confirmation template 2024-10-01 15:24:50 +03:00
Petko Bordjukov 71e8ab74da Limit access to archived conferences 2024-10-01 14:59:48 +03:00
22 changed files with 2106 additions and 24 deletions

View File

@ -4,7 +4,7 @@ class Api::EventsController < Api::ApplicationController
before_action :require_current_conference!
def index
@events = current_conference.events.approved.joins(:proposition).includes(:participations)
@events = current_conference.events.approved.joins(:proposition).includes(:participations).with_attached_resources_bundle
end
def halfnarp_friendly

View File

@ -0,0 +1,9 @@
class Api::SchedulesController < Api::ApplicationController
include ::CurrentConferenceAssigning
include ::PublicApiExposing
before_action :require_current_conference!
def show
@halls = Conference.last.halls.includes(:translations, slots: {approved_event: [:participants_with_personal_profiles, :proposition]})
end
end

View File

@ -9,6 +9,7 @@ module Management
.eager_load(:participants_with_personal_profiles,
:proposition, :proposer, {track: [:translations]},
{event_type: [:translations]}, :feedbacks)
.with_attached_resources_bundle
.preload(:conference), filters: params[:filters]).results
# @events = @conference.events.order(:title).includes(:proposition, :proposer, :track, :event_type)
@ -76,6 +77,7 @@ module Management
:abstract,
:description,
:notes,
:resources_bundle,
:track_id,
:event_type_id,
participations_attributes: [

View File

@ -8,7 +8,11 @@ module Management
private
def authorize_user!
if params[:conference_id] && params[:conference_id].to_i < Conference.last.id
head :forbidden unless current_user.admin? && current_user.owner?
else
head :forbidden unless current_user.admin?
end
end
end
end

View File

@ -2,12 +2,16 @@ module Public
class EventsController < Public::ApplicationController
before_action :authenticate_user!
def current_user_events
Event.joins(:conference, :proposition, :participations).where(conference: current_conference).where("propositions.proposer_id = ? OR participations.participant_id = ?", current_user.id, current_user.id)
end
def index
@events = Event.joins(:conference, :proposition, :participations).where(conference: current_conference).where("propositions.proposer_id = ? OR participations.participant_id = ?", current_user.id, current_user.id)
@events = current_user_events
end
def edit
@event = Event.joins(:participations).find_by(id: params[:id], participations: {participant_id: current_user.id})
@event = current_user_events.find_by(id: params[:id])
end
def new
@ -30,9 +34,9 @@ module Public
end
def update
@event = Event.joins(:participations).find_by(id: params[:id], participations: {participant_id: current_user.id})
@event = current_user_events.find_by(id: params[:id])
if @event.update(event_params)
if @event.fields_editable_by_participant && @event.update(event_params.permit(@event.fields_editable_by_participant))
flash[:notice] = I18n.t("views.events.event_successfully_updated", event_type: @event.event_type.name.mb_chars.downcase)
after_save_redirect
else
@ -56,9 +60,7 @@ module Public
def event_params
params.require(:event).permit(
:title, :subtitle, :track_id, :length, :language,
:abstract, :description, :notes, :agreement,
:event_type_id
Event.new.fields_editable_by_participant
)
end

View File

@ -12,6 +12,8 @@ class Event < ActiveRecord::Base
has_many :participants_with_personal_profiles, through: :approved_participations, source: :participant_with_personal_profile
has_many :conflict_counts, -> { order(number_of_conflicts: :desc) }, foreign_key: :left_id
has_one_attached :resources_bundle
has_many :feedbacks, as: :feedback_receiving
has_many :feedbacks_with_comment, -> { where.not(comment: [nil, ""]) }, as: :feedback_receiving, class_name: 'Feedback'
include FeedbackReceiving
@ -20,6 +22,7 @@ class Event < ActiveRecord::Base
scope :ranked, -> { where.not(ranked: nil).where.not(votes: nil) }
scope :approved, -> { where(propositions: {status: Proposition.statuses[:approved]})}
scope :approved_joined, -> { joins(:proposition).merge(Proposition.approved) }
validates :conference, presence: true
validates :title, presence: true, length: {maximum: 65}
@ -68,6 +71,25 @@ class Event < ActiveRecord::Base
}
end
def fields_editable_by_participant
if not id or conference.start_date > 7.days.from_now
[
:title, :subtitle, :track_id, :length, :language,
:abstract, :description, :notes,
:resources_bundle,
:agreement,
:event_type_id
]
elsif conference.end_date > -14.days.from_now
[
:resources_bundle,
:agreement,
]
else
[]
end
end
def ranked?
conference.has_vote_results? && rank.present? && number_of_votes.present?
end

View File

@ -1,4 +1,5 @@
class Slot < ActiveRecord::Base
belongs_to :hall
belongs_to :event, required: false
belongs_to :approved_event, -> { joins(:proposition).approved_joined }, class_name: 'Event', foreign_key: 'event_id'
end

View File

@ -11,5 +11,6 @@
json.participant_user_ids event.participations.map(&:participant_id)
json.feedback_url new_event_feedback_url(event_id: event.id)
json.feedback_qr_code_url event_feedback_qr_code_url(event_id: event.id, format: :svg)
json.resources_bundle ((event.resources_bundle.attached? && event.conference.end_date < 0.days.from_now) ? rails_blob_url(event.resources_bundle, disposition: "attachment") : nil)
end
end

View File

@ -0,0 +1,22 @@
@halls.each do |hall|
json.set! hall.name do
json.days do
hall.slots.to_a.sort_by(&:starts_at).group_by { |slot| slot.starts_at.to_date }.each do |day, slots|
json.set! day do
json.array! slots do |slot|
next unless slot.approved_event
json.starts_at slot.starts_at
json.starts_at_human l(slot.starts_at, format: '%a, %H:%M')
json.title slot.approved_event.title
json.speakers do
json.array! slot.approved_event.participants_with_personal_profiles do |participant|
json.name participant.name
json.email participant.public_email
end
end
end
end
end
end
end
end

View File

@ -11,7 +11,5 @@
С приложения QR код към този имейл ще можете да достъпите формуляра за обратна връзка на предложеното от Вас събитие. Моля, включете го в презентацията си.
Ако планирате да представяте отдалечено или използвате MacBook, моля, отговорете на този имейл, за да ни уведомите. Също така, ако имате въпроси или нужда от допълнителна информация, не се колебайте да се свържете с нас, като отговорите на този имейл.
Поздрави,
Екипът на <%= @event.conference.title %>

View File

@ -11,8 +11,6 @@ To confirm your participation please follow the link below as soon as you can:
We kindly request that you ensure the inclusion of the QR code attached to this email in your presentation. It links directly to the feedback form for your presentation, making it easier for attendees to provide valuable insights.
Additionally, please respond to this email to let us know whether your presentation will be remote or if you plan to present using a MacBook.
Should you have any questions or require further information, please do not hesitate to contact us by replying to this email.
Best regards,

View File

@ -18,6 +18,13 @@
= f.input :abstract
= f.input :description
= f.input :notes
div class="form-group file optional resources_bundle"
dev class="col-sm-3 control-label text optional"
= f.label :resources_bundle
.col-sm-9
= link_to @event.resources_bundle.filename, rails_blob_url(@event.resources_bundle.blob, disposition: "attachment") if @event.resources_bundle.attached?
= f.hidden_field :resources_bundle, value:@event.resources_bundle.signed_id if @event.resources_bundle.attached?
= f.input :resources_bundle, as: :file, wrapper: false, input_html: {direct_upload: true}, label: false
hr
.row
.col-lg-12

View File

@ -1,5 +1,5 @@
<%- csv_headers = %w{id title subtitle type track language paticipants length status rank number_of_votes proposer_notes} -%>
<%- csv_headers = %w{id title subtitle type track language participants length status rank number_of_votes abstract description proposer_notes resources_bundle} -%>
<%= CSV.generate_line(csv_headers).html_safe -%>
<%- @events.each do |event| -%>
<%= CSV.generate_line([event.id, event.title, event.subtitle, event.event_type.name, event.track.name, event.language, participant_names_with_emails(event).join(', '), event.length, event.status, event.rank, event.number_of_votes, event.notes]).html_safe -%>
<%= CSV.generate_line([event.id, event.title, event.subtitle, event.event_type.name, event.track.name, event.language, participant_names_with_emails(event).join(', '), event.length, event.status, event.rank, event.number_of_votes, event.abstract, event.description, event.notes, (rails_blob_url(event.resources_bundle, disposition: "attachment") if event.resources_bundle.attached?)]).html_safe -%>
<%- end -%>

View File

@ -36,6 +36,9 @@
- if @event.notes.present?
h3 = Event.human_attribute_name :notes
p = simple_format @event.notes
- if @event.resources_bundle.attached?
h3 = Event.human_attribute_name :resources_bundle
p = link_to @event.resources_bundle.filename, rails_blob_url(@event.resources_bundle.blob, disposition: "attachment")
- if @conference.has_vote_results? or @conference.has_voting_endpoint?
.col-md-3
.panel.panel-info.panel-rank

View File

@ -84,6 +84,7 @@ bg:
language: "Език"
length: "Продължителност"
notes: "Допълнителни бележки"
resources_bundle: "Ресурси (презентация, код, ...)"
subtitle: "Подзаглавие"
title: "Заглавие"
track: "Поток от лекции"
@ -357,6 +358,7 @@ bg:
language: ""
length: "Продължителността на събитието (в минути). Продължителността на %{type} е между %{min} и %{max} минути, заедно с въпросите"
notes: "Допълнителни бележки, които искате да споделите с организаторския екип"
resources_bundle: "Ресурси за посетителите - слайдове, код, записки, файл с връзки, архив... Те ще бъдат предоставени налични за сваляне от посетителите след конференцията."
subtitle: ""
title: ""
track: "Потокът от лекции, в който искате да попадне предложението ви"

View File

@ -84,6 +84,7 @@ en:
language: "Language"
length: "Length"
notes: "Notes"
resources_bundle: "Resources bundle"
subtitle: "Sub-title"
title: "Title"
track: "Track"
@ -357,6 +358,7 @@ en:
language: ""
length: "Length of the event (in minutes). The length of a %{type} is between %{min} and %{max} minutes"
notes: "Notes that you'd like the organisation team to read"
resources_bundle: "Resources for the visitors - slides, code, notes, file with links, archive... These will be available to the visitors after the conference."
subtitle: ""
title: ""
track: "The lecture track for your event"

View File

@ -32,6 +32,7 @@ Rails.application.routes.draw do
resources :event_types, only: :index
resources :halls, only: :index
resources :slots, only: :index
resource :schedule, only: :show
resources :volunteers
end
end

View File

@ -0,0 +1,5 @@
class AddOwnerFieldToUsers < ActiveRecord::Migration[7.1]
def change
add_column :users, :owner, :boolean, null: false, default: false
end
end

View File

@ -11,4 +11,5 @@ User.create(
password_confirmation: "123qweASD",
confirmed_at: Time.current,
admin: true
owner: true
)

1997
db/structure.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,22 @@
= simple_form_for @event, wrapper: :default do |form|
= form.input :event_type_id, as: :hidden, wrapper: false
= form.input :event_type_id, as: :hidden, wrapper: false, disabled: :event_type.in?(@event.fields_editable_by_participant)
p
= form.error_notification
.form-inputs
= form.input :title, autofocus: true
= form.input :subtitle
= form.association :track, wrapper: :default, collection: current_conference.tracks.map { |track| [track.name, track.id, {title: track.description}] }
= form.input :length, hint: t('simple_form.hints.event.length', type: @event.event_type.name.mb_chars.downcase, min: @event.event_type.minimum_length, max: @event.event_type.maximum_length)
= form.input :language, as: :radio_buttons, collection: locale_collection, include_blank: false, wrapper: :default
= form.input :abstract
= form.input :description
= form.input :notes
= form.input :title, autofocus: true, disabled: !:title.in?(@event.fields_editable_by_participant)
= form.input :subtitle, disabled: !:subtitle.in?(@event.fields_editable_by_participant)
= form.association :track, wrapper: :default, collection: current_conference.tracks.map { |track| [track.name, track.id, {title: track.description}] }, disabled: !:track_id.in?(@event.fields_editable_by_participant)
= form.input :length, hint: t('simple_form.hints.event.length', type: @event.event_type.name.mb_chars.downcase, min: @event.event_type.minimum_length, max: @event.event_type.maximum_length), disabled: !:length.in?(@event.fields_editable_by_participant)
= form.input :language, as: :radio_buttons, collection: locale_collection, include_blank: false, wrapper: :default, disabled: !:language.in?(@event.fields_editable_by_participant)
= form.input :abstract, disabled: !:abstract.in?(@event.fields_editable_by_participant)
= form.input :description, disabled: !:description.in?(@event.fields_editable_by_participant)
= form.input :notes, disabled: !:notes.in?(@event.fields_editable_by_participant)
.input
= link_to @event.resources_bundle.filename, rails_blob_url(@event.resources_bundle.blob, disposition: "attachment") if @event.resources_bundle.attached?
= form.hidden_field :resources_bundle, value:@event.resources_bundle.signed_id if @event.resources_bundle.attached?
= form.input :resources_bundle, as: :file, wrapper: false, input_html: {direct_upload: true}, disabled: !:resources_bundle.in?(@event.fields_editable_by_participant)
= form.input :agreement, as: :boolean, wrapper: :default

View File

@ -11,6 +11,7 @@ FactoryBot.define do
factory :administrator do
admin { true }
owner { true }
end
end
end