Skip to content

Commit

Permalink
Merge pull request #10261 from DFE-Digital/cv/one-login-component
Browse files Browse the repository at this point in the history
New header and primary navigation for candidate support and provider
  • Loading branch information
CatalinVoineag authored Jan 16, 2025
2 parents 75213a8 + 5684c9e commit fcda817
Show file tree
Hide file tree
Showing 21 changed files with 342 additions and 87 deletions.
2 changes: 2 additions & 0 deletions .env.test
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ COVERAGE=false
AZURE_CLIENT_ID=
AZURE_FEDERATED_TOKEN_FILE=
GOOGLE_CLOUD_CREDENTIALS_STATS={}

GOVUK_ONE_LOGIN_ACCOUNT_URL=http://home.integration.account.gov.uk
2 changes: 1 addition & 1 deletion app/components/utility/header_component.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class HeaderComponent < ViewComponent::Base
attr_reader :classes, :product_name, :service_name, :service_link, :phase_tag, :navigation_items, :navigation_classes

def initialize(service_link:, classes: '', product_name: nil, homepage_url: nil, service_name: nil, phase_tag: false, navigation_items: [], navigation_classes: '')
def initialize(service_link: nil, classes: '', product_name: nil, homepage_url: nil, service_name: nil, phase_tag: false, navigation_items: [], navigation_classes: '')
@classes = classes
@product_name = product_name
@homepage_url = homepage_url
Expand Down
2 changes: 1 addition & 1 deletion app/components/utility/phase_banner_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="app-phase-banner<%= @no_border ? ' app-phase-banner--no-border' : '' %> govuk-!-display-none-print">
<div class="app-phase-banner govuk-!-display-none-print">
<div class="govuk-width-container">
<%= govuk_phase_banner(
tag: {
Expand Down
32 changes: 32 additions & 0 deletions app/frontend/styles/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,35 @@
}
}
}

.govuk-header {
&__navigation {
display: flex;

@include govuk-media-query($from: tablet) {
justify-content: flex-end;
}
}

&__navigation-list {
@include govuk-media-query($from: tablet) {
display: flex;
}
}

&__navigation-item {
@include govuk-media-query($from: tablet) {
padding-inline: govuk-spacing(3);
margin: 0;

border-left: 1px solid $govuk-border-colour;
}
}
}

.one-login-svg {
position: relative;
top: 2px;

margin-left: 7px;
}
10 changes: 10 additions & 0 deletions app/frontend/styles/_primary-navigation.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
.govuk-service-navigation {
&__container {
justify-content: space-between;
}

&__link {
font-weight: bold;
}
}

.app-primary-navigation {
background-color: govuk-colour("light-grey");
}
Expand Down
152 changes: 123 additions & 29 deletions app/helpers/navigation_items.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,72 @@ def candidate_primary_navigation(current_candidate:, current_controller:)

if current_candidate.current_application.any_offer_accepted?
[
NavigationItem.new(
t('page_titles.offer_dashboard'),
candidate_interface_application_offer_dashboard_path,
true,
),
{
text: t('page_titles.offer_dashboard'),
href: candidate_interface_application_offer_dashboard_path,
active: true,
},
]
elsif current_candidate.current_application.carry_over?
[
NavigationItem.new(
t('page_titles.your_applications'),
candidate_interface_application_choices_path,
true,
),
{
text: t('page_titles.your_applications'),
href: candidate_interface_application_choices_path,
active: true,
},
]
else
[
NavigationItem.new(
t('page_titles.your_details'),
candidate_interface_details_path,
current_controller.respond_to?(:choices_controller?) ? !current_controller.choices_controller? : false,
),
NavigationItem.new(
t('page_titles.your_applications'),
candidate_interface_application_choices_path,
current_controller.respond_to?(:choices_controller?) ? current_controller.choices_controller? : false,
),
{
text: t('page_titles.your_details'),
href: candidate_interface_details_path,
active: current_controller.respond_to?(:choices_controller?) ? !current_controller.choices_controller? : false,
},
{
text: t('page_titles.your_applications'),
href: candidate_interface_application_choices_path,
active: current_controller.respond_to?(:choices_controller?) ? current_controller.choices_controller? : false,
},
]
end
end

def candidate(current_candidate:)
if current_candidate.nil?
[]
else
sign_in_items(current_candidate)
end
end

