Skip to content

Commit

Permalink
Merge pull request #10930 from 18F/stages/rc-2024-07-11
Browse files Browse the repository at this point in the history
Deploy RC 396 to Production
  • Loading branch information
mdiarra3 committed Jul 11, 2024
2 parents 988c6d4 + 299c05e commit c7af67c
Show file tree
Hide file tree
Showing 44 changed files with 1,120 additions and 165 deletions.
4 changes: 2 additions & 2 deletions app/components/badge_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<%= content_tag('div', **tag_options, class: ['lg-verification-badge', *tag_options[:class]]) do %>
<%= render IconComponent.new(icon:, class: 'text-success') %>
<%= content_tag('div', **tag_options, class: ['lg-verification-badge', border_css_class, *tag_options[:class]]) do %>
<%= render IconComponent.new(icon:, class: icon_css_class) %>
<%= content %>
<% end %>
21 changes: 21 additions & 0 deletions app/components/badge_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class BadgeComponent < BaseComponent
ICONS = %i[
lock
check_circle
warning
info
].to_set.freeze

attr_reader :icon, :tag_options
Expand All @@ -13,4 +15,23 @@ def initialize(icon:, **tag_options)
@icon = icon
@tag_options = tag_options
end

def color_token
case icon
when :check_circle, :lock
'success'
when :warning
'warning'
else
'info'
end
end

def border_css_class
"border-#{color_token}"
end

def icon_css_class
"text-#{color_token}"
end
end
14 changes: 14 additions & 0 deletions app/components/tooltip_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class TooltipComponent < BaseComponent
attr_reader :tooltip_text, :tag_options

def initialize(tooltip_text:, **tag_options)
@tooltip_text = tooltip_text
@tag_options = tag_options
end

def call
content_tag(:'lg-tooltip', content, **tag_options, 'tooltip-text': tooltip_text)
end
end
9 changes: 9 additions & 0 deletions app/components/tooltip_component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
@forward 'usa-tooltip';

