Skip to content

Commit

Permalink
Export responses by start & end date
Browse files Browse the repository at this point in the history
* associate for with a service stage
  • Loading branch information
ryanwoldatwork authored Jan 16, 2025
1 parent 73e688e commit ac68ceb
Show file tree
Hide file tree
Showing 12 changed files with 212 additions and 119 deletions.
8 changes: 8 additions & 0 deletions app/controllers/admin/forms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ def update_admin_options
def update_form_manager_options
ensure_form_manager(form: @form)
@form.update(form_admin_options_params)
set_service_stage_options
flash.now[:notice] = 'Form Manager forms options updated successfully'
end

Expand All @@ -158,6 +159,7 @@ def show
format.html do
ensure_response_viewer(form: @form) unless @form.template?
@questions = @form.ordered_questions
set_service_stage_options
@events = @events = Event.where(object_type: 'Form', object_uuid: @form.uuid).order("created_at DESC")
end

Expand Down Expand Up @@ -517,6 +519,7 @@ def form_params
:success_text,
:success_text_heading,
:service_id,
:service_stage_id,
# PRA Info
:omb_approval_number,
:expiration_date,
Expand Down Expand Up @@ -588,10 +591,15 @@ def form_admin_options_params
:omb_approval_number,
:expiration_date,
:service_id,
:service_stage_id,
:enforce_new_submission_validations,
)
end

def set_service_stage_options
@service_stage_options = @form.service.present? ? @form.service.service_stages.order(:position, :name).map { |s| [s.name, s.id] } : []
end

# Add rules for AASM state transitions here
def transition_state
Event.log_event(Event.names[:form_published], 'Form', @form.uuid, "Form #{@form.name} published at #{DateTime.now}", current_user.id) if (params['form']['aasm_state'] == 'published') && !@form.published?
Expand Down
9 changes: 8 additions & 1 deletion app/controllers/admin/service_stages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ def index
else
ensure_service_manager_permissions
@service_stages = ServiceStage.order(:position)
render :unscoped_index
end
respond_to do |format|
format.html {
render :index
}
format.json {
render json: @service_stages
}
end
end

Expand Down
41 changes: 41 additions & 0 deletions app/views/admin/forms/_form_manager_options.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,16 @@
<%= f.select :service_id, form.organization.services.includes(:organization).order("organizations.name", :name).map { |h| ["#{h.organization.name} - #{h.name}", h.id] }, { include_blank: true }, class: "usa-select" %>
</div>

<div class="field">
<%= f.label :service_stage_id, "Service Stage", class: "usa-label" %>
<small>
Select a Service in order to specify a Service Stage.
<%= link_to "Service Stage", admin_services_path, target: "_blank" %>.
</small>

<%= f.select :service_stage_id, options_for_select(service_stage_options, selected: form.try(:service_stage_id)), { include_blank: true }, class: "usa-select" %>
</div>

<div class="field">
<%= f.label :audience, nil, class: "usa-label" %>
<small>
Expand Down Expand Up @@ -129,3 +139,34 @@
</div>
<% end %>
<% end %>

<script>
document.addEventListener("DOMContentLoaded", () => {
const serviceSelect = document.getElementById("form_service_id");
const serviceStageSelect = document.getElementById("form_service_stage_id");

serviceSelect.addEventListener("change", () => {
const serviceId = serviceSelect.value;

// Clear the service stage dropdown
serviceStageSelect.innerHTML = '<option value="">Select a Service Stage</option>';

if (serviceId) {
fetch(`/admin/services/${serviceId}/service_stages.json`)
.then((response) => response.json())
.then((data) => {
const stages = data.data
stages.forEach((stage) => {
const option = document.createElement("option");
option.value = stage.id;
option.textContent = stage.attributes.name;
serviceStageSelect.appendChild(option);
});
})
.catch((error) => console.error("Error fetching service stages:", error));
} else {
serviceStageSelect.innerHTML = '<option value="">Select a Service Stage</option>';
}
});
});
</script>
9 changes: 1 addition & 8 deletions app/views/admin/forms/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,6 @@
</div>

<div class="well">
<div class="grid-row grid-gap-md">
<div class="tablet:grid-col-6">
<div class="text-uppercase font-body-3xs">
Form information
</div>
</div>
</div>
<div class="grid-row grid-gap-md">
<div class="tablet:grid-col-6">
<div>
Expand Down Expand Up @@ -226,7 +219,7 @@
<%= render 'admin/forms/admin_options', form: @form %>
</div>
<div class="form-manager-options">
<%= render 'admin/forms/form_manager_options', form: @form %>
<%= render 'admin/forms/form_manager_options', form: @form, service_stage_options: @service_stage_options %>
</div>
<% end %>
</div>
Expand Down
2 changes: 1 addition & 1 deletion app/views/admin/forms/update_form_manager_options.js.erb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
$(".form-manager-options").html("<%= j(render('admin/forms/form_manager_options', form: @form )) %>");
$(".form-manager-options").html("<%= j(render('admin/forms/form_manager_options', form: @form, service_stage_options: @service_stage_options )) %>");
201 changes: 108 additions & 93 deletions app/views/admin/submissions/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,90 +2,94 @@
<div id="submissions_table">
<%= render 'admin/submissions/submissions', submissions: submissions, form: form %>
</div>
<div class="font-sans-lg margin-top-3 padding-top-2 border-top border-base-lighter">