def for_support_primary_nav(current_support_user, current_controller)
if current_support_user
[
NavigationItem.new('Candidates', support_interface_applications_path, active?(current_controller, %w[candidates import_references application_forms]), []),
NavigationItem.new('Providers', support_interface_providers_path, active?(current_controller, %w[providers course provider_users api_tokens]), []),
NavigationItem.new('Performance', support_interface_performance_path, active?(current_controller, %w[performance data_exports validation_errors email_log vendor_api_requests performance_dashboard]), []),
NavigationItem.new('Settings', support_interface_settings_path, active?(current_controller, %w[settings tasks support_users]), []),
NavigationItem.new('Documentation', support_interface_docs_path, active?(current_controller, %w[docs]), []),
{
text: 'Candidates',
href: support_interface_applications_path,
active: active?(current_controller, %w[candidates import_references application_forms]),
},
{
text: 'Providers',
href: support_interface_providers_path,
active: active?(current_controller, %w[providers course provider_users api_tokens]),
},
{
text: 'Performance',
href: support_interface_performance_path,
active: active?(current_controller, %w[performance data_exports validation_errors email_log vendor_api_requests performance_dashboard]),
},
{
text: 'Settings',
href: support_interface_settings_path,
active: active?(current_controller, %w[settings tasks support_users]),
},
{
text: 'Documentation',
href: support_interface_docs_path,
active: active?(current_controller, %w[docs]),
},
]
else
[]
Expand Down Expand Up @@ -75,10 +103,54 @@ def for_provider_primary_nav(current_provider_user, current_controller, performi
items = []

if current_provider_user && !performing_setup
items << NavigationItem.new('Applications', provider_interface_applications_path, active?(current_controller, %w[application_choices decisions offer_changes notes interviews offers feedback conditions reconfirm_deferred_offers]), [])
items << NavigationItem.new('Interview schedule', provider_interface_interview_schedule_path, active?(current_controller, %w[interview_schedules]), [])
items << NavigationItem.new('Reports', provider_interface_reports_path, active?(current_controller, %w[reports application_data_export hesa_exports recruitment_performance_reports withdrawal_reports withdrawal_reasons_reports status_of_active_applications diversity_reports]))
items << NavigationItem.new('Activity log', provider_interface_activity_log_path, active?(current_controller, %w[activity_log]), [])
items << {
text: 'Applications',
href: provider_interface_applications_path,
active: active?(
current_controller,
%w[
application_choices
decisions
offer_changes
notes
interviews
offers
feedback
conditions
reconfirm_deferred_offers
references
courses
study_modes
],
),
}
items << {
text: 'Interview schedule',
href: provider_interface_interview_schedule_path,
active: active?(current_controller, %w[interview_schedules]),
}
items << {
text: 'Reports',
href: provider_interface_reports_path,
active: active?(
current_controller,
%w[
reports
application_data_export
hesa_exports
recruitment_performance_reports
withdrawal_reports
withdrawal_reasons_reports
status_of_active_applications
diversity_reports
],
),
}
items << {
text: 'Activity log',
href: provider_interface_activity_log_path,
active: active?(current_controller, %w[activity_log]),
}
end

items
Expand Down Expand Up @@ -140,5 +212,27 @@ def active?(current_controller, active_controllers)
def active_action?(current_controller, active_action)
current_controller.action_name == active_action
end

def sign_in_items(current_candidate)
items = []

if FeatureFlag.active?(:one_login_candidate_sign_in) && !OneLogin.bypass? && current_candidate.one_login_auth.present?
items << NavigationItem.new("GOV.UK One Login #{one_login_svg}".html_safe, ENV['GOVUK_ONE_LOGIN_ACCOUNT_URL'])
end

sign_out_path = FeatureFlag.active?(:one_login_candidate_sign_in) ? auth_one_login_sign_out_path : candidate_interface_sign_out_path
items << NavigationItem.new('Sign out', sign_out_path)
end

def one_login_svg
"<span aria-hidden=\"true\" class=\"one-login-svg\">
<svg width=\"15\" height=\"15\" viewBox=\"0 0 22 22\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" focusable=\"false\" aria-hidden=\"true\">
<circle cx=\"11\" cy=\"11\" r=\"11\" fill=\"white\" data-darkreader-inline-fill=\"\" style=\"--darkreader-inline-fill: #e8e6e3;\"></circle>
<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M3.29297 18.8487C4.23255 15.4753 7.32741 13 11.0004 13C14.6731 13 17.7678 15.4749 18.7076 18.848C17.8058 19.7338 16.752 20.4654 15.5889 21H11.0004H6.41097C5.24819 20.4655 4.19463 19.7342 3.29297 18.8487Z\" fill=\"#1D70B8\" data-darkreader-inline-fill=\"\" style=\"--darkreader-inline-fill: #65aee7;\"></path>
<circle cx=\"11\" cy=\"7.75\" r=\"3.75\" fill=\"#1D70B8\" data-darkreader-inline-fill=\"\" style=\"--darkreader-inline-fill: #65aee7;\"></circle>
<circle cx=\"11\" cy=\"11\" r=\"10\" stroke=\"white\" stroke-width=\"2\" data-darkreader-inline-stroke=\"\" style=\"--darkreader-inline-stroke: #e8e6e3;\"></circle>
</svg>
</span><span class=\"govuk-visually-hidden\">Currently impersonating:</span>"
end
end
end
64 changes: 36 additions & 28 deletions app/views/layouts/_header.html.erb
Original file line number Diff line number Diff line change
@@ -1,41 +1,50 @@
<% case try(:current_namespace) %>
<% when 'candidate_interface' %>
<%= render(HeaderComponent.new(
classes: "app-header--#{HostingEnvironment.environment_name} app-header--full-border",
service_name: service_name,
service_link: service_link,
)) %>
<%= render PhaseBannerComponent.new(no_border: current_candidate.present?) %>
<% if current_candidate %>
<% sign_out_path = FeatureFlag.active?(:one_login_candidate_sign_in) ? auth_one_login_sign_out_path : candidate_interface_sign_out_path %>
<%= render(PrimaryNavigationComponent.new(
items: NavigationItems.candidate_primary_navigation(current_candidate:, current_controller: controller),
items_right: [NavigationItems::NavigationItem.new('Sign out', sign_out_path)],
)) %>
<% end %>
<%= render(
HeaderComponent.new(
homepage_url: service_link,
classes: "app-header--#{HostingEnvironment.environment_name} app-header--full-border",
navigation_items: NavigationItems.candidate(current_candidate:),
),
) %>

<%= govuk_service_navigation(
service_name: t('service_name.apply'),
current_path: request.path,
navigation_items: NavigationItems.candidate_primary_navigation(
current_candidate:,
current_controller: controller,
),
navigation_id: 'service-navigation',
) %>
<%= render PhaseBannerComponent.new(no_border: current_candidate.present?) %>
<% when 'support_interface' %>
<%= render(HeaderComponent.new(
classes: "app-header--#{HostingEnvironment.environment_name} app-header--full-border app-header--wide-logo",
product_name: service_name,
homepage_url: service_link,
service_link: service_link,
phase_tag: true,
navigation_items: NavigationItems.for_support_account_nav(try(:current_support_user)),
navigation_classes: 'govuk-header__navigation--end',
)) %>
<%= render(PrimaryNavigationComponent.new(
items: NavigationItems.for_support_primary_nav(try(:current_support_user), controller),
)) %>
<%= govuk_service_navigation(
service_name: t('service_name.apply'),
current_path: request.path,
navigation_items: NavigationItems.for_support_primary_nav(try(:current_support_user), controller),
navigation_id: 'service-navigation',
) %>
<%= yield(:navigation) if content_for?(:navigation) %>
<% when 'provider_interface' %>
<%= render(HeaderComponent.new(
classes: "app-header--#{HostingEnvironment.environment_name} app-header--full-border app-header--wide-logo",
product_name: service_name,
homepage_url: service_link,
service_link: service_link,
navigation_items: NavigationItems.for_provider_account_nav(try(:current_provider_user), controller, performing_setup: @provider_setup&.pending?),
navigation_classes: 'govuk-header__navigation--end',
)) %>

<%= govuk_service_navigation(
service_name: t('service_name.manage'),
current_path: request.path,
navigation_items: NavigationItems.for_provider_primary_nav(try(:current_provider_user), controller, performing_setup: @provider_setup&.pending?),
navigation_id: 'service-navigation',
) %>

<% if controller.controller_name == 'start_page' %>
<%= render(PhaseBannerComponent.new(
feedback_link: ProviderInterface::FEEDBACK_LINK,
Expand All @@ -49,9 +58,6 @@
no_border: true,
feedback_link: ProviderInterface::FEEDBACK_LINK,
)) %>
<%= render(PrimaryNavigationComponent.new(
items: NavigationItems.for_provider_primary_nav(try(:current_provider_user), controller, performing_setup: @provider_setup&.pending?),
)) %>
<% end %>
<% when 'vendor_api_docs' %>
<%= render(HeaderComponent.new(
Expand All @@ -78,8 +84,10 @@
<% components_name = 'ViewComponent Previews' if request.path.match(/^\/rails\/view_components/) %>
<%= render(HeaderComponent.new(
classes: "app-header--#{HostingEnvironment.environment_name}",
service_name: components_name || try(:service_name),
service_link: components_url || try(:service_link),
homepage_url: components_url || try(:service_link),
)) %>

<%= govuk_service_navigation(service_name: components_name || try(:service_name), navigation_id: 'service-navigation') %>

<%= render PhaseBannerComponent.new %>
<% end %>
Loading

0 comments on commit fcda817

Please sign in to comment.