From f8c2adaf790091a9b231dc361d0c8e05dacc925e Mon Sep 17 00:00:00 2001 From: Ryan Wold Date: Tue, 21 Nov 2023 09:50:56 -0800 Subject: [PATCH 1/2] upload settings --- .env.sample | 8 +++++++- app/controllers/admin/cx_collection_details_controller.rb | 8 +++++++- app/views/components/forms/edit/_builder.html.erb | 2 +- .../forms/edit/question_types/_radio_buttons.html.erb | 5 ++++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.env.sample b/.env.sample index c0e0bbbd5..b1389c462 100644 --- a/.env.sample +++ b/.env.sample @@ -48,12 +48,18 @@ RAILS_ACTIVE_RECORD_KEY_DERIVATION_SALT= # Redis cache store REDIS_URL=redis://localhost:6379/1 -# For image uploads +# S3 Public Bucket for organization logo uploads S3_AWS_ACCESS_KEY_ID= S3_AWS_SECRET_ACCESS_KEY= S3_AWS_BUCKET_NAME= S3_AWS_REGION= +# S3 Private Bucket for Collection uploads +S3_UPLOADS_AWS_ACCESS_KEY_ID= +S3_UPLOADS_AWS_BUCKET_NAME= +S3_UPLOADS_AWS_REGION= +S3_UPLOADS_AWS_SECRET_ACCESS_KEY= + # For seeding the database with Admin users TOUCHPOINTS_ADMIN_EMAILS=comma-separated-emails diff --git a/app/controllers/admin/cx_collection_details_controller.rb b/app/controllers/admin/cx_collection_details_controller.rb index 7b5b48437..db75e69c5 100644 --- a/app/controllers/admin/cx_collection_details_controller.rb +++ b/app/controllers/admin/cx_collection_details_controller.rb @@ -61,7 +61,13 @@ def upload_csv file = params[:file] # Assuming the file comes from a form field named 'file' bucket = ENV.fetch("S3_UPLOADS_AWS_BUCKET_NAME") - s3 = Aws::S3::Resource.new + s3 = Aws::S3::Resource.new( + region: ENV.fetch("S3_UPLOADS_AWS_REGION"), + credentials: Aws::Credentials.new( + ENV.fetch("S3_UPLOADS_AWS_ACCESS_KEY_ID"), + ENV.fetch("S3_UPLOADS_AWS_SECRET_ACCESS_KEY") + ) + ) key = "cx_data_collections/cx-upload-#{Time.now.to_i}-#{file.original_filename}}" obj = s3.bucket(bucket).object(file.original_filename) # Upload the file diff --git a/app/views/components/forms/edit/_builder.html.erb b/app/views/components/forms/edit/_builder.html.erb index ecdd00221..18272af7c 100644 --- a/app/views/components/forms/edit/_builder.html.erb +++ b/app/views/components/forms/edit/_builder.html.erb @@ -1,7 +1,7 @@ <% @instruction_text_limit = 1500 %> <% @disclaimer_text_limit = 500 %> <% @tabindex = 0 %> -
+
<%= render 'admin/forms/logo_display', { form: form } %>

