Browse Source

CLDC-2252 Add homepage task section (#2115)

* feat: wip add lettings, sales and schemes sections with correct text, counts, links and colouring

* feat: add flex styling to match designs

* CLDC-3076: Make example dates consistent (#2107)

* CLDC-3076: Make example dates consistent

* Use example date even when some hint text provided already

* Temp remove some date restrictions

* Update to 2 line breaks

* Revert "Temp remove some date restrictions"

This reverts commit cd7f18f9f1.

* Fix lettings log accessor in date question (#2117)

* Fix lettings log accessor in date question

* Remove hardcoded date example from mrcdate question (#2118)

---------

Co-authored-by: Rachael Booth <Rachael.Booth@softwire.com>

* feat: update breakpoints for responsive layout changes

* lint: use hash lookup where possible

* lint: erblinting

* feat: improve formatting

* Reuse govuk grid

* Revert "Reuse govuk grid"

This reverts commit 8c71f5d9ed.

* feat: test home page data boxes

* refactor: lint

* refactor: lint

* feat: test link behaviour is correct in all user scenarios

* refactor: lint

* feat: update tests

* feat: combine task, resources, deadlines sections

---------

Co-authored-by: Rachael Booth <Rachael.Booth@softwire.com>
Co-authored-by: kosiakkatrina <54268893+kosiakkatrina@users.noreply.github.com>
Co-authored-by: Kat <kosiak.katrina@gmail.com>
pull/2131/head
natdeanlewissoftwire 2 years ago committed by GitHub
parent
commit
645994d469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 66
      app/frontend/styles/_data_box.scss
  2. 1
      app/frontend/styles/application.scss
  3. 71
      app/helpers/home_helper.rb
  4. 9
      app/views/home/_data_box.html.erb
  5. 58
      app/views/home/index.html.erb
  6. 158
      spec/features/home_page_spec.rb

66
app/frontend/styles/_data_box.scss

@ -0,0 +1,66 @@
.app-data-box-group {
@include govuk-font($size: 19);
font-weight: bold;
white-space: nowrap;
}
@media (min-width: 54.0625em) {
.app-data-box-group-one-third {
display: flex;
justify-content: space-between;
column-gap: govuk-spacing(4);
width: 100%;
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-third {
width: 33.3333%;
float: left;
}
}
@media (min-width: 54.0625em) {
.app-data-box__underline {
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-group-one-half {
display: flex;
justify-content: space-between;
column-gap: govuk-spacing(4);
width: 100%;
min-width: 733.33px;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-half {
width: 50%;
float: left;
}
}
@media (min-width: 54.0625em) {
.app-data-box-one-half__underline {
min-width: 733.33px;
}
}
.app-data-box__upper {
@include govuk-responsive-margin(2, "bottom");
@include govuk-responsive-padding(4);
background-color: govuk-colour("light-grey");
color: govuk-colour("blue");
}
.app-data-box__lower {
@include govuk-responsive-margin(4, "bottom");
@include govuk-responsive-padding(4);
background-color: govuk-colour("blue");
}
.app-data-box__count {
font-size: 48px;
color: govuk-colour("blue");
}

1
app/frontend/styles/application.scss

@ -25,6 +25,7 @@ $govuk-breakpoints: (
@import "accessible-autocomplete";
@import "button";
@import "card";
@import "data_box";
@import "document-list";
@import "feedback";
@import "filter";

71
app/helpers/home_helper.rb

@ -0,0 +1,71 @@
module HomeHelper
def data_count(user, type)
if user.data_provider?
case type
when "lettings" then user.lettings_logs.in_progress.where(created_by: user).count
when "sales" then user.sales_logs.in_progress.where(created_by: user).count
when "misc" then user.lettings_logs.completed.where(created_by: user).count
end
else
case type
when "lettings" then user.lettings_logs.in_progress.count
when "sales" then user.sales_logs.in_progress.count
when "schemes" then user.schemes.incomplete.count
end
end
end
def heading_for_user_role(user)
ROLE_HEADINGS[user.role]
end
def data_subheading(user, type)
case type
when "schemes"
"Incomplete schemes"
when "misc"
"Your completed lettings"
else
"#{user.role == 'data_provider' ? :"Your " : nil}#{type} in progress".capitalize
end
end
def data_path(user, type)
if user.data_provider?
case type
when "lettings" then lettings_logs_path(status: [:in_progress], assigned_to: "you")
when "sales" then sales_logs_path(status: [:in_progress], assigned_to: "you")
when "misc" then lettings_logs_path(status: [:completed], assigned_to: "you")
end
else
case type
when "lettings" then lettings_logs_path(status: [:in_progress])
when "sales" then sales_logs_path(status: [:in_progress])
when "schemes" then schemes_path(status: [:incomplete])
end
end
end
def view_all_path(type)
case type
when "lettings" then clear_filters_path(filter_type: "lettings_logs")
when "sales" then clear_filters_path(filter_type: "sales_logs")
when "schemes" then clear_filters_path(filter_type: "schemes")
when "misc" then clear_filters_path(filter_type: "schemes")
end
end
def view_all_text(type)
if type == "misc"
"View all schemes"
else
"View all #{type}"
end
end
ROLE_HEADINGS = {
"data_provider" => "Complete your logs",
"data_coordinator" => "Manage your data",
"support" => "Manage all data",
}.freeze
end

9
app/views/home/_data_box.html.erb

@ -0,0 +1,9 @@
<div class="app-data-box__upper">
<div class="app-data-box__count">
<%= govuk_link_to data_count(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state govuk-link--no-underline" %>
</div>
<%= govuk_link_to data_subheading(@current_user, type), data_path(@current_user, type), class: "govuk-link--no-visited-state" %>
</div>
<div class="app-data-box__lower">
<%= govuk_link_to view_all_text(type), view_all_path(type), class: "govuk-link--inverse" %>
</div>

58
app/views/home/index.html.erb

@ -1,8 +1,56 @@
<p class="govuk-body-l"><%= "Welcome back, #{@current_user.name}" %></p>
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<%= render partial: "layouts/collection_resources" %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<%= render partial: "home/upcoming_deadlines" %>
<div class="govuk-width-container">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-grid-row govuk-!-margin-bottom-7">
<span class="govuk-body-l"><%= "Welcome back, #{@current_user.name}" %></span>
<h1 class="govuk-heading-l"><%= heading_for_user_role(@current_user) %></h1>
</div>
<div class="govuk-grid-row">
<div class="app-data-box-group">
<% if @current_user.support? || (@current_user.data_coordinator? && @current_user.sales_logs.present?) %>
<div class="app-data-box-group-one-third">
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "lettings" } %></span>
</div>
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "sales" } %></span>
</div>
<div class="app-data-box-one-third">
<span><%= render partial: "home/data_box", locals: { type: "schemes" } %></span>
</div>
</div>
<% else %>
<div class="app-data-box-group-one-half">
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "lettings" } %></span>
</div>
<% if @current_user.data_coordinator? %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "schemes" } %></span>
</div>
<% elsif @current_user.sales_logs.present? %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "sales" } %></span>
</div>
<% else %>
<div class="app-data-box-one-half">
<span><%= render partial: "home/data_box", locals: { type: "misc" } %></span>
</div>
<% end %>
</div>
<% end %>
</div>
</div>
<div class="govuk-grid-row">
<div class="app-data-box__underline">
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
</div>
</div>
<div class="govuk-grid-row">
<%= render partial: "layouts/collection_resources" %>
<hr class="govuk-section-break govuk-section-break--visible govuk-section-break--m">
<%= render partial: "home/upcoming_deadlines" %>
</div>
</div>
</div>
</div>

158
spec/features/home_page_spec.rb

@ -0,0 +1,158 @@
require "rails_helper"
require_relative "form/helpers"
RSpec.describe "Home Page Features" do
include Helpers
context "when the user is a data provider" do
let(:user) { FactoryBot.create(:user, name: "Provider") }
before do
create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation)
create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 2, :completed)
sign_in user
visit("/")
end
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Provider")
expect(page).to have_content("Complete your logs")
end
context "when their organisation has submitted sales logs" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation, created_by: user)
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Your sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress], assigned_to: "you"), sales_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "sales_logs")])
end
end
context "when their organisation has never submitted sales logs" do
before do
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["6", "Your lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress], assigned_to: "you"), lettings_logs_path(status: [:in_progress], assigned_to: "you"), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["4", "Your completed lettings", "View all schemes"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:completed], assigned_to: "you"), lettings_logs_path(status: [:completed], assigned_to: "you"), clear_filters_path(filter_type: "schemes")])
end
end
end
context "when the user is a data coordinator" do
before do
create_list(:lettings_log, 6, :in_progress, owning_organisation: user.organisation)
create_list(:lettings_log, 2, :in_progress, owning_organisation: user.organisation, created_by: user)
create_list(:lettings_log, 4, :completed, owning_organisation: user.organisation)
create_list(:lettings_log, 2, :completed)
create_list(:scheme, 1, :incomplete, owning_organisation: user.organisation)
sign_in user
visit("/")
end
let(:user) { FactoryBot.create(:user, :data_coordinator, name: "Coordinator") }
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Coordinator")
expect(page).to have_content("Manage your data")
end
context "when their organisation has submitted sales logs" do
before do
create_list(:sales_log, 5, :in_progress, owning_organisation: user.organisation)
create_list(:sales_log, 3, :completed, owning_organisation: user.organisation)
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-third")
expect(data_boxes.count).to eq(3)
expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["5", "Sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")])
expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
context "when their organisation has never submitted sales logs" do
before do
visit("/")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-half")
expect(data_boxes.count).to eq(2)
expect(data_boxes[0].all("a").map(&:text)).to eq(["8", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
end
context "when the user is a support user" do
let(:support_user) { FactoryBot.create(:user, :support, name: "Support") }
let(:notify_client) { instance_double(Notifications::Client) }
let(:confirmation_token) { "MCDH5y6Km-U7CFPgAMVS" }
let(:devise_notify_mailer) { DeviseNotifyMailer.new }
let(:otp) { "999111" }
before do
create_list(:lettings_log, 2, :in_progress)
create_list(:lettings_log, 1, :completed)
create_list(:sales_log, 3, :in_progress)
create_list(:sales_log, 1, :completed)
create_list(:scheme, 1, :incomplete)
completed_scheme = create(:scheme)
create(:location, scheme: completed_scheme)
allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer)
allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client)
allow(Devise).to receive(:friendly_token).and_return(confirmation_token)
allow(notify_client).to receive(:send_email).and_return(true)
allow(SecureRandom).to receive(:random_number).and_return(otp)
visit("/lettings-logs")
fill_in("user[email]", with: support_user.email)
fill_in("user[password]", with: support_user.password)
click_button("Sign in")
fill_in("code", with: otp)
click_button("Submit")
visit("/")
end
it "displays the correct welcome text" do
expect(page).to have_current_path("/")
expect(page).to have_content("Welcome back, Support")
expect(page).to have_content("Manage all data")
end
it "displays correct data boxes, counts and links" do
data_boxes = page.find_all(class: "app-data-box-one-third")
expect(data_boxes.count).to eq(3)
expect(data_boxes[0].all("a").map(&:text)).to eq(["2", "Lettings in progress", "View all lettings"])
expect(data_boxes[0].all("a").map { |line| line["href"] }).to eq([lettings_logs_path(status: [:in_progress]), lettings_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "lettings_logs")])
expect(data_boxes[1].all("a").map(&:text)).to eq(["3", "Sales in progress", "View all sales"])
expect(data_boxes[1].all("a").map { |line| line["href"] }).to eq([sales_logs_path(status: [:in_progress]), sales_logs_path(status: [:in_progress]), clear_filters_path(filter_type: "sales_logs")])
expect(data_boxes[2].all("a").map(&:text)).to eq(["1", "Incomplete schemes", "View all schemes"])
expect(data_boxes[2].all("a").map { |line| line["href"] }).to eq([schemes_path(status: [:incomplete]), schemes_path(status: [:incomplete]), clear_filters_path(filter_type: "schemes")])
end
end
end
Loading…
Cancel
Save