diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index a870b1ef..704c97ac 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -50,4 +50,22 @@ $(document).on("turbolinks:load", function () { .classList.add("active-topic__hidden"); }); } + + var changeNotificationDateLink = document.querySelector("#change-notification-date-link"); + if (changeNotificationDateLink) { + changeNotificationDateLink.addEventListener("click", function (e) { + e.preventDefault(); + $("#change-notification-date").removeClass("sdn-appear-link-hide"); + $("#deadline-notifications-info").addClass("sdn-appear-link-hide"); + }); + } + + var changeNotificationDateClose = document.querySelector("#change-notification-date-close"); + if (changeNotificationDateClose) { + changeNotificationDateClose.addEventListener("click", function (e) { + e.preventDefault(); + $("#change-notification-date").addClass("sdn-appear-link-hide"); + $("#deadline-notifications-info").removeClass("sdn-appear-link-hide"); + }); + } }); diff --git a/app/controllers/admin/steps_controller.rb b/app/controllers/admin/steps_controller.rb index d7e80c2c..d63c7cad 100644 --- a/app/controllers/admin/steps_controller.rb +++ b/app/controllers/admin/steps_controller.rb @@ -83,7 +83,8 @@ def step_params :position, :app_url, :app_link_text, - :type + :type, + :waiting_time ) end end diff --git a/app/controllers/deadline_notifications_controller.rb b/app/controllers/deadline_notifications_controller.rb new file mode 100644 index 00000000..57354ea1 --- /dev/null +++ b/app/controllers/deadline_notifications_controller.rb @@ -0,0 +1,54 @@ +class DeadlineNotificationsController < ApplicationController + before_action :set_journey_and_step + def subscribe_to_deadline_notification + notification_date = params[:notification_date] ? Date.parse(params[:notification_date]) : nil + notification_date ||= Date.new(params[:year].to_i, params[:month].to_i, params[:day].to_i) + + @user_journey = UserJourney.order(id: :desc).find_by(user: current_user, journey: @journey) + @user_step = @user_journey.user_steps.find_by(step: @current_step) + + @user_step.update(to_be_notified_at: notification_date) + respond_to do |format| + format.html do + redirect_to [@journey, @current_step] + end + format.js do + render 'deadline_notifications_updated' + end + end + + rescue Date::Error => e + respond_to do |format| + format.html do + redirect_to [@journey, @current_step] + end + format.js do + render 'deadline_notifications_update_error' + end + end + end + + def unsubscribe_deadline_notification + @user_journey = UserJourney.order(id: :desc).find_by(user: current_user, journey: @journey) + @user_step = @user_journey.user_steps.find_by(step: @current_step) + + @user_step.update(to_be_notified_at: nil) + + respond_to do |format| + format.html do + redirect_to [@journey, @current_step] + end + format.js do + render 'deadline_notifications_updated' + end + end + + end + + private + + def set_journey_and_step + @journey = Journey.published.find_by!(slug: params[:journey_id]) + @current_step = @journey.steps.find_by!(slug: params[:id]) + end +end diff --git a/app/controllers/steps_controller.rb b/app/controllers/steps_controller.rb index bf86125c..ba40fb96 100644 --- a/app/controllers/steps_controller.rb +++ b/app/controllers/steps_controller.rb @@ -19,7 +19,7 @@ def update @current_step = @journey.steps.find_by(slug: params[:id]) @user_step = @user_journey.user_steps.find_or_initialize_by(step: @current_step) - @user_step.update(status: params['status']) + @user_step.update(status: params['status'], submitted_at: params['status'] == 'waiting' ? Date.today : nil) respond_to do |format| format.html do diff --git a/app/helpers/format_days_helper.rb b/app/helpers/format_days_helper.rb index 3381de29..8db7f3e4 100644 --- a/app/helpers/format_days_helper.rb +++ b/app/helpers/format_days_helper.rb @@ -23,4 +23,12 @@ def format_remaining_days_count(remaining_days) "posledný deň" end end + + def format_past_days_count(past_days) + if past_days == 1 + "1 dňom" + else + "#{past_days} dňami" + end + end end diff --git a/app/models/step.rb b/app/models/step.rb index e7a14cb6..27bccfe0 100644 --- a/app/models/step.rb +++ b/app/models/step.rb @@ -18,6 +18,7 @@ class Step < ApplicationRecord validates :slug, presence: true, uniqueness: true validates :description, presence: true validates :is_waiting_step, inclusion: { in: [true, false] } + validates :waiting_time, :numericality => { greater_than_or_equal_to: 0 } # FIXME: fill in position from id! diff --git a/app/models/user_step.rb b/app/models/user_step.rb index 54df987d..d617d84e 100644 --- a/app/models/user_step.rb +++ b/app/models/user_step.rb @@ -9,7 +9,7 @@ class UserStep < ApplicationRecord validates :status, inclusion: { in: %w(not_started started waiting done) } def refresh_status - if all_tasks_completed? && !step.has_app? + if all_tasks_completed? && !step.has_app? && !step.is_waiting_step? update(status: 'done') elsif user_tasks.completed.none? update(status: 'not_started') @@ -18,6 +18,14 @@ def refresh_status end end + def remaining_time + step.waiting_time - (Date.today - submitted_at).to_i + end + + def expected_resolution_date + Date.today + remaining_time.days + end + def done? status == 'done' end diff --git a/app/views/admin/steps/_form.html.erb b/app/views/admin/steps/_form.html.erb index fe23e500..c5673752 100644 --- a/app/views/admin/steps/_form.html.erb +++ b/app/views/admin/steps/_form.html.erb @@ -10,6 +10,7 @@ <%= form.text_field :custom_title %> <%= form.text_field :keywords %> <%= form.check_box :is_waiting_step %> + <%= form.number_field :waiting_time %> <%= form.text_field :slug %> <%= form.text_field :app_url %> <%= form.text_field :app_link_text %> diff --git a/app/views/components/_timeline.html.erb b/app/views/components/_timeline.html.erb index 0ae44188..5d1be1f5 100644 --- a/app/views/components/_timeline.html.erb +++ b/app/views/components/_timeline.html.erb @@ -23,6 +23,14 @@ <%= link_to step.title, [@journey, step], class: 'sdn-timeline__link' %> + <% if step.waiting_time > 0 && user_step&.status == "waiting" && user_step&.submitted_at %> + <% remaining_time = user_step.remaining_time %> + <% if remaining_time < 0 %> + Lehota vypršala pred: <%= format_past_days_count(-1 * remaining_time) %> + <% else %> + Čakacia lehota: <%= format_remaining_days_count(remaining_time) %> + <% end %> + <% end %> <% else %> <%= link_to step.title, [@journey, step], class: 'sdn-timeline__link' %> <% end %> diff --git a/app/views/deadline_notifications/_subscription_info.erb b/app/views/deadline_notifications/_subscription_info.erb new file mode 100644 index 00000000..217ee3f4 --- /dev/null +++ b/app/views/deadline_notifications/_subscription_info.erb @@ -0,0 +1,24 @@ +
+ <% if current_user_step.to_be_notified_at %> +

