-
Notifications
You must be signed in to change notification settings - Fork 17
Add table of SMS/Voice support dynamically loaded from IDP #707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e568af2
fd8f7ea
430c712
6eb954c
54a812d
af97694
b3d947c
96c25c8
d7571a2
432b8c7
bd26f85
b6b456d
31c4cf7
e9df0dd
04371ae
c882cb4
f13af97
06e5b07
8e85293
a499537
f070897
5bcec6e
4e5bf14
f43ef83
e0a24df
3835aa1
af6dea4
cb1ef76
d6c3058
384236d
c5b0035
35ce65b
2593584
4285c71
7005704
2f0fb5d
88c9df0
06baa4b
f631155
82d11e9
5a7d4b0
72fba67
45212e9
bd799b9
0b272c8
da23b25
71a36b0
ac472fe
bebb949
4f179bf
5afc5bc
2d2c160
0b41650
b68f93b
66d6022
f564b71
91d5833
105b01b
5ebf732
ad842e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| {% comment %} | ||
| Should include these translations as includes: | ||
| - heading_country | ||
| - heading_dialing_code | ||
| - heading_sms | ||
| - heading_voice | ||
| - option_yes | ||
| - option_no | ||
| {% endcomment %} | ||
|
|
||
| <div | ||
| class="js-country-support" | ||
| data-idp-base-url="{{ site.idp_base_url }}" | ||
| data-translation-option-yes="{{ include.option_yes }}" | ||
| data-translation-option-no="{{ include.option_no }}" | ||
| hidden | ||
| > | ||
| <span hidden data-item="icon-success" class="svg-wrapper svg-success">{% include svg/font-awesome-check-circle-solid.svg %}</span> | ||
| <span hidden data-item="icon-error" class="svg-wrapper svg-error">{% include svg/font-awesome-times-circle-solid.svg %}</span> | ||
| <table class="usa-table--borderless usa-table--sticky-header"> | ||
| <thead> | ||
| <tr> | ||
| <th scope="col" class="usa-table--sticky-header--heading">{{ include.heading_country }}</th> | ||
| <th scope="col" class="usa-table--sticky-header--heading">{{ include.heading_dialing_code }}</th> | ||
| <th scope="col" class="usa-table--sticky-header--heading">{{ include.heading_sms }}</th> | ||
| <th scope="col" class="usa-table--sticky-header--heading">{{ include.heading_voice }}</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| <tr data-item="template-row"> | ||
| <td data-item="country"></td> | ||
| <td data-item="dialing-code"></td> | ||
| <td data-item="sms"> | ||
| <span class="margin-right-05" data-item="icon" aria-hidden="true"></span> | ||
| <span data-item="text"></span> | ||
| </td> | ||
| <td data-item="voice"> | ||
| <span class="margin-right-05" data-item="icon" aria-hidden="true"></span> | ||
| <span data-item="text"></span> | ||
| </td> | ||
| </tr> | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| .usa-table--sticky-header { | ||
| position: relative; | ||
|
|
||
| .usa-table--sticky-header--heading, | ||
| thead th.usa-table--sticky-header--heading { | ||
| background-color: $white; | ||
| position: sticky; | ||
| top: 0; | ||
| } | ||
| } | ||
|
zachmargolis marked this conversation as resolved.
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,3 +12,11 @@ | |
| fill: $grey; | ||
| } | ||
| } | ||
|
|
||
| .svg-success { | ||
| color: $success; | ||
| } | ||
|
|
||
| .svg-error { | ||
| color: $error; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,3 +18,5 @@ | |
| @import "layout"; | ||
| @import "box-info"; | ||
| @import "card"; | ||
|
|
||
| @import "sticky-table"; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| /** | ||
| * @typedef Country | ||
| * @property {string} name | ||
| * @property {string} country_code The international dialing code (ex "1" for the US) | ||
| * @property {boolean} supports_sms | ||
| * @property {boolean} supports_voice | ||
| */ | ||
|
|
||
| /** | ||
| * @typedef CountrySupport | ||
| * @property {Record<string,Country>} countries | ||
| */ | ||
|
|
||
| /** | ||
| * @example | ||
| * prettyDialingCode('1') => '+1' | ||
| * prettyDialingCode('1234') => '+1-234' | ||
| * prettyDialingCode('789') => '+789' | ||
| * @param {string} dialingCode | ||
| * @return {string} | ||
| */ | ||
| const prettyDialingCode = (dialingCode) => { | ||
| if (dialingCode.length > 1 && dialingCode.indexOf('1') === 0) { | ||
| return `+1-${dialingCode.slice(1)}`; | ||
| } | ||
| return `+${dialingCode}`; | ||
| }; | ||
|
|
||
| /** | ||
| * @typedef {(input: RequestInfo, init?: RequestInit) => Promise<Response>} Fetch | ||
| */ | ||
|
|
||
| /** | ||
| * @param {HTMLElement} elem | ||
| * @param {Fetch} fetch | ||
| */ | ||
| function loadCountrySupportTable(elem, fetch) { | ||
| const tbody = elem.querySelector('tbody'); | ||
| const templateRow = elem.querySelector('[data-item=template-row]'); | ||
| const successIcon = elem.querySelector('[data-item=icon-success]'); | ||
| const errorIcon = elem.querySelector('[data-item=icon-error]'); | ||
| if (!tbody || !templateRow || !successIcon || !errorIcon) { | ||
| return; | ||
| } | ||
|
|
||
| const { idpBaseUrl, translationOptionYes, translationOptionNo } = elem.dataset; | ||
|
|
||
| /** | ||
| * @param {HTMLElement} cell | ||
| * @param {boolean} enabled | ||
| */ | ||
| const updateCell = (cell, enabled) => { | ||
| cell.querySelector('[data-item=text]').innerText = enabled | ||
| ? translationOptionYes | ||
| : translationOptionNo; | ||
|
|
||
| const clonedIcon = (enabled ? successIcon : errorIcon).cloneNode(true); | ||
| clonedIcon.hidden = false; | ||
| cell.querySelector('[data-item=icon]').appendChild(clonedIcon); | ||
| }; | ||
|
|
||
| fetch(`${idpBaseUrl || ''}/api/country-support`) | ||
| .then((response) => response.json()) | ||
| .then((/** @type {CountrySupport} */ { countries }) => { | ||
| Object.entries(countries) | ||
| .sort(([_isoCodeA, { name: a }], [_isoCodeB, { name: b }]) => a.localeCompare(b)) | ||
| .forEach( | ||
| ([ | ||
| isoCode, | ||
| { | ||
| name, | ||
| country_code: countryCode, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One thing we may consider in the future is to have the API respond with locale-translated country names? For example, Germany is "Allemagne" in French, but currently we show all country names in English.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes definitely! The IDP itself only has English names right now, but that is a great idea. In the meantime we do that the ISO country codes too
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I bet we're probably showing English names in some of our translated alert texts. Thinking ones like this in particular: I'll plan to confirm and create a ticket as necessary.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For posterity: LG-5321 |
||
| supports_sms: supportsSms, | ||
| supports_voice: supportsVoice, | ||
| }, | ||
| ]) => { | ||
| const row = templateRow.cloneNode(true); | ||
|
|
||
| row.querySelector('[data-item=country]').innerText = `${name} (${isoCode})`; | ||
| row.querySelector('[data-item=dialing-code]').innerText = prettyDialingCode( | ||
| countryCode, | ||
| ); | ||
| updateCell(row.querySelector('[data-item=sms]'), supportsSms); | ||
| updateCell(row.querySelector('[data-item=voice]'), supportsVoice); | ||
| tbody.appendChild(row); | ||
| }, | ||
| ); | ||
|
|
||
| tbody.removeChild(templateRow); | ||
| elem.hidden = false; | ||
| }); | ||
| } | ||
|
|
||
| /** @type {Promise<Fetch>} */ | ||
| const fetchPromise = | ||
| 'fetch' in window | ||
| ? new Promise((resolve) => resolve(window.fetch)) | ||
| : import(/* webpackChunkName: "whatwg-fetch" */ 'whatwg-fetch').then(({ fetch }) => fetch); | ||
|
|
||
| fetchPromise.then((fetch) => { | ||
| Array.from(document.querySelectorAll('.js-country-support')).forEach((elem) => | ||
| loadCountrySupportTable(elem, fetch), | ||
| ); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,23 @@ | ||
| { | ||
| "presets": [["@babel/preset-env", { "targets": { "ie": "11" } }]], | ||
| "presets": [ | ||
| [ | ||
| "@babel/preset-env", | ||
| { | ||
| "useBuiltIns": "usage", | ||
| "corejs": 3, | ||
| "targets": { "ie": "11" } | ||
| } | ||
| ] | ||
| ], | ||
| "env": { | ||
| "test": { | ||
| "presets": [["@babel/preset-env", { "targets": { "node": "current" } }]] | ||
| } | ||
| } | ||
| }, | ||
| "overrides": [ | ||
| { | ||
| "test": "node_modules", | ||
| "sourceType": "unambiguous" | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| layout: help | ||
| title: International phone number support | ||
| category: manage-your-account | ||
| order: 5 | ||
| scripts: | ||
| - /assets/js/build/country_support.js | ||
| --- | ||
|
|
||
| <noscript> | ||
| We need JavaScript in order to load the list of supported countries. | ||
| </noscript> | ||
|
|
||
| {% include country_support_table.html | ||
| heading_country="Country" | ||
| heading_dialing_code="Dialing Code" | ||
| heading_sms="Supports SMS" | ||
| heading_voice="Supports Voice" | ||
| option_yes="Yes" | ||
| option_no="No" %} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| layout: help | ||
| title: Soporte de número de teléfono internacional | ||
| category: manage-your-account | ||
| order: 5 | ||
| scripts: | ||
| - /assets/js/build/country_support.js | ||
| --- | ||
|
|
||
| <noscript> | ||
| Necesitamos JavaScript para cargar la lista de países admitidos. | ||
| </noscript> | ||
|
|
||
| {% include country_support_table.html | ||
| heading_country="País" | ||
| heading_dialing_code="Codigo para marcar" | ||
| heading_sms="Compatible con SMS" | ||
| heading_voice="Admite marcación por voz" | ||
| option_yes="Sí" | ||
| option_no="No" %} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| layout: help | ||
| title: Prise en charge des numéros de téléphone internationaux | ||
| category: manage-your-account | ||
| order: 5 | ||
| scripts: | ||
| - /assets/js/build/country_support.js | ||
| --- | ||
|
|
||
| <noscript> | ||
| Nous avons besoin de JavaScript pour charger la liste des pays pris en charge. | ||
| </noscript> | ||
|
|
||
| {% include country_support_table.html | ||
| heading_country="Pays" | ||
| heading_dialing_code="Indicatif" | ||
| heading_sms="Prend en charge les SMS" | ||
| heading_voice="Prend en charge la numérotation vocale" | ||
| option_yes="Oui" | ||
| option_no="Non" %} |
Uh oh!
There was an error while loading. Please reload this page.