npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@govuk-one-login/spinner

v1.0.1

Published

Spinner component used when a user returns from IPV to authentication

Downloads

629

Readme

Authentication spinner

About The Project

This spinner component is initialised on a web page rendered by the authentication frontend app (but owned by the Orchestration Team) to replace a server-rendered form with content and interactive controls that update to reflect the readiness state returned by an API.

States represented by the spinner component include:

  1. Pending
  2. Error
  3. Long wait
  4. Completed

Getting Started

For this component to work as a progressive enhancement you will need:

  1. A working form that does not rely on JavaScript to function
  2. The /dist/spinner-app.js script to be included and deferred on only the relevant page
  3. The spinner CSS to be included in your application CSS
  4. The page to contain an element with:
    1. an id of spinner-container
    2. all the necessary data- attributes populated with the content to be displayed.
  5. An API endpoint that can respond to async GET requests initiated by the JavaScript component
    <div id="spinner-container"
         data-initial-heading="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.initial.heading' | translate + serviceName }}"
         data-initial-spinnerStateText="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.initial.spinnerStateText' | translate }}"
         data-initial-spinnerState="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.initial.spinnerState' | translate }}"
         data-error-heading="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.heading' | translate }}"
         data-error-messageText="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.messageText' | translate }}"
         data-error-whatYouCanDo-heading="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.whatYouCanDo.heading' | translate }}"
         data-error-whatYouCanDo-message-text1="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.whatYouCanDo.message.text1' | translate }}"
         data-error-whatYouCanDo-message-link-href="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.whatYouCanDo.message.link.href' | translate }}"
         data-error-whatYouCanDo-message-link-text="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.whatYouCanDo.message.link.text' | translate }}"
         data-error-whatYouCanDo-message-text2="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.error.whatYouCanDo.message.text2' | translate }}"
         data-complete-spinnerState="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.complete.spinnerState' | translate }}"
         data-longWait-spinnerStateText="{{ 'pages.proveIdentityCheckNew.progressivelyEnhancedVersion.longWait.spinnerStateText' | translate }}"
    >
        <form action="/ipv-callback" method="post" novalidate="novalidate">
            <input type="hidden" name="_csrf" value="{{ csrfToken }}" />
            <div class="govuk-form-group">
                <h1 class="govuk-label-wrapper">
                    <label class="govuk-label govuk-label--l" for="more-detail">
                        {{ 'pages.proveIdentityCheckNew.htmlOnlyVersion.header' | translate }}
                    </label>
                </h1>
                <p class="govuk-body">{{ 'pages.proveIdentityCheckNew.htmlOnlyVersion.paragraph' | translate }}</p>
                <button type="submit" class="govuk-button">
                    {{ 'pages.proveIdentityCheckNew.htmlOnlyVersion.button' | translate }}
                </button>
            </div>
        </form>
    </div>

Installation

Install the package with

npm i @govuk-one-login/authentication-spinner

Include and defer a script tag in the HTML page with a src attribute referencing the distribution file (spinner-app.js in the dist directory). Including this script is all that is necessary to initialise the component.

How the authentication spinner works

1. Getting a reference to the required DOM element

When the component JavaScript runs in a user's browser, a DOM lookup is performed for an element with the id of spinner-container. This element is required as a mounting point for the component. If the DOM element is not found, the spinner will not run and the user can proceed to use the non-JavaScript version.

2. Initialising the spinner content

Where this element is found, it is passed as an argument to the Spinner constructor. The constructor will then try to populate the Spinner content attribute using data-* attributes found on the DOM element included in the server-rendered page (this approach has been taken so that content and language translations can be managed alongside other content in authentication frontend).

If any attribute is missing, the component will set domRequirementsMet to false, preventing state from being initialised and timers being set. As before, if this requirement is not met, nothing happens and the user can proceed to use the non-JavaScript version.

3. Initialising timers

The instantiated spinner is then initialised, beginning with initialising three timers:

  1. The informUserWhereWaitIsLong timer will update the spinner after a specified time to reflect a long wait
  2. The abortUnresponsiveRequest timer will abort the spinner, clear timers and render an error state after a specified time
  3. The updateDomTimer timer will update the DOM at set intervals to reflect any changes in the virtual DOM

The duration of these timers are set within the Spinner config property.

4. Perform initial update

Initialisation then proceeds to do an initial update of the DOM, replacing the server-rendered content with the JavaScript component.

5. Requesting ID processing status

Initialisation then proceeds to request the ID processing status. This uses recursive calls to this.requestIDProcessingStatus() at set intervals (as set in config), each of which initiates a fetch request for the processing status.

If a COMPLETED or INTERVENTION status is returned by the API, the component will be updated to reflect completion, the call to action will be enabled and further fetch requests will be prevented. Clicking the enabled call to action will result in the user making a synchronous POST request to the same route and server-side processing will determine if they can continue to the RP or be presented with a page reflecting an account intervention being in place.

If a status of ERROR is returned, the component is updated to reflect an error and further fetch requests are prevented.

If no fetch request has resulted in a status of COMPLETED or INTERVENTION after the time limits set in informUserWhereWaitIsLong and abortUnresponsiveRequest, their referenced functions will be called (updating the page and aborting the spinner to prevent further fetch requests respectively).