Skip to content

Commit 0b61401

Browse files
Sortition navigation tabs (#19)
* Add nav tabs for sortition steps * Fix lints * Fix tests
1 parent 4cb1fae commit 0b61401

File tree

12 files changed

+181
-39
lines changed

12 files changed

+181
-39
lines changed

app/controllers/decidim/stratified_sortitions/admin/stratified_sortitions_controller.rb

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,24 @@ def destroy
9999

100100
def upload_sample
101101
enforce_permission_to :upload_sample, :stratified_sortition
102+
if stratified_sortition.strata_and_substrata_configured?
103+
@stratified_sortition = stratified_sortition
104+
@sample_participants_count = @stratified_sortition.sample_participants.count
105+
@last_sample = SampleImport.where(stratified_sortition: @stratified_sortition).order(created_at: :desc).first
106+
@samples = SampleImport.where(stratified_sortition: @stratified_sortition).order(created_at: :asc)
107+
@strata_data = strata_data(@stratified_sortition)
108+
@candidates_data = candidates_data(@stratified_sortition)
109+
else
110+
redirect_to edit_stratified_sortition_path(stratified_sortition),
111+
flash: { warning: t("stratified_sortitions.upload_sample.strata_not_configured", scope: "decidim.stratified_sortitions.admin") }
112+
end
113+
end
102114

103-
@stratified_sortition = stratified_sortition
104-
@sample_participants_count = @stratified_sortition.sample_participants.count
105-
@last_sample = SampleImport.where(stratified_sortition: @stratified_sortition).order(created_at: :desc).first
106-
@samples = SampleImport.where(stratified_sortition: @stratified_sortition).order(created_at: :asc)
107-
@strata_data = strata_data(@stratified_sortition)
108-
@candidates_data = candidates_data(@stratified_sortition)
115+
def execute
116+
unless stratified_sortition.can_execute?
117+
redirect_to edit_stratified_sortition_path(stratified_sortition),
118+
flash: { warning: t("stratified_sortitions.execute.empty_sample_participants", scope: "decidim.stratified_sortitions.admin") }
119+
end
109120
end
110121

111122
def execute_stratified_sortition
@@ -118,7 +129,7 @@ def execute_stratified_sortition
118129
disposition: "attachment"
119130
else
120131
flash[:error] = @result.error
121-
redirect_to upload_sample_stratified_sortition_path(stratified_sortition)
132+
redirect_to execute_stratified_sortition_path(stratified_sortition)
122133
end
123134
end
124135

app/models/decidim/stratified_sortitions/stratified_sortition.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ def self.ransackable_scopes(_auth_object = nil)
4040
def strata_and_substrata_configured?
4141
strata.any? && strata.all? { |stratum| stratum.substrata.any? }
4242
end
43+
44+
def can_execute?
45+
strata_and_substrata_configured? && !sample_participants.empty?
46+
end
4347
end
4448
end
4549
end

app/packs/stylesheets/decidim/stratified_sortitions/admin/stratified_sortitions.scss

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,51 @@
1+
.stratified_sortition_header {
2+
border: 0;
3+
}
4+
5+
.stratified_sortition_nav {
6+
border-bottom: 2px solid #CCC;
7+
margin-bottom: 20px;
8+
overflow: visible;
9+
10+
.import-sample-btn {
11+
display: inline-flex;
12+
gap: 0.4rem;
13+
align-items: center;
14+
justify-content: center;
15+
min-width: 200px;
16+
position: relative;
17+
top: 3px;
18+
border-bottom: 2px solid transparent;
19+
color: #ccc;
20+
fill: #ccc;
21+
22+
button {
23+
all: unset;
24+
display: inline-flex;
25+
gap: 0.4rem;
26+
align-items: center;
27+
cursor: pointer;
28+
padding: 0.5rem 0;
29+
}
30+
31+
&:hover {
32+
color: rgba(21, 90, 191, 0.7);
33+
fill: rgba(21, 90, 191, 0.7);
34+
border-bottom: 2px solid rgba(21, 90, 191, 0.7);
35+
}
36+
}
37+
38+
.active {
39+
color: rgba(21, 90, 191, 1);
40+
fill: rgba(21, 90, 191, 1);
41+
border-bottom: 2px solid rgba(21, 90, 191, 1);
42+
}
43+
44+
button[disabled] {
45+
cursor: not-allowed !important;
46+
}
47+
}
48+
149
.stratum-fields,
250
.substratum-fields {
351
display: flex;
@@ -10,9 +58,6 @@
1058
}
1159
}
1260