+ O vypršaní lehoty vám zašleme notifikáciu e-mailom dňa <%= current_user_step.to_be_notified_at.strftime('%d.%m.%Y') %>. + Zmeniť dátum +

+ <%= form_tag unsubscribe_deadline_notification_journey_step_path(@current_step.journey, @current_step), remote: true, authenticity_token: true, method: :delete do %> + <%= hidden_field_tag :current_user_step_id, current_user_step.id %> + <%= submit_tag 'Zrušiť notifikáciu', class: 'govuk-button govuk-button--warning' %> + <% end %> + <% else + current_user_step.submitted_at %> +

+ Ak si želáte môžeme vám poslať notifikáciu dňa <%= current_user_step.expected_resolution_date.strftime('%d.%m.%Y') %>. + Zmeniť dátum +

+ + <%= form_tag subscribe_to_deadline_notification_journey_step_path(@current_step.journey, @current_step), remote: true, authenticity_token: true do %> + <%= hidden_field_tag :current_user_step_id, current_user_step.id %> + <%= hidden_field_tag :notification_date, current_user_step.expected_resolution_date %> + <%= submit_tag 'Zapnúť notifikáciu', class: 'govuk-button' %> + <% end %> + <% end %> +
diff --git a/app/views/deadline_notifications/_subscription_settings.erb b/app/views/deadline_notifications/_subscription_settings.erb new file mode 100644 index 00000000..4101515c --- /dev/null +++ b/app/views/deadline_notifications/_subscription_settings.erb @@ -0,0 +1,36 @@ +
+ <%= render 'deadline_notifications/subscription_info', current_user_step: current_user_step %> +
+ diff --git a/app/views/deadline_notifications/deadline_notifications_update_error.js.erb b/app/views/deadline_notifications/deadline_notifications_update_error.js.erb new file mode 100644 index 00000000..dc77c201 --- /dev/null +++ b/app/views/deadline_notifications/deadline_notifications_update_error.js.erb @@ -0,0 +1,2 @@ +$('#change-notification-date').find('.govuk-form-group').addClass('govuk-form-group--error') +$('#change-notification-date').find('#dob-error').removeClass('sdn-appear-link-hide') diff --git a/app/views/deadline_notifications/deadline_notifications_updated.js.erb b/app/views/deadline_notifications/deadline_notifications_updated.js.erb new file mode 100644 index 00000000..4fa03861 --- /dev/null +++ b/app/views/deadline_notifications/deadline_notifications_updated.js.erb @@ -0,0 +1,5 @@ +$('#subsciption_info').replaceWith('<%= j render "deadline_notifications/subscription_info", current_user_step: @user_step %>'); +$('#deadline-notifications-info').removeClass('sdn-appear-link-hide') +$('#change-notification-date').addClass('sdn-appear-link-hide') +$('#change-notification-date').find('.govuk-form-group').removeClass('govuk-form-group--error') +$('#change-notification-date').find('#dob-error').addClass('sdn-appear-link-hide') diff --git a/app/views/steps/_todo_list_logged_in.html.erb b/app/views/steps/_todo_list_logged_in.html.erb index 5e332c5b..075ef75c 100644 --- a/app/views/steps/_todo_list_logged_in.html.erb +++ b/app/views/steps/_todo_list_logged_in.html.erb @@ -30,8 +30,15 @@ <% elsif current_user_step.waiting? %>
-

