Skip to content

Commit

Permalink
add batch editing for events
Browse files Browse the repository at this point in the history
  • Loading branch information
elad-eyal committed Oct 17, 2020
1 parent e887816 commit 92c1983
Show file tree
Hide file tree
Showing 16 changed files with 500 additions and 1 deletion.
74 changes: 74 additions & 0 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,14 @@ def filter_modal
render partial: 'filter_modal'
end

def bulk_edit_modal
authorize @conference, :read?
@events = search @conference.events_with_review_averages.includes(:track)
@num_of_matching_events = @events.reorder('').pluck(:id).count

render partial: 'bulk_edit_modal'
end

# events as pdf
def cards
authorize @conference, :manage?
Expand Down Expand Up @@ -165,6 +173,10 @@ def start_review
def batch_actions
if params[:bulk_email]
bulk_send_email
elsif params[:bulk_set]
bulk_set
elsif params[:bulk_add_person]
bulk_add_person
else
redirect_to events_path, alert: :illegal
end
Expand All @@ -188,6 +200,68 @@ def bulk_send_email
end
end

def bulk_set
authorize @conference, :orga?
events = search @conference.events_with_review_averages.includes(:track)

total_successful = 0
total_skipped = 0
total_failed = 0
events.each do |event|
if event.try(params[:bulk_set_attribute]) == params[:bulk_set_value]
total_skipped +=1
elsif event.update( params[:bulk_set_attribute] => params[:bulk_set_value] )
total_successful += 1
else
total_failed += 1
end
end

summary = [ t('events_module.bulk_edit.update_successful', count: total_successful),
(t('events_module.bulk_edit.update_skipped', count: total_skipped) if total_skipped > 0),
(t('events_module.bulk_edit.update_failed', count: total_failed) if total_failed > 0) ].join(' ')

if total_failed > 0
redirect_back alert: summary, fallback_location: root_path
else
redirect_back notice: summary, fallback_location: root_path
end
end

def bulk_add_person
authorize @conference, :orga?
events = search @conference.events_with_review_averages.includes(:track)

person_id = params[:person_id]
event_role = params[:event_role]
redirect_back(alert: t('ability.denied'), fallback_location: root_path) and return if person_id.blank? or event_role.blank?

total_successful = 0
total_skipped = 0
total_failed = 0

events.each do |event|
if EventPerson.where(event: event, person_id: person_id, event_role: event_role).any?
total_skipped +=1
elsif event.update( event_people_attributes: { 'x' => { person_id: person_id,
event_role: event_role } } )
total_successful += 1
else
total_failed += 1
end
end

summary = [ t('events_module.bulk_edit.update_successful', count: total_successful),
(t('events_module.bulk_edit.update_skipped', count: total_skipped) if total_skipped > 0),
(t('events_module.bulk_edit.update_failed', count: total_failed) if total_failed > 0) ].join(' ')

if total_failed > 0
redirect_back alert: summary, fallback_location: root_path
else
redirect_back notice: summary, fallback_location: root_path
end
end

# GET /events/1
# GET /events/1.json
def show
Expand Down
4 changes: 4 additions & 0 deletions app/models/event.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def track_name
track.try(:name)
end

def track_name=(name)
update(track: conference.tracks.find_by(name: name))
end

def end_time
start_time.since((time_slots * conference.timeslot_duration).minutes)
end
Expand Down
5 changes: 5 additions & 0 deletions app/views/events/_below_table.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,9 @@
id: 'bulk_email',
data: { confirm: t('notifications_module.send_unspecified_notification_confirm', count: @num_of_matching_events) },
class: 'danger'
- if policy(@conference).manage?
%p
= link_to t('events_module.bulk_edit.show'), '#',
class: [ 'show_events_modal' ] ,
data: { url: bulk_edit_modal_events_url(request.query_parameters) }