diff --git a/app/views/components/forms/edit/question_types/_radio_buttons.html.erb b/app/views/components/forms/edit/question_types/_radio_buttons.html.erb index 03c807fe1..44690c200 100644 --- a/app/views/components/forms/edit/question_types/_radio_buttons.html.erb +++ b/app/views/components/forms/edit/question_types/_radio_buttons.html.erb @@ -1,4 +1,7 @@ -
+
<%= question.text %> <%= render 'components/question_title', question: question, form_builder: true %>
From 479109669a14e9fa20e7d4546d10abf753d54dde Mon Sep 17 00:00:00 2001 From: Ryan Wold <64987852+ryanwoldatwork@users.noreply.github.com> Date: Mon, 11 Dec 2023 16:15:15 -0800 Subject: [PATCH 2/2] update gems * update service channels * render action cable tag * update cx text copy --- Gemfile.lock | 78 +++++++++---------- app/controllers/admin/users_controller.rb | 2 +- app/models/form.rb | 2 +- .../cx_collection_details/_form.html.erb | 7 +- .../cx_collection_details/upload.html.erb | 16 +--- app/views/admin/cx_collections/_form.html.erb | 2 +- app/views/admin/cx_collections/show.html.erb | 37 +++++---- .../admin/service_providers/_results.html.erb | 2 + app/views/admin/submissions/index.html.erb | 1 + .../components/forms/edit/_builder.html.erb | 2 +- .../question_types/_icon_checkboxes.html.erb | 12 ++- app/views/layouts/application.html.erb | 1 + 12 files changed, 86 insertions(+), 76 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 45c08d3cd..c7fb84a58 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,24 +100,24 @@ GEM acts-as-list (0.1.2) acts-as-taggable-on (10.0.0) activerecord (>= 6.1, < 7.2) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) ast (2.4.2) - aws-eventstream (1.2.0) - aws-partitions (1.853.0) + aws-eventstream (1.3.0) + aws-partitions (1.864.0) aws-record (2.13.0) aws-sdk-dynamodb (~> 1, >= 1.85.0) - aws-sdk-core (3.187.0) - aws-eventstream (~> 1, >= 1.0.2) + aws-sdk-core (3.190.0) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-dynamodb (1.96.0) - aws-sdk-core (~> 3, >= 3.184.0) + aws-sdk-dynamodb (1.98.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) - aws-sdk-kms (1.72.0) - aws-sdk-core (~> 3, >= 3.184.0) + aws-sdk-kms (1.74.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) aws-sdk-rails (3.9.0) aws-record (~> 2) @@ -127,23 +127,23 @@ GEM aws-sessionstore-dynamodb (~> 2) concurrent-ruby (~> 1) railties (>= 5.2.0) - aws-sdk-s3 (1.136.0) - aws-sdk-core (~> 3, >= 3.181.0) + aws-sdk-s3 (1.141.0) + aws-sdk-core (~> 3, >= 3.189.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.6) - aws-sdk-ses (1.56.0) - aws-sdk-core (~> 3, >= 3.184.0) + aws-sigv4 (~> 1.8) + aws-sdk-ses (1.58.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) aws-sdk-sesv2 (1.41.0) aws-sdk-core (~> 3, >= 3.184.0) aws-sigv4 (~> 1.1) - aws-sdk-sqs (1.67.0) - aws-sdk-core (~> 3, >= 3.184.0) + aws-sdk-sqs (1.69.0) + aws-sdk-core (~> 3, >= 3.188.0) aws-sigv4 (~> 1.1) aws-sessionstore-dynamodb (2.1.0) aws-sdk-dynamodb (~> 1, >= 1.85.0) rack (~> 2) - aws-sigv4 (1.6.1) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) bcrypt (3.1.20) @@ -152,7 +152,7 @@ GEM bindex (0.8.1) bootsnap (1.17.0) msgpack (~> 1.2) - brakeman (6.0.1) + brakeman (6.1.0) builder (3.2.4) bullet (7.1.4) activesupport (>= 3.0.0) @@ -173,7 +173,7 @@ GEM nokogiri (~> 1.6) rubyzip (~> 1.1) tilt (>= 1.4) - carrierwave (3.0.4) + carrierwave (3.0.5) activemodel (>= 6.0.0) activesupport (>= 6.0.0) addressable (~> 2.6) @@ -210,11 +210,11 @@ GEM drb (2.2.0) ruby2_keywords erubi (1.12.0) - excon (0.104.0) - factory_bot (6.2.1) + excon (0.105.0) + factory_bot (6.4.2) activesupport (>= 5.0.0) - factory_bot_rails (6.2.0) - factory_bot (~> 6.2.0) + factory_bot_rails (6.4.2) + factory_bot (~> 6.4) railties (>= 5.0.0) faraday (0.17.6) multipart-post (>= 1.2, < 3) @@ -249,7 +249,7 @@ GEM activesupport (>= 6.0.0) railties (>= 6.0.0) io-console (0.6.0) - irb (1.9.0) + irb (1.10.1) rdoc reline (>= 0.3.8) jbuilder (2.11.5) @@ -260,7 +260,7 @@ GEM rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (2.6.3) + json (2.7.1) json-jwt (1.15.3) activesupport (>= 4.2) aes_key_wrap @@ -310,7 +310,7 @@ GEM multi_xml (0.6.0) multipart-post (2.3.0) mutex_m (0.2.0) - net-imap (0.4.5) + net-imap (0.4.7) date net-protocol net-pop (0.1.2) @@ -321,11 +321,11 @@ GEM net-protocol newrelic_rpm (9.6.0) base64 - nio4r (2.6.0) - nokogiri (1.15.4) + nio4r (2.7.0) + nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.15.4-x86_64-darwin) + nokogiri (1.15.5-x86_64-darwin) racc (~> 1.4) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) @@ -370,7 +370,7 @@ GEM rack (>= 2.0.0) rack-protection (3.1.0) rack (~> 2.2, >= 2.2.4) - rack-session (1.0.1) + rack-session (1.0.2) rack (< 3) rack-test (2.1.0) rack (>= 1.3) @@ -420,16 +420,16 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - rdoc (6.6.0) + rdoc (6.6.1) psych (>= 4.0.0) redis (5.0.8) redis-client (>= 0.17.0) - redis-client (0.18.0) + redis-client (0.19.0) connection_pool redis-namespace (1.11.0) redis (>= 4) - regexp_parser (2.8.2) - reline (0.4.0) + regexp_parser (2.8.3) + reline (0.4.1) io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) @@ -446,7 +446,7 @@ GEM rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (6.0.3) + rspec-rails (6.1.0) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -457,7 +457,7 @@ GEM rspec-support (3.12.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.57.2) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) @@ -465,7 +465,7 @@ GEM rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.1, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) rubocop-ast (1.30.0) @@ -528,7 +528,7 @@ GEM ssrf_filter (1.1.2) stimulus-rails (1.3.0) railties (>= 6.0.0) - stringio (3.0.9) + stringio (3.1.0) thor (1.3.0) tilt (2.3.0) timeout (0.4.1) diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 3abacce18..10435d61b 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -38,7 +38,7 @@ def inactivate! end def show - @forms = @user.forms + @forms = @user.forms.order(:status, :name) @websites = Website.where(site_owner_email: @user.email) @collections = @user.collections.order(:year, :quarter) @user_events = Event.limit(100).where(user_id: @user.id).order('created_at DESC') diff --git a/app/models/form.rb b/app/models/form.rb index 0d8855c4b..66eaaa608 100644 --- a/app/models/form.rb +++ b/app/models/form.rb @@ -17,7 +17,7 @@ class Form < ApplicationRecord has_many :users, through: :user_roles, primary_key: :form_id validates :name, presence: true - validates :disclaimer_text, length: { in: 0..500, allow_blank: true } + validates :disclaimer_text, length: { in: 0..1000, allow_blank: true } validates :delivery_method, presence: true validates :anticipated_delivery_count, numericality: true, allow_nil: true validate :omb_number_with_expiration_date diff --git a/app/views/admin/cx_collection_details/_form.html.erb b/app/views/admin/cx_collection_details/_form.html.erb index a2ec1aaea..35b1266f4 100644 --- a/app/views/admin/cx_collection_details/_form.html.erb +++ b/app/views/admin/cx_collection_details/_form.html.erb @@ -40,7 +40,7 @@
Tell us how you deployed the survey. What is the channel you used to reach your respondents?
- <%= form.select :channel, [:computer, :mobile, :paper, :in_person], { prompt: "What type of response channel?" }, class: "usa-select" %> + <%= form.select :channel, Service.channels, { prompt: "What type of response channel?" }, class: "usa-select" %>
@@ -112,7 +112,8 @@
<%= form.label :volume_of_respondents, class: "usa-label" %>
- This is your best estimate of the number of respondents who completed the feedback survey. In general, this should be a count of the number of responses your are responses. + This is your best estimate of the number of respondents who completed the post-transaction customer feedback survey. + In general, this should be a count of the number of responses for your survey.
<%= form.number_field :volume_of_respondents, class: "usa-input" %>
@@ -128,7 +129,7 @@