Podanie bolo zaslané

- Po úspešnom vybavení podania, keď dostanete pozitívnu odpoveď, označte +

Podané

+ <% if current_user_step.submitted_at %> +

+ Čakacia lehota na vybavenie je <%= t('components.deadline.remaining_days', count: @current_step.waiting_time) %>. + Ostáva <%= t('components.deadline.remaining_days', count: current_user_step.remaining_time) %>. +

+ <% end %> + + Po úspešnom vybavení, keď dostanete pozitívnu odpoveď, označte úlohu za vybavenú.
@@ -40,6 +47,17 @@ <%= link_to 'Označiť ako vybavené', journey_step_path(@journey, @current_step, status: 'done'), class: 'govuk-button', method: :patch, remote: true %> +
+
+ + + Notifikácia e-mailom + + +
+ <%= render 'deadline_notifications/subscription_settings', current_user_step: current_user_step %> +
+
<% else %> <% if @current_step.tasks.any? && @current_step.has_app? %>
@@ -59,8 +77,7 @@
<% end %> - + <% end %> - <% end %> diff --git a/config/routes.rb b/config/routes.rb index cf99a807..98d6ab32 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -54,6 +54,10 @@ resources :journeys, path: 'zivotne-situacie', only: [:show] do resources :steps, path: 'krok' do get :start, on: :member, path: 'spustit' + member do + post 'vytvorit-notifikaciu', to: 'deadline_notifications#subscribe_to_deadline_notification', as: :subscribe_to_deadline_notification + delete 'zrusit-notifikaciu', to: 'deadline_notifications#unsubscribe_deadline_notification', as: :unsubscribe_deadline_notification + end resources :tasks do member do post :complete diff --git a/db/migrate/20230627134435_add_waiting_time_to_steps.rb b/db/migrate/20230627134435_add_waiting_time_to_steps.rb new file mode 100644 index 00000000..b339a6cc --- /dev/null +++ b/db/migrate/20230627134435_add_waiting_time_to_steps.rb @@ -0,0 +1,5 @@ +class AddWaitingTimeToSteps < ActiveRecord::Migration[6.1] + def change + add_column :steps, :waiting_time, :integer, default: 0 + end +end diff --git a/db/migrate/20231007072828_add_submitted_at_and_to_be_notified_at_to_user_step.rb b/db/migrate/20231007072828_add_submitted_at_and_to_be_notified_at_to_user_step.rb new file mode 100644 index 00000000..494722cd --- /dev/null +++ b/db/migrate/20231007072828_add_submitted_at_and_to_be_notified_at_to_user_step.rb @@ -0,0 +1,6 @@ +class AddSubmittedAtAndToBeNotifiedAtToUserStep < ActiveRecord::Migration[6.1] + def change + add_column :user_steps, :submitted_at, :date, default: nil + add_column :user_steps, :to_be_notified_at, :date, default: nil + end +end diff --git a/db/structure.sql b/db/structure.sql index 0010d3d2..e4f95833 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -1025,7 +1025,8 @@ CREATE TABLE public.steps ( app_url character varying, type character varying DEFAULT 'BasicStep'::character varying NOT NULL, app_link_text character varying, - custom_title character varying + custom_title character varying, + waiting_time integer DEFAULT 0 ); @@ -1168,7 +1169,9 @@ CREATE TABLE public.user_steps ( step_id bigint NOT NULL, status character varying NOT NULL, created_at timestamp without time zone NOT NULL, - updated_at timestamp without time zone NOT NULL + updated_at timestamp without time zone NOT NULL, + submitted_at date, + to_be_notified_at date ); @@ -2440,6 +2443,8 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230325092744'), ('20230325095737'), ('20230325151049'), -('20240427124856'); +('20240427124856'), +('20230627134435'), +('20231007072828');