// The USWDS tooltip component does not handle child elements gracefully. Prevent non-interactive
// child elements from triggering event handlers to avoid errors.
//
// See: https://github.com/uswds/uswds/pull/5263#issuecomment-2191808834
lg-tooltip .usa-icon {
pointer-events: none;
}
1 change: 1 addition & 0 deletions app/components/tooltip_component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import '@18f/identity-tooltip/tooltip-element';
1 change: 1 addition & 0 deletions app/controllers/accounts/connected_accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def show
@presenter = AccountShowPresenter.new(
decrypted_pii: nil,
sp_session_request_url: sp_session_request_url_with_updated_params,
authn_context: resolved_authn_context_result,
sp_name: decorated_sp_session.sp_name,
user: current_user,
locked_for_session: pii_locked_for_session?(current_user),
Expand Down
1 change: 1 addition & 0 deletions app/controllers/accounts/history_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def show
@presenter = AccountShowPresenter.new(
decrypted_pii: nil,
sp_session_request_url: sp_session_request_url_with_updated_params,
authn_context: resolved_authn_context_result,
sp_name: decorated_sp_session.sp_name,
user: current_user,
locked_for_session: pii_locked_for_session?(current_user),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def show
@presenter = AccountShowPresenter.new(
decrypted_pii: nil,
sp_session_request_url: sp_session_request_url_with_updated_params,
authn_context: resolved_authn_context_result,
sp_name: decorated_sp_session.sp_name,
user: current_user,
locked_for_session: pii_locked_for_session?(current_user),
Expand Down
1 change: 1 addition & 0 deletions app/controllers/accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ def show
@presenter = AccountShowPresenter.new(
decrypted_pii: cacher.fetch(current_user.active_or_pending_profile&.id),
sp_session_request_url: sp_session_request_url_with_updated_params,
authn_context: resolved_authn_context_result,
sp_name: decorated_sp_session.sp_name,
user: current_user,
locked_for_session: pii_locked_for_session?(current_user),
Expand Down
1 change: 1 addition & 0 deletions app/controllers/events_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def show
@presenter = AccountShowPresenter.new(
decrypted_pii: nil,
sp_session_request_url: sp_session_request_url_with_updated_params,
authn_context: resolved_authn_context_result,
sp_name: decorated_sp_session.sp_name,
user: current_user,
locked_for_session: pii_locked_for_session?(current_user),
Expand Down
24 changes: 24 additions & 0 deletions app/javascript/packages/tooltip/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# `@18f/identity-tooltip`

Custom element for a tooltip component.

## Usage

Importing the element will register the `<lg-tooltip>` custom element:

```ts
import '@18f/identity-tooltip/tooltip-element';
```

The custom element will implement behaviors for showing tooltip text on hover or focus, but all markup must already exist.

> [!WARNING]
> Due to existing issues with the U.S. Web Design System Tooltip component, there are a few limitations to be aware of:
> 1. Content must be wrapped in a wrapper element, such as a `<span>` tag.
> 2. Any other nested child elements must be non-interactive, using `pointer-events: none;`.
```html
<lg-tooltip tooltip-text="Your identity has been verified.">
<span>Verified</span>
</lg-tooltip>
```
11 changes: 11 additions & 0 deletions app/javascript/packages/tooltip/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "@18f/identity-tooltip",
"version": "1.0.0",
"private": true,
"dependencies": {
"@18f/identity-design-system": "^9.3.0"
},
"sideEffects": [
"./tooltip-element.ts"
]
}
27 changes: 27 additions & 0 deletions app/javascript/packages/tooltip/tooltip-element.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { screen, getByText, waitFor } from '@testing-library/dom';
import userEvent from '@testing-library/user-event';
import { computeAccessibleDescription } from 'dom-accessibility-api';
import './tooltip-element';

describe('TooltipElement', () => {
function createAndConnectElement({ tooltipText = '', innerHTML = '<span>Verified</span>' } = {}) {
const element = document.createElement('lg-tooltip');
element.setAttribute('tooltip-text', tooltipText);
element.innerHTML = innerHTML;
document.body.appendChild(element);
return element;
}

it('initializes tooltip element', async () => {
const tooltipText = 'Your identity has been verified';
const element = createAndConnectElement({ tooltipText });

const content = getByText(element, 'Verified');

await userEvent.hover(content);
expect(computeAccessibleDescription(content)).to.be.equal(tooltipText);
await waitFor(() => {
expect(screen.getByText(tooltipText).classList.contains('is-visible')).to.be.true();
});
});
});
32 changes: 32 additions & 0 deletions app/javascript/packages/tooltip/tooltip-element.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { tooltip } from '@18f/identity-design-system';

class TooltipElement extends HTMLElement {
connectedCallback() {
this.tooltipElement.setAttribute('title', this.tooltipText);
this.tooltipElement.classList.add('usa-tooltip');
tooltip.on(this.tooltipElement);
}

get tooltipElement(): HTMLElement {
return this.firstElementChild as HTMLElement;
}

/**
* Retrieves the text to be shown in the tooltip.
*/
get tooltipText(): string {
return this.getAttribute('tooltip-text')!;
}
}

declare global {
interface HTMLElementTagNameMap {
'lg-tooltip': TooltipElement;
}
}

if (!customElements.get('lg-tooltip')) {
customElements.define('lg-tooltip', TooltipElement);
}

export default TooltipElement;
70 changes: 56 additions & 14 deletions app/presenters/account_show_presenter.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
# frozen_string_literal: true

class AccountShowPresenter
attr_reader :user, :decrypted_pii, :locked_for_session, :pii, :sp_session_request_url, :sp_name

def initialize(decrypted_pii:, sp_session_request_url:, sp_name:, user:,
locked_for_session:)
attr_reader :user,
:decrypted_pii,
:locked_for_session,
:pii,
:sp_session_request_url,
:authn_context,
:sp_name

delegate :identity_verified_with_biometric_comparison?, to: :user

def initialize(
decrypted_pii:,
sp_session_request_url:,
authn_context:,
sp_name:,
user:,
locked_for_session:
)
@decrypted_pii = decrypted_pii
@user = user
@sp_name = sp_name
@sp_session_request_url = sp_session_request_url
@authn_context = authn_context
@locked_for_session = locked_for_session
@pii = determine_pii
end
Expand All @@ -17,10 +32,6 @@ def show_password_reset_partial?
user.password_reset_profile.present?
end

def show_pii_partial?
decrypted_pii.present? || user.identity_verified?
end

def show_manage_personal_key_partial?
user.encrypted_recovery_code_digest.present? &&
user.password_reset_profile.blank?
Expand All @@ -30,14 +41,45 @@ def show_service_provider_continue_partial?
sp_name.present? && sp_session_request_url.present?
end

def show_gpo_partial?
def showing_alerts?
show_service_provider_continue_partial? ||
show_password_reset_partial?
end

def active_profile?
user.active_profile.present?
end

def active_profile_for_authn_context?
return @active_profile_for_authn_context if defined?(@active_profile_for_authn_context)

@active_profile_for_authn_context = active_profile? && (
!authn_context.biometric_comparison? || identity_verified_with_biometric_comparison?
)
end

def pending_idv?
authn_context.identity_proofing? && !active_profile_for_authn_context?
end

def pending_ipp?
user.pending_in_person_enrollment.present?
end

def pending_gpo?
user.gpo_verification_pending_profile?
end

def showing_any_partials?
show_service_provider_continue_partial? ||
show_password_reset_partial? ||
show_gpo_partial?
def show_idv_partial?
active_profile? || pending_idv? || pending_ipp? || pending_gpo?
end

def formatted_ipp_due_date
I18n.l(user.pending_in_person_enrollment.due_date, format: :event_date)
end

def formatted_nonbiometric_idv_date
I18n.l(user.active_profile.created_at, format: :event_date)
end

def show_unphishable_badge?
Expand Down Expand Up @@ -119,7 +161,7 @@ def decrypted_pii_accessor
end

def determine_pii
return PiiAccessor.new unless show_pii_partial?
return PiiAccessor.new unless active_profile?
if decrypted_pii.present? && !@locked_for_session
decrypted_pii_accessor
else
Expand Down
4 changes: 0 additions & 4 deletions app/views/accounts/_badges.html.erb
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
<% if @presenter.show_unphishable_badge? %>
<%= render BadgeComponent.new(icon: :lock).with_content(t('headings.account.unphishable')) %>
<% end %>
<% if @presenter.show_verified_badge? %>
<%= render BadgeComponent.new(icon: :check_circle).with_content(t('headings.account.verified_account')) %>
<% end %>
Loading

0 comments on commit c7af67c

Please sign in to comment.