- Creating this Collection Detail will allow you to submit the corresponding survey data as a CSV file on the next page. + Creating this collection detail will allow you to submit the corresponding survey data as a CSV file on the next page. You may still edit after you have created the collection detail.

diff --git a/app/views/admin/cx_collection_details/upload.html.erb b/app/views/admin/cx_collection_details/upload.html.erb index 6a107a060..850c85fb0 100644 --- a/app/views/admin/cx_collection_details/upload.html.erb +++ b/app/views/admin/cx_collection_details/upload.html.erb @@ -19,19 +19,11 @@

- Before you attach your survey dataset below. + Before you attach your survey dataset below,
- Please review this checklist and make sure the excel meet these formatting requirements: -
- Is it named correctly. Examples - -
- Is it a CSV formatted file? -
- Are the 14 columns? -
- Is each row a response to the feedback survey. - Does it generally look like - <%= link_to "this", "https://github.com/gsa/touchpoints/wiki/" %>? + please review + <%= link_to "this checklist", "https://github.com/GSA/touchpoints/wiki/CX‐Data‐Collection‐Data‐Format", target: "_blank" %> + and make sure the CSV upload file is in the correct format.

<%= form_with url: post_csv_admin_cx_collection_detail_path, method: :post, local: true, multipart: true do |form| %> diff --git a/app/views/admin/cx_collections/_form.html.erb b/app/views/admin/cx_collections/_form.html.erb index d59d581d6..caa1a914c 100644 --- a/app/views/admin/cx_collections/_form.html.erb +++ b/app/views/admin/cx_collections/_form.html.erb @@ -27,7 +27,7 @@
<%= form.label :service_provider_id, "HISP Service Provider", class: "usa-label" %> - <%= form.select :service_provider_id, ServiceProvider.all.includes(:organization).order("organizations.abbreviation", :name).map { |h| ["#{h.organization.abbreviation} - #{h.organization.name} - #{h.name}", h.id] }, { include_blank: true }, { class: "usa-select", required: true } %> + <%= form.select :service_provider_id, ServiceProvider.active.includes(:organization).order("organizations.abbreviation", :name).map { |h| ["#{h.organization.abbreviation} - #{h.organization.name} - #{h.name}", h.id] }, { include_blank: true }, { class: "usa-select", required: true } %>
diff --git a/app/views/admin/cx_collections/show.html.erb b/app/views/admin/cx_collections/show.html.erb index 9cbc43649..349c80204 100644 --- a/app/views/admin/cx_collections/show.html.erb +++ b/app/views/admin/cx_collections/show.html.erb @@ -41,14 +41,11 @@