<div class="font-sans-lg margin-top-3 padding-top-2 border-top border-base-lighter margin-bottom-3">
Export responses
</div>
<div>
<%= form_with(url: export_admin_form_path(@form), class: "usa-form", method: :get, local: true) do %>
<div class="usa-form-group display-inline-block">
<label for="fiscal_year">Select Fiscal Year:</label>
<select id="fiscal_year" class="usa-select" name="fiscal_year" onchange="updateExportLink()">
<option value="all" data-start="2019-10-01" data-end="2025-09-30">All</option>
<option value="2025" data-start="2024-10-01" data-end="2025-09-30">2025</option>
<option value="2024" data-start="2023-10-01" data-end="2024-09-30">2024</option>
<option value="2023" data-start="2022-10-01" data-end="2023-09-30">2023</option>
<option value="2022" data-start="2021-10-01" data-end="2022-09-30">2022</option>
<option value="2021" data-start="2020-10-01" data-end="2021-09-30">2021</option>
<option value="2020" data-start="2019-10-01" data-end="2020-09-30">2020</option>
</select>

<input type="hidden" id="start_date" name="start_date" value="2019-10-01">
<input type="hidden" id="end_date" name="end_date" value="2025-09-30">
</div>
<div class="usa-form-group display-inline-block">
<button type="submit" class="usa-button usa-button--outline">Export</button>
</div>
<% end %>
</div>
<%- if form.kind == "a11_v2" %>
<div class="margin-top-6 margin-top-3 padding-top-2 border-top border-base-lighter a11-fiscal-year">
<span class="usa-tag">
A-11 v2 Reporting
</span>
<br>
<br>
<div class="font-sans-lg">
Export A11-v2 Responses
</div>
<%= form_with(url: export_a11_v2_submissions_admin_form_url(@form, start_date: "2019-10-01"), class: "usa-form", method: :get, local: true) do %>
<div
class="usa-form-group display-inline-block">
<label for="fiscal_year">Select Fiscal Year:</label>
<select id="a11-fiscal-year" class="usa-select" name="fiscal_year" onchange="updateA11ExportLink()">
<option value="all" data-start="2019-10-01" data-end="2025-09-30">All</option>
<option value="2025" data-start="2024-10-01" data-end="2025-09-30">2025</option>
<option value="2024" data-start="2023-10-01" data-end="2024-09-30">2024</option>
<option value="2023" data-start="2022-10-01" data-end="2023-09-30">2023</option>
<option value="2022" data-start="2021-10-01" data-end="2022-09-30">2022</option>
<option value="2021" data-start="2020-10-01" data-end="2021-09-30">2021</option>
<option value="2020" data-start="2019-10-01" data-end="2020-09-30">2020</option>
</select>

<input type="hidden" id="a11_start_date" name="start_date" value="2019-10-01">
<input type="hidden" id="a11_end_date" name="end_date" value="2025-09-30">
</div>
<div class="usa-form-group display-inline-block">
<button type="submit" class="usa-button usa-button--outline">Export</button>
<form
class="usa-form"
id="export-buttons"
>
<div class="usa-form-group">
<label class="usa-label"
id="start-date-label"
for="start-date"
>Start Date</label>
<div class="usa-hint" id="start-date-hint">mm/dd/yyyy</div>
<div class="usa-date-picker2"
data-default-value="<%= Date.today.to_s %>">
<input
class="usa-input"
id="start-date"
name="start_date"
aria-labelledby="start-date-label"
aria-describedby="start-date-hint"
type="date"
value="<%= FiscalYear.first_day_of_fiscal_quarter(Date.today) %>"
/>
</div>
<% end %>
</div>

<div class="margin-top-6 form-and-a11-fiscal-year">
<div class="font-sans-lg">
Export Form and A11-v2 Responses
<div
class="usa-form-group">
<label class="usa-label"
id="end-date-label"
for="end-date">End Date</label>
<div class="usa-hint" id="end-date-hint">mm/dd/yyyy</div>
<div class="usa-date-picker2"
data-default-value="<%= Date.today.to_s %>">
<input
class="usa-input"
id="end-date"
name="end_date"
aria-labelledby="end-date-label"
aria-describedby="end-date-hint"
type="date"
value="<%= Date.today %>"
/>
</div>
<%= form_with(url: export_form_and_a11_v2_submissions_admin_form_url(@form, start_date: "2019-10-01"), class: "usa-form", method: :get, local: true) do %>
<div
class="usa-form-group display-inline-block">
<label for="fiscal_year">Select Fiscal Year:</label>
<select id="form-and-a11-fiscal-year" class="usa-select" name="fiscal_year" onchange="updateA11ExportLink()">
<option value="all" data-start="2019-10-01" data-end="2025-09-30">All</option>
<option value="2025" data-start="2024-10-01" data-end="2025-09-30">2025</option>
<option value="2024" data-start="2023-10-01" data-end="2024-09-30">2024</option>
<option value="2023" data-start="2022-10-01" data-end="2023-09-30">2023</option>
<option value="2022" data-start="2021-10-01" data-end="2022-09-30">2022</option>
<option value="2021" data-start="2020-10-01" data-end="2021-09-30">2021</option>
<option value="2020" data-start="2019-10-01" data-end="2020-09-30">2020</option>
</select>
</div>