13-
.import-sample-btn {
14-
white-space: nowrap;
15-
}
1661

1762
.example-file-census-container {
1863
padding:1em;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<div class="flex items-left stratified_sortition_nav">
2+
<%= button_to edit_stratified_sortition_path(stratified_sortition),
3+
method: :get,
4+
class: "import-sample-btn #{'active' if action_name == 'edit'}" do %>
5+
<%= icon "settings-4-line" %> <%= t("actions.configure", scope: "decidim.stratified_sortitions.admin") %>
6+
<% end %>
7+
<%= button_to upload_sample_stratified_sortition_path(stratified_sortition),
8+
method: :get,
9+
class: "import-sample-btn #{'active' if action_name == 'upload_sample'}",
10+
disabled: !stratified_sortition.strata_and_substrata_configured? do %>
11+
<%= icon "group-line" %> <%= t("actions.census_management", scope: "decidim.stratified_sortitions.admin") %>
12+
<% end %>
13+
<%= button_to execute_stratified_sortition_path(stratified_sortition),
14+
method: :get,
15+
class: "import-sample-btn #{'active' if action_name == 'execute'}",
16+
disabled: !stratified_sortition.can_execute? do %>
17+
<%= icon "play-fill" %> <%= t("actions.execute", scope: "decidim.stratified_sortitions.admin") %>
18+
<% end %>
19+
</div>

app/views/decidim/stratified_sortitions/admin/stratified_sortitions/edit.html.erb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
<% add_decidim_page_title(t(".title")) %>
2-
<div class="item_show__header">
2+
<div class="item_show__header stratified_sortition_header">
33
<h1 class="item_show__header-title">
44
<%= t(".title") %>
55
</h1>
6-
<div class="flex items-center gap-x-4">
7-
<%= button_to t("actions.census_management", scope: "decidim.stratified_sortitions.admin"),
8-
upload_sample_stratified_sortition_path(stratified_sortition),
9-
method: :get,
10-
class: "button button__sm button__secondary import-sample-btn",
11-
disabled: !stratified_sortition.strata_and_substrata_configured? %>
12-
</div>
136
</div>
7+
8+
<%= render 'navigation_menu' %>
9+
1410
<div class="item__edit item__edit-1col">
1511
<div class="item__edit-form">
1612
<%= decidim_form_for(@form, html: { class: "form-defaults form edit_stratified_sortition stratified_sortition_form_admin" }) do |f| %>
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<% add_decidim_page_title(t(".title")) %>
2+
<div class="item_show__header stratified_sortition_header">
3+
<h1 class="item_show__header-title">
4+
<%= t(".title") %>
5+
</h1>
6+
</div>
7+
<%= render 'navigation_menu' %>
8+
<div class="card">
9+
<div class="item_show__header">
10+
<%= button_to t('.execute_stratified_sortition'),
11+
execute_stratified_sortition_stratified_sortition_path(stratified_sortition),
12+
method: :post,
13+
class: 'button button__sm button__secondary' %>
14+
</div>
15+
</div>
16+
17+
<%= append_javascript_pack_tag "decidim_stratified_sortitions_admin" %>
18+
<%= append_stylesheet_pack_tag "decidim_stratified_sortitions_admin" %>

app/views/decidim/stratified_sortitions/admin/stratified_sortitions/upload_sample.html.erb

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
<% add_decidim_page_title(t(".title")) %>
2-
<div class="card">
3-
<div class="item_show__header">
4-
<%= button_to t('.execute_stratified_sortition'),
5-
execute_stratified_sortition_stratified_sortition_path(@stratified_sortition),
6-
method: :post,
7-
class: 'button button__sm button__secondary',
8-
disabled: @stratified_sortition.sample_participants.empty? %>
9-
10-
<% if @stratified_sortition.sample_participants.empty? %>
11-
<p><%= t('.execute_stratified_sortition_help') %></p>
12-
<% end %>
13-
</div>
2+
<div class="item_show__header stratified_sortition_header">
3+
<h1 class="item_show__header-title">
4+
<%= t(".title") %>
5+
</h1>
146
</div>
7+
<%= render 'navigation_menu' %>
158
<div class="card mt-12">
169
<div class="item_show__header">
1710
<h1 class="item_show__header-title">
1811
<div>
19-
<%= t(".title") %>
12+
<%= t(".upload_file") %>
2013
</div>
2114
</h1>
2215
</div>

config/locales/ca.yml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ ca:
3939
confirm_destroy: Segur que vols eliminar aquest %{name}?
4040
destroy: Esborra
4141
duplicate: Duplica
42+
execute: Executar sorteig
4243
new_stratified_sortition: "Nou sorteig estratificat"
4344
title: "Accions"
4445
census_management: Gestió cens
@@ -73,6 +74,10 @@ ca:
7374
edit:
7475
title: Editar sorteig estratificat
7576
update: Actualitzar
77+
execute:
78+
empty_sample_participants: No es pot executar el sorteig sense un cens carregat
79+
execute_stratified_sortition: Executar sorteig estratificat
80+
title: Executar sorteig estratificat
7681
form:
7782
data: Informació general
7883
description: Descripció
@@ -115,6 +120,7 @@ ca:
115120
census_file: Triar un fitxer
116121
census_file_label: Arxiu excel.csv amb les dades del cens
117122
configure_strata_first: Primer has de configurar els estrats i subestrats
123+
confirm_remove_uploaded_samples: Estàs segur que vols eliminar totes les mostres carregades?
118124
count_uploaded_files: "<b>%{count}</b> registres carregats."
119125
description: "Ha de ser un fitxer generat en excel i exportat en CSV amb las siguientes columnes:"
120126
download_template: "Descarregar plantilla CSV"
@@ -128,9 +134,10 @@ ca:
128134
no_data: Sense dades
129135
place: Lloc de naixement
130136
remove_uploaded_samples: Eliminar mostres carregades
131-
confirm_remove_uploaded_samples: Estàs segur que vols eliminar totes les mostres carregades?
137+
strata_not_configured: Primer has de configurar els estrats i subestrats
132138
target: Target
133-
title: Pujar un nou cens
139+
title: Gestionar cens
140+
upload_file: Pujar un nou cens
134141
uploaded_file: Dades del cens carregat
135142
uploaded_files: "S'han agregat els següents fitxers:"
136143
no_uploaded_files: "No hi ha fitxers carregats."

config/locales/en.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,16 @@ en:
3030
global:
3131
announcement: Announcement
3232
publish_sortitions: Publish Stratified Sortitions
33+
step:
34+
announcement: Announcement
3335
stratified_sortitions:
3436
admin:
3537
actions:
3638
configure: Configure
3739
confirm_destroy: Are you sure you want to delete this %{name}?
3840
destroy: Delete
3941
duplicate: Duplicate
42+
execute: Execute sortition
4043
new_stratified_sortition: "New Stratified Sortition"
4144
title: "Actions"
4245
census_management: Census management
@@ -58,7 +61,10 @@ en:
5861
has_problems: This stratified sortition couldn't be deleted due to related problems
5962
success: Stratified sortition successfully deleted
6063
execute:
64+
empty_sample_participants: The sortition cannot be executed without a loaded census
65+
execute_stratified_sortition: Execute stratified sortition
6166
success: Stratified sortition successfully executed
67+
title: Execute stratified sortition
6268
duplicate:
6369
error: There's been a problem duplicating this stratified sortition
6470
success: Stratified sortition successfully duplicated
@@ -119,16 +125,18 @@ en:
119125
example: "Candidate data 1,Candidate data 2,Candidate data 3,Candidate data 4,Stratum 1,Stratum 2,Stratum 3,Stratum N<br>example@example.com,D,Higher,34<br>example@example.com,E,Higher,24<br><br>. . ."
120126
execute_stratified_sortition: Execute sortition
121127
execute_stratified_sortition_help: The sortition cannot be executed until records are uploaded.
122-
filename_data: File name, on %{date}, number of records %{count}
128+
filename_data: "%{filename}, on %{date}, number of records %{count}"
123129
gender: Gender
124-
last_upload_date: The last upload was on February 24, 2025 10:41
130+
last_upload_date: The last upload was on %{date}
125131
help: The first four columns are candidate data, such as email, ID, phone, or address, and the following columns are the strata defined in the stratified sortition. Each row represents a candidate.
126132
no_data: No data
127133
place: Place of birth
128134
remove_uploaded_samples: Remove uploaded samples
129135
confirm_remove_uploaded_samples: Are you sure you want to remove all uploaded samples?
136+
strata_not_configured: You must configure strata and substrata first
130137
target: Target
131-
title: Upload a new census
138+
title: Manage census
139+
upload_file: Upload a new census
132140
uploaded_file: Census data
133141
uploaded_files: "The following files have been added:"
134142
no_uploaded_files: "No files uploaded."

config/locales/es.yml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ es:
3939
confirm_destroy: ¿Estás seguro de que quieres eliminar este %{name}?
4040
destroy: Eliminar
4141
duplicate: Duplicar
42+
execute: Ejecutar sorteo
4243
new_stratified_sortition: "Nuevo sorteo estratificado"
4344
title: "Acciones"
4445
census_management: Gestión censo
@@ -60,7 +61,10 @@ es:
6061
has_problems: Este sorteo estratificado no se pudo eliminar debido a problemas relacionados
6162
success: Sorteo estratificado eliminado con éxito
6263
execute:
64+
empty_sample_participants: No se puede ejecutar el sorteo sin un censo cargado
65+
execute_stratified_sortition: Ejecutar sorteo estratificado
6366
success: Sorteo estratificado ejecutado con éxito
67+
title: Ejecutar sorteo estratificado
6468
duplicate:
6569
error: Ha habido un problema al duplicar este sorteo estratificado
6670
success: Sorteo estratificado duplicado con éxito
@@ -121,16 +125,18 @@ es:
121125
example: "Dato candidato 1,Dato candidato 2,Dato candidato 3,Dato candidato 4,Estrato 1,Estrato 2,Estrato 3,Estrato N<br>example@example.com,D,Superiores,34<br>example@example.com,E,Superiores,24<br><br>. . ."
122126
execute_stratified_sortition: Ejecutar sorteo
123127
execute_stratified_sortition_help: El sorteo no se puede ejecutar hasta que no se carguen registros.
124-
filename_data: Nombre de archivo, el día %{date}, número de registros %{count}
128+
filename_data: "%{filename}, el día %{date}, número de registros %{count}"
125129
gender: Género
126-
last_upload_date: La última carga fue el día Febrero 24, 2025 10:41
130+
last_upload_date: La última carga fue el día %{date}
127131
help: Las cuatro primeras columnas son datos del candidato, por ejemplo correo electrónico, DNI, teléfono o dirección y las siguientes columnas son los estratos definidos en el sorteo estratificado. Cada fila representa un candidato.
128132
no_data: No hay datos
129133
place: Lugar de nacimiento
130134
remove_uploaded_samples: Eliminar muestras cargadas
131135
confirm_remove_uploaded_samples: ¿Estás seguro de que quieres eliminar todas las muestras cargadas?
136+
strata_not_configured: Primero debes configurar los estratos y subestratos
132137
target: Objetivo
133-
title: Subir un nuevo censo
138+
title: Gestionar censo
139+
upload_file: Subir un nuevo censo
134140
uploaded_file: Datos del censo
135141
uploaded_files: "Se han agregado los siguientes archivos:"
136142
no_uploaded_files: "No hay archivos cargados."

0 commit comments

Comments
 (0)