- CX Customer Experience reporting is described in - OMB Circular A-11, Section 280. -

-

- Each quarter, OMB coordinates this data collection from all HISPs. - This data will be summarized and reported on - performance.gov/cx. + This collection record will help HISPs report survey(s) corresponding to the selected designated service. + This data will be reviewed, summarized, and reported on performance.gov/cx.

@@ -66,6 +63,10 @@ <%= label_tag :service_provider, "Service Provider", class: "usa-label" %> <%= link_to @cx_collection.service_provider.name, admin_service_provider_path( @cx_collection.service_provider) %>

+

+ <%= label_tag :service, "Service", class: "usa-label" %> + <%= link_to @cx_collection.service.name, admin_service_path( @cx_collection.service) %> +

<%= label_tag :user, nil, class: "usa-label" %> <%= link_to_if performance_manager_permissions?, @cx_collection.user.email, admin_user_path(@cx_collection.user) %> @@ -98,7 +99,8 @@

- Add a reporting page for each touchpoint available within a service. + For each service, HISP may collect post-transaction customer feedback at multiple touchpoints within a service. + Report each set of survey data below by adding one or more detail records.

@@ -193,15 +195,22 @@

- Submitting this Data Collection will send an email - to <%= ENV.fetch("TOUCHPOINTS_ADMIN_EMAILS").split(',').to_sentence %> - who will - 1. review the data, then - 2. contact you via email - prior to publishing data on performance.gov. + Submitting this data collection will trigger a notification for the OMB CX Team. + Your submission will be reviewed and given a + rating. + Only collections with Green rating are published on + performance.gov/cx.