<input type="hidden" id="form_and_a11_start_date" name="start_date" value="2019-10-01">
<input type="hidden" id="form_and_a11_end_date" name="end_date" value="2025-09-30">
</div>
<div class="usa-form-group display-inline-block">
<button type="submit" class="usa-button usa-button--outline">Export</button>
</div>
<% end %>
<div class="usa-button-group">
<button type="submit"
class="usa-button"
name="download_type"
formaction="<%= export_admin_form_path(@form) %>"
value="standard_form_data"
disabled="true"
>
Download
</button>
</div>
<%- if form.kind == "a11_v2" %>
<div>
<button type="submit"
class="usa-button usa-button--outline"
name="download_type"
formaction="<%= export_a11_v2_submissions_admin_form_path(@form) %>"
value="a11_data"
disabled="true"
>
Download A11-v2 Responses
</button>
<div class="margin-top-1 text-base font-sans-2xs">for A-11 reporting</div>
</div>
<% end -%>
<div>
<button type="submit"
class="usa-button usa-button--secondary"
name="download_type"
formaction="<%= export_form_and_a11_v2_submissions_admin_form_path(@form) %>"
value="combined_a11_and_form_data"
disabled="true"
>
Download A11-v2 + Form Responses
</button>
<div class="margin-top-1 text-base font-sans-2xs">to see form and A-11 responses together</div>
</div>
<% end %>
</form>
<% else %>
<div class="usa-alert usa-alert--info">
<div class="usa-alert__body">
Expand All @@ -108,24 +112,6 @@
}
}

function updateExportLink() {
const selectedOption = document.getElementById('fiscal_year').selectedOptions[0];
document.getElementById('start_date').value = selectedOption.getAttribute('data-start');
document.getElementById('end_date').value = selectedOption.getAttribute('data-end');
}

function updateA11ExportLink() {
const selectedOption = document.getElementById('a11-fiscal-year').selectedOptions[0];
document.getElementById('a11_start_date').value = selectedOption.getAttribute('data-start');
document.getElementById('a11_end_date').value = selectedOption.getAttribute('data-end');
}

function updateA11ExportLink() {
const selectedOption = document.getElementById('form-and-a11-fiscal-year').selectedOptions[0];
document.getElementById('form_and_a11_start_date').value = selectedOption.getAttribute('data-start');
document.getElementById('form_and_a11_end_date').value = selectedOption.getAttribute('data-end');
}

// When mousing over a cell with long text, show it all
// When mousing out, display 50 characters max
$(function() {
Expand All @@ -136,5 +122,34 @@
$(".truncate").on("mouseout", function() {
$(this).text(truncate($(this).attr("fulltext"), 50));
});

const startDateInput = document.getElementById('start-date');
const endDateInput = document.getElementById('end-date');
const buttons = document.querySelectorAll('form#export-buttons button');

function toggleButtons() {
const startDateValue = new Date(startDateInput.value);
const endDateValue = new Date(endDateInput.value);

let isValid = true;

if (!startDateInput.value || !endDateInput.value) {
isValid = false; // Both dates must be filled
} else if (endDateValue <= startDateValue) {
isValid = false; // End date must be greater than start date
}

buttons.forEach((button) => {
button.disabled = !isValid;
});
}

if (startDateInput && endDateInput) {
// Add event listeners to both date inputs
startDateInput.addEventListener('input', toggleButtons);
endDateInput.addEventListener('input', toggleButtons);
toggleButtons()
}

});
</script>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<fieldset class="usa-fieldset radios margin-top-3">
<fieldset class="usa-fieldset radios margin-top-2">
<%= render 'components/question_title_legend', question: question %>
<div class="question-options">
<% question.question_options.each_with_index do |option, index| %>
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20250115175322_add_service_stage_to_forms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddServiceStageToForms < ActiveRecord::Migration[7.2]
def change
add_column :forms, :service_stage_id, :integer, default: nil
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.2].define(version: 2025_01_10_215441) do
ActiveRecord::Schema[7.2].define(version: 2025_01_15_175322) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

Expand Down Expand Up @@ -310,6 +310,7 @@
t.string "audience", default: "public", comment: "indicates whether a form is intended for a public or internal audience"
t.string "short_uuid", limit: 8
t.boolean "enforce_new_submission_validations", default: true
t.integer "service_stage_id"
t.index ["legacy_touchpoint_id"], name: "index_forms_on_legacy_touchpoint_id"
t.index ["legacy_touchpoint_uuid"], name: "index_forms_on_legacy_touchpoint_uuid"
t.index ["organization_id"], name: "index_forms_on_organization_id"
Expand Down
Loading

0 comments on commit ac68ceb

Please sign in to comment.