107 changes: 107 additions & 0 deletions app/views/events/_bulk_edit_modal.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
.modal-header
= link_to "×", "#", class: "close"
%h3
= t('events_module.bulk_edit.title', count: @num_of_matching_events)
.modal-body#filter_form
- if policy(@conference).manage?
%div.actions.editables
= select_tag 'edit_selector',
options_for_select( [ [t('events_module.bulk_edit.set_new_track'), :set_new_track],
[t('events_module.bulk_edit.set_new_event_type'), :set_new_event_type],
[t('events_module.bulk_edit.set_new_state'), :set_new_state],
[t('events_module.bulk_edit.add_person'), :add_person]]),
include_blank: t('select_one'),
style: "width:400px"
%div.editable.set_new_track{style: "display:none;"}
- if @conference.tracks.any?
= simple_form_for(:bulk_edit_track, url: batch_actions_events_path(request.query_parameters), method: :post) do |f|
= f.label t('events_module.bulk_edit.set_new_track')
= f.hidden_field 'bulk_set_attribute', value: 'track_name', name: 'bulk_set_attribute'
= select_tag 'bulk_set_value', options_for_select(@conference.tracks.map { |t| t.name.to_s }), include_blank: t('select_one'), style: "width:400px"
.actions= f.button :submit,
t('set'),
name: 'bulk_set',
id: 'bulk_set',
data: { confirm: t('events_module.bulk_edit.set_track_confirm', count: @num_of_matching_events) },
class: 'danger'
%div.editable.set_new_event_type{style: "display:none;"}
= simple_form_for(:bulk_edit_event_type, url: batch_actions_events_path(request.query_parameters), method: :post) do |f|
= f.label t('events_module.bulk_edit.set_new_event_type')
= f.hidden_field 'bulk_set_attribute', value: 'event_type', name: 'bulk_set_attribute'
= select_tag 'bulk_set_value', options_for_select(translated_options(@conference.allowed_event_types_as_list)), include_blank: t('select_one'), style: "width:400px"
.actions= f.button :submit,
t('set'),
name: 'bulk_set',
id: 'bulk_set',
data: { confirm: t('events_module.bulk_edit.set_events_type_confirm', count: @num_of_matching_events) },
class: 'danger'
%div.editable.set_new_state{style: "display:none;"}
= simple_form_for(:bulk_edit_event_state, url: batch_actions_events_path(request.query_parameters), method: :post) do |f|
= f.label t('events_module.bulk_edit.set_new_state')
= f.hidden_field 'bulk_set_attribute', value: 'state', name: 'bulk_set_attribute'
= select_tag 'bulk_set_value',
options_for_select(Event.state_machine.states.map { |st| [t(st.name.to_s, scope: 'conferences_module'), st.name.to_s] }),
include_blank: t('select_one'), style: "width:400px"
.actions= f.button :submit,
t('set'),
name: 'bulk_set',
id: 'bulk_set',
data: { confirm: t('events_module.bulk_edit.set_events_confirm', count: @num_of_matching_events) },
class: 'danger'
%div.editable.add_person{style: "display:none;"}
= simple_form_for(:bulk_edit_add_person,
url: batch_actions_events_path(request.query_parameters),
method: :post,
data: { persons: Person.fullname_options } ) do |f|
.peoplefilter
= f.label t('events_module.bulk_edit.add_person')
= text_field_tag :filter, 'filter', style: "width:200px"
= select_tag :person_id,
options_for_select(Person.all.sort_by(&:full_name).map{|p| [p.full_name_annotated, p.id]}),
name: :person_id,
include_blank: t('select_one'),
style: "width:200px"
= f.label t('role_str')
= select_tag :event_role,
options_for_select(translated_options(EventPerson::ROLES)),
include_blank: t('select_one'),
style: "width:200px"
.actions= f.button :submit,
t('add'),
name: 'bulk_add_person',
id: 'bulk_add_person',
data: { confirm: t('events_module.bulk_edit.add_person_confirm', count: @num_of_matching_events) },
class: 'danger'
:javascript
attach_filter = function(set) {
form = $("form.bulk_edit_add_person");
var persons = form.data()["persons"];
var q = $(set).find('input[name=filter]');
var list = $(set).find('select[name=person_id]');

q.on('input', function(e) {
$(list).empty();
$(list).append($('<option>', { value: null, text: "" }));

$(persons).each(function(i) {
id = persons[i]["id"];
text = persons[i]["text"];

if (text.toUpperCase().indexOf(q.val().toUpperCase()) >= 0) {
$(list).append($('<option>', { value: id, text: text }));
}
});
});
}

$("div.peoplefilter").each(function(i) {
attach_filter(this);
});

$("#edit_selector").on('change', function () {

$("div.editable").hide();
if (this.value) {
$("div." + this.value).show();
}
});
1 change: 0 additions & 1 deletion app/views/events/_table.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,3 @@
= action_button "small danger", t('destroy'), event, data: { confirm: t('are_you_sure')}, method: :delete
- elsif current_user.is_speaker_in?(event)
= action_button "small", t('edit'), edit_cfp_event_path(event)
= render partial: 'events/modal_holder'
1 change: 1 addition & 0 deletions app/views/events/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
= render partial: 'filters', locals: { params: params }
= render 'shared/search_and_table', collection: @events
= render 'below_table'
= render partial: 'modal_holder'
32 changes: 32 additions & 0 deletions config/locales/de.yml
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ de:
review_metric: Metrik überprüfen
room: Raum
track: Track
add: Hinzufügen
add_association: "%{name} hinzufügen"
additional_resources: Zusätzliche Ressourcen
admin: Administrator
Expand Down Expand Up @@ -988,6 +989,36 @@ de:
attachments_overview: Anhänge
average_feedback: 'Durchschnittliches Feedback:'
average_speaker_feedback: 'Durchschnittliches Feedback als Sprecher:'
bulk_edit:
add_person: Person hinzufügen
add_person_confirm:
one: Möchten Sie diesem Ereignis wirklich eine Person hinzufügen?
other: Möchten Sie wirklich allen %{count}-Ereignissen eine Person hinzufügen?
set_events_confirm:
one: Möchten Sie den Status für dieses Ereignis wirklich ändern?
other: Möchten Sie den Status für alle %{count}-Ereignisse wirklich ändern?
set_events_type_confirm:
one: Möchten Sie den Typ dieses Ereignisses wirklich ändern?
other: Möchten Sie den Typ wirklich für alle %{count}-Ereignisse ändern?
set_new_event_type: Ereignistyp ändern
set_new_state: Zustand zuweisen
set_new_track: Titel zuweisen
set_track_confirm:
one: Möchten Sie den Track dieses Events wirklich ändern?
other: Möchten Sie wirklich die Spur aller %{count}-Ereignisse ändern?
show: Bearbeiten Sie diese Ereignisse
title:
one: 'Edit %{count} event:'
other: 'Bearbeiten von %{count}-Ereignissen:'
update_failed:
one: "%{count}-Bearbeitung fehlgeschlagen."
other: "%{count} Änderungen fehlgeschlagen."
update_skipped:
one: "%{count} Bearbeitung übersprungen."
other: "%{count} Änderungen übersprungen."
update_successful:
one: "%{count} Bearbeitung erfolgreich abgeschlossen."
other: "%{count} Änderungen wurden erfolgreich abgeschlossen."
cancel_event: Event absagen
cancel_event_hint: Markieren Sie dieses Event als abgesagt. Üblicherweise bedeutet dies, dass die Referenten ihren Auftritt absagen mussten.
col_toggle_rooms: 'Räume wechseln:'
Expand Down Expand Up @@ -2111,6 +2142,7 @@ de:
login: Einloggen
signup: Anmelden
update_password: Aktualisiere mein Passwort
set: einstellen
settings: Einstellungen
show: Anzeige
show_account: Konto
Expand Down
35 changes: 35 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ en:
review_metric: Review metric
room: room
track: track
add: Add
add_association: Add %{name}
additional_resources: Additional Resources
admin: Admin
Expand Down Expand Up @@ -972,6 +973,39 @@ en:
ago: "%{time_ago} ago"
all_events: All events
all_rating: All ratings
bulk_edit:
add_person: Add person
add_person_confirm:
one: Are you sure you want to add a person to this event?
other: Are you sure you want to add a person to all %{count} events?
set_new_state: Assign state
set_new_track: Assign track
set_new_event_type: Change event type
set_events_confirm:
one: Are you sure you want to change state for this event?
other: Are you sure you want to change state for all %{count} events?
set_events_type_confirm:
one: Are you sure you want to modify this event's type?
other: Are you sure you want to modify the type for all %{count} events?
set_track_confirm:
one: Are you sure you want to change the track of this event?
other: Are you sure you want to change the track of all %{count} events?
set_events_confirm:
one: you sure you want to change state for this event?
other: Are you sure you want to change state for all %{count} events?
update_successful:
one: "%{count} edit completed successfully."
other: "%{count} edits completed successfully."
update_skipped:
one: "%{count} edit skipped."
other: "%{count} edits skipped."
show: Edit these events
title:
one: 'Edit %{count} event:'
other: 'Edit %{count} events:'
update_failed:
one: "%{count} edit failed."
other: "%{count} edits failed."
attachments_overview: Attachments
average_feedback: 'Average Feedback:'
average_speaker_feedback: 'Average feedback as speaker:'
Expand Down Expand Up @@ -2092,6 +2126,7 @@ en:
login: Log in
signup: Sign up
update_password: Update my password
set: Set
settings: Settings
show: Show
show_account: Account
Expand Down
32 changes: 32 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ es:
review_metric: Revisar métrica
room: sala
track: área
add: Añadir
add_association: Agregar %{name}
additional_resources: Recursos adicionales
admin: Administración
Expand Down Expand Up @@ -1023,6 +1024,36 @@ es:
attachments_overview: Archivos adjuntos
average_feedback: 'Comentarios promedio:'
average_speaker_feedback: 'Comentarios promedio como ponente:'
bulk_edit:
add_person: Añadir persona
add_person_confirm:
one: "¿Estás seguro de que deseas agregar una persona a este evento?"
other: "¿Está seguro de que desea agregar una persona a todos los eventos %{count}?"
set_events_confirm:
one: "¿Estás seguro de que quieres cambiar el estado de este evento?"
other: "¿Está seguro de que desea cambiar el estado de todos los eventos %{count}?"
set_events_type_confirm:
one: "¿Estás seguro de que deseas modificar el tipo de este evento?"
other: "¿Está seguro de que desea modificar el tipo para todos los eventos %{count}?"
set_new_event_type: Cambiar tipo de evento
set_new_state: Asignar estado
set_new_track: Asignar pista
set_track_confirm:
one: "¿Seguro que quieres cambiar la pista de este evento?"
other: "¿Está seguro de que desea cambiar el seguimiento de todos los eventos %{count}?"
show: Edita estos eventos
title:
one: 'Editar evento %{count}:'
other: 'Editar eventos %{count}:'
update_failed:
one: La edición %{count} falló.
other: Las ediciones %{count} fallaron.
update_skipped:
one: Edición %{count} omitida.
other: Ediciones %{count} omitidas.
update_successful:
one: Edición %{count} completada con éxito.
other: Las ediciones %{count} se completaron correctamente.
cancel_event: Cancelar evento
cancel_event_hint: Marque este evento como cancelado. Por lo general, esto significa que los oradores tuvieron que cancelar su apariencia.
col_toggle_rooms: 'Conmutar habitaciones:'
Expand Down Expand Up @@ -2149,6 +2180,7 @@ es:
login: Iniciar sesión
signup: Regístrate
update_password: Actualiza mi contraseña
set: Conjunto
settings: Personalización
show: Espectáculo
show_account: Cuenta
Expand Down
Loading

0 comments on commit 92c1983

Please sign in to comment.