+

+ Please only report post-transaction feedback survey(s) with the three required questions and in the correct CSV format, as described in + OMB Circular A-11, Section 280. +

+

+ Please contact your HISP Portfolio Manager if HISP has any concerns about meeting the post-transaction feedback survey and reporting requirements. +


<%= link_to submit_admin_cx_collection_path(@cx_collection), class: "usa-button full-width", method: "post", data: { confirm: 'Are you sure?' } do %> Submit this Data Collection diff --git a/app/views/admin/service_providers/_results.html.erb b/app/views/admin/service_providers/_results.html.erb index d8fb553f8..f4bbb4db4 100644 --- a/app/views/admin/service_providers/_results.html.erb +++ b/app/views/admin/service_providers/_results.html.erb @@ -1,6 +1,7 @@ + @@ -11,6 +12,7 @@ <% @service_providers.each do |service_provider| %> + diff --git a/app/views/admin/submissions/index.html.erb b/app/views/admin/submissions/index.html.erb index 0f1827ca8..f3b4302d6 100644 --- a/app/views/admin/submissions/index.html.erb +++ b/app/views/admin/submissions/index.html.erb @@ -15,6 +15,7 @@ <%= link_to "Export FY2021", export_submissions_admin_form_url(form, start_date: "2020-10-01", end_date: "2021-09-30", format: "json"), class: "usa-button usa-button--outline export-btn" %> <%= link_to "Export FY2022", export_submissions_admin_form_url(form, start_date: "2021-10-01", end_date: "2022-09-30", format: "json"), class: "usa-button usa-button--outline export-btn" %> <%= link_to "Export FY2023", export_submissions_admin_form_url(form, start_date: "2022-10-01", end_date: "2023-09-30", format: "json"), class: "usa-button usa-button--outline export-btn" %> + <%= link_to "Export FY2024", export_submissions_admin_form_url(form, start_date: "2023-10-01", end_date: "2024-09-30", format: "json"), class: "usa-button usa-button--outline export-btn" %>

<% else %>
diff --git a/app/views/components/forms/edit/_builder.html.erb b/app/views/components/forms/edit/_builder.html.erb index 18272af7c..457dc8d07 100644 --- a/app/views/components/forms/edit/_builder.html.erb +++ b/app/views/components/forms/edit/_builder.html.erb @@ -1,5 +1,5 @@ <% @instruction_text_limit = 1500 %> -<% @disclaimer_text_limit = 500 %> +<% @disclaimer_text_limit = 1000 %> <% @tabindex = 0 %>
<%= render 'admin/forms/logo_display', { form: form } %> diff --git a/app/views/components/forms/question_types/_icon_checkboxes.html.erb b/app/views/components/forms/question_types/_icon_checkboxes.html.erb index 5316c2d69..e9c440910 100644 --- a/app/views/components/forms/question_types/_icon_checkboxes.html.erb +++ b/app/views/components/forms/question_types/_icon_checkboxes.html.erb @@ -22,13 +22,17 @@ <% if option.value == "effectiveness" %> "> <% elsif option.value == "efficiency" %> - "> + "> <% elsif option.value == "ease" %> - "> + "> <% elsif option.value == "transparency" %> - "> + "> + <% elsif option.value == "humanity" %> + "> + <% elsif option.value == "employee" %> + "> <% else %> - "> + "> <% end %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 5a376cf1b..7139eb8bd 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -14,6 +14,7 @@ <%= csrf_meta_tags %> <%= csp_meta_tag %> + <%= action_cable_meta_tag %> <%= favicon_link_tag asset_path('favicon.ico') %> <%= stylesheet_link_tag 'application', media: 'all', integrity: true %> <%= javascript_include_tag 'app', integrity: true %>
Active Organization Name # of services
<%= !service_provider.inactive %> <%= service_provider.organization.name %> <%= link_to service_provider.name, admin_service_provider_path(service_provider) %> <%= service_provider.services.size %>