2025-10-06 09:38:54 -04:00
( function ( window ) {
2018-11-28 17:40:54 +00:00
"use strict" ;
2025-10-24 13:19:02 -04:00
// HTML escaping utility to prevent XSS
const escapeHtml = ( unsafe ) => {
if ( ! unsafe ) return '' ;
return String ( unsafe )
. replace ( /&/g , "&" )
. replace ( /</g , "<" )
. replace ( />/g , ">" )
. replace ( /"/g , """ )
. replace ( /'/g , "'" ) ;
} ;
2025-10-06 09:38:54 -04:00
window . NotifyModules [ 'template-folder-form' ] = function ( ) {
2018-11-28 17:40:54 +00:00
this . start = function ( templateFolderForm ) {
2025-10-24 13:19:02 -04:00
this . form = templateFolderForm ;
2018-11-28 17:40:54 +00:00
remove the unknown button in js
When you hit enter while an input in a form is in focus, your browser
finds the first button in the form, and carries out that action. So,
for non-js users, we added a hidden submit button with a value of
"unknown" to reflect that we don't know the intention of the user.
However, with JS enabled, this ambiguity doesn't exist - there's only
submit button and forms to fill in at a time, and non-visible fields
aren't even submitted at all. We can remove the unknown button,
supporting enter as submit properly. If the user is on one of the grey
button states, with no submit, it'll press the first button, and go to
the new template / move to existing folder dialog. That's fine enough.
2018-12-05 13:48:07 +00:00
// remove the hidden unknown button - if you've got JS enabled then the action you want to do is implied by
// which field is visible.
2025-10-24 13:19:02 -04:00
const unknownButton = this . form . querySelector ( 'button[value=unknown]' ) ;
if ( unknownButton ) {
unknownButton . remove ( ) ;
}
remove the unknown button in js
When you hit enter while an input in a form is in focus, your browser
finds the first button in the form, and carries out that action. So,
for non-js users, we added a hidden submit button with a value of
"unknown" to reflect that we don't know the intention of the user.
However, with JS enabled, this ambiguity doesn't exist - there's only
submit button and forms to fill in at a time, and non-visible fields
aren't even submitted at all. We can remove the unknown button,
supporting enter as submit properly. If the user is on one of the grey
button states, with no submit, it'll press the first button, and go to
the new template / move to existing folder dialog. That's fine enough.
2018-12-05 13:48:07 +00:00
2025-10-24 13:19:02 -04:00
this . liveRegionCounter = this . form . querySelector ( '.selection-counter' ) ;
// Critical: Verify live region counter exists before proceeding
if ( ! this . liveRegionCounter ) {
console . error ( 'templateFolderForm: .selection-counter element not found' ) ;
return ;
}
2018-11-28 17:40:54 +00:00
2025-10-14 13:20:58 -04:00
// Get single channel data from DOM (must happen after DOM is ready)
const addNewTemplateForm = document . querySelector ( 'div[id=add_new_template_form]' ) ;
2025-10-24 13:19:02 -04:00
this . singleNotificationChannel = addNewTemplateForm ? addNewTemplateForm . getAttribute ( "data-channel" ) : null ;
this . singleChannelService = addNewTemplateForm ? addNewTemplateForm . getAttribute ( "data-service" ) : null ;
2025-10-14 13:20:58 -04:00
2025-10-24 13:19:02 -04:00
this . liveRegionCounter . insertAdjacentElement ( 'beforebegin' , this . nothingSelectedButtons ) ;
this . liveRegionCounter . insertAdjacentElement ( 'beforebegin' , this . itemsSelectedButtons ) ;
2018-11-28 17:40:54 +00:00
2025-10-24 13:19:02 -04:00
// all the diff states that we want to show or hide - using Map for better performance
2018-12-04 14:48:39 +00:00
this . states = [
2020-09-22 11:45:55 +01:00
{
key : 'nothing-selected-buttons' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#nothing_selected' ) ,
2020-09-22 11:45:55 +01:00
cancellable : false
} ,
{
key : 'items-selected-buttons' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#items_selected' ) ,
2020-09-22 11:45:55 +01:00
cancellable : false
} ,
{
key : 'move-to-existing-folder' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#move_to_folder_radios' ) ,
2020-09-22 11:45:55 +01:00
cancellable : true ,
2025-10-24 13:19:02 -04:00
setFocus : ( ) => {
const el = document . getElementById ( 'move_to_folder_radios' ) ;
if ( el ) el . focus ( ) ;
} ,
2020-09-22 11:45:55 +01:00
action : 'move to folder' ,
description : 'Press move to confirm or cancel to close'
} ,
{
key : 'move-to-new-folder' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#move_to_new_folder_form' ) ,
2020-09-22 11:45:55 +01:00
cancellable : true ,
2025-10-24 13:19:02 -04:00
setFocus : ( ) => {
const el = document . getElementById ( 'move_to_new_folder_form' ) ;
if ( el ) el . focus ( ) ;
} ,
2020-09-22 11:45:55 +01:00
action : 'move to new folder' ,
description : 'Press add to new folder to confirm name or cancel to close'
} ,
{
key : 'add-new-folder' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#add_new_folder_form' ) ,
2020-09-22 11:45:55 +01:00
cancellable : true ,
2025-10-24 13:19:02 -04:00
setFocus : ( ) => {
const el = document . getElementById ( 'add_new_folder_form' ) ;
if ( el ) el . focus ( ) ;
} ,
2020-09-22 11:45:55 +01:00
action : 'new folder' ,
description : 'Press add new folder to confirm name or cancel to close'
} ,
{
key : 'add-new-template' ,
2025-10-24 13:19:02 -04:00
el : this . form . querySelector ( '#add_new_template_form' ) ,
2020-09-22 11:45:55 +01:00
cancellable : true ,
2025-10-24 13:19:02 -04:00
setFocus : ( ) => {
const el = document . getElementById ( 'add_new_template_form' ) ;
if ( el ) el . focus ( ) ;
} ,
2020-09-22 11:45:55 +01:00
action : 'new template' ,
description : 'Press continue to confirm selection or cancel to close'
}
2018-12-04 14:48:39 +00:00
] ;
2018-11-29 17:39:58 +00:00
2018-12-10 16:53:12 +00:00
// cancel/clear buttons only relevant if JS enabled, so
2018-12-04 14:48:39 +00:00
this . states . filter ( state => state . cancellable ) . forEach ( ( x ) => this . addCancelButton ( x ) ) ;
2018-12-10 16:53:12 +00:00
this . states . filter ( state => state . key === 'items-selected-buttons' ) . forEach ( x => this . addClearButton ( x ) ) ;
2018-11-30 12:02:51 +00:00
2025-10-24 13:19:02 -04:00
// make elements focusable
this . states . filter ( state => state . setFocus ) . forEach ( x => {
if ( x . el ) {
x . el . setAttribute ( 'tabindex' , '0' ) ;
}
} ) ;
2020-09-22 11:45:55 +01:00
this . addDescriptionsToStates ( ) ;
2019-01-17 10:52:13 +00:00
// activate stickiness of elements in each state
this . activateStickyElements ( ) ;
2018-11-29 16:20:44 +00:00
// first off show the new template / new folder buttons
2025-10-24 13:19:02 -04:00
this . _lastState = this . form . dataset . prevState ;
2019-03-20 14:04:06 +00:00
if ( this . _lastState === undefined ) {
2019-02-13 16:43:38 +00:00
this . selectActionButtons ( ) ;
2018-12-19 15:24:48 +00:00
} else {
2019-03-20 14:04:06 +00:00
this . currentState = this . _lastState ;
2018-12-19 15:24:48 +00:00
this . render ( ) ;
2018-12-05 12:01:02 +00:00
}
2018-11-29 16:20:44 +00:00
2025-10-24 13:19:02 -04:00
this . form . addEventListener ( 'click' , ( event ) => {
const button = event . target . closest ( 'button.usa-button' ) ;
if ( button ) {
this . actionButtonClicked ( event ) ;
}
} ) ;
this . form . addEventListener ( 'change' , ( event ) => {
if ( event . target . matches ( 'input[type=checkbox]' ) ) {
this . templateFolderCheckboxChanged ( ) ;
} else if ( event . target . matches ( 'input[name="add_template_by_template_type"]' ) ) {
this . templateTypeChanged ( ) ;
}
} ) ;
2018-11-29 16:20:44 +00:00
} ;
2020-09-22 11:45:55 +01:00
this . addDescriptionsToStates = function ( ) {
2025-10-24 13:19:02 -04:00
this . states . filter ( state => 'description' in state ) . forEach ( state => {
const id = ` ${ escapeHtml ( state . key ) } __description ` ;
const description = ` <p class="usa-sr-only" id=" ${ id } "> ${ escapeHtml ( state . description ) } </p> ` ;
if ( state . el ) {
state . el . insertAdjacentHTML ( 'afterbegin' , description ) ;
state . el . setAttribute ( 'aria-describedby' , id ) ;
}
2020-09-22 11:45:55 +01:00
} ) ;
2019-01-29 15:53:59 +00:00
} ;
2019-01-17 10:52:13 +00:00
this . activateStickyElements = function ( ) {
2025-10-24 13:19:02 -04:00
const oldClass = 'js-will-stick-at-bottom-when-scrolling' ;
const newClass = 'js-stick-at-bottom-when-scrolling' ;
2019-01-17 10:52:13 +00:00
this . states . forEach ( state => {
2025-10-24 13:19:02 -04:00
if ( state . el ) {
state . el . querySelectorAll ( '.' + oldClass ) . forEach ( el => {
el . classList . remove ( oldClass ) ;
el . classList . add ( newClass ) ;
} ) ;
}
2019-01-17 10:52:13 +00:00
} ) ;
} ;
2018-12-04 14:48:39 +00:00
this . addCancelButton = function ( state ) {
2025-10-24 13:19:02 -04:00
const selector = ` [value= ${ state . key } ] ` ;
const cancel = this . makeButton ( 'Cancel' , {
2019-02-15 16:10:01 +00:00
'onclick' : ( ) => {
// clear existing data
2025-10-24 13:19:02 -04:00
if ( state . el ) {
state . el . querySelectorAll ( 'input[type="radio"]' ) . forEach ( input => input . checked = false ) ;
state . el . querySelectorAll ( 'input[type="text"]' ) . forEach ( input => input . value = '' ) ;
}
2019-02-15 16:10:01 +00:00
// go back to action buttons
this . selectActionButtons ( selector ) ;
} ,
'cancelSelector' : selector ,
2020-09-21 20:27:47 +01:00
'nonvisualText' : state . action
2019-02-15 16:10:01 +00:00
} ) ;
2018-11-30 12:02:51 +00:00
2025-10-24 13:19:02 -04:00
if ( state . el ) {
const submitButton = state . el . querySelector ( '[type=submit]' ) ;
if ( submitButton ) {
submitButton . insertAdjacentElement ( 'afterend' , cancel ) ;
}
}
2018-11-30 12:02:51 +00:00
} ;
2018-12-10 16:53:12 +00:00
this . addClearButton = function ( state ) {
2025-10-24 13:19:02 -04:00
const selector = 'button[value=add-new-template]' ;
const clear = this . makeButton ( 'Clear' , {
2019-02-15 16:10:01 +00:00
'onclick' : ( ) => {
// uncheck all templates and folders
2025-10-24 13:19:02 -04:00
this . form . querySelectorAll ( 'input[type="checkbox"]' ) . forEach ( input => input . checked = false ) ;
2018-12-10 16:53:12 +00:00
2019-02-15 16:10:01 +00:00
// go back to action buttons
this . selectActionButtons ( selector ) ;
} ,
'nonvisualText' : "selection"
2018-12-10 16:53:12 +00:00
} ) ;
2025-10-24 13:19:02 -04:00
if ( state . el ) {
const counter = state . el . querySelector ( '.template-list-selected-counter' ) ;
if ( counter ) {
counter . appendChild ( clear ) ;
}
}
2018-12-10 16:53:12 +00:00
} ;
2019-02-15 16:10:01 +00:00
this . makeButton = ( text , opts ) => {
2025-10-24 13:19:02 -04:00
const btn = document . createElement ( 'a' ) ;
btn . href = '' ;
btn . textContent = text ;
btn . classList . add ( 'usa-link' , 'js-cancel' ) ;
// isn't set if cancelSelector is undefined
if ( opts . cancelSelector ) {
btn . dataset . target = opts . cancelSelector ;
}
btn . setAttribute ( 'tabindex' , '0' ) ;
const handler = event => {
// space, enter or no keyCode (must be mouse input)
if ( [ 13 , 32 , undefined ] . indexOf ( event . keyCode ) > - 1 ) {
event . preventDefault ( ) ;
if ( opts . hasOwnProperty ( 'onclick' ) ) {
opts . onclick ( ) ;
}
2018-12-10 17:32:36 +00:00
}
2025-10-24 13:19:02 -04:00
} ;
btn . addEventListener ( 'click' , handler ) ;
btn . addEventListener ( 'keydown' , handler ) ;
if ( opts . hasOwnProperty ( 'nonvisualText' ) ) {
const span = document . createElement ( 'span' ) ;
span . className = 'usa-sr-only' ;
span . textContent = ' ' + opts . nonvisualText ;
btn . appendChild ( span ) ;
}
2019-02-15 16:10:01 +00:00
2025-10-24 13:19:02 -04:00
return btn ;
2019-02-15 16:10:01 +00:00
} ;
2018-12-10 16:53:12 +00:00
2019-02-01 16:13:04 +00:00
this . selectActionButtons = function ( targetSelector ) {
2018-12-05 12:01:02 +00:00
// If we want to show one of the grey choose actions state, we can pretend we're in the choose actions state,
// and then pretend a checkbox was clicked to work out whether to show zero or non-zero options.
// This calls a render at the end
this . currentState = 'nothing-selected-buttons' ;
this . templateFolderCheckboxChanged ( ) ;
2019-02-01 16:13:04 +00:00
if ( targetSelector ) {
2025-10-24 13:19:02 -04:00
const target = document . querySelector ( targetSelector ) ;
if ( target ) {
target . focus ( ) ;
}
2019-02-01 16:13:04 +00:00
}
2018-12-05 12:01:02 +00:00
} ;
2019-03-20 14:04:06 +00:00
// method that checks the state against the last one, used prior to render() to see if needed
this . stateChanged = function ( ) {
let changed = this . currentState !== this . _lastState ;
this . _lastState = this . currentState ;
return changed ;
} ;
2018-11-29 17:39:58 +00:00
this . actionButtonClicked = function ( event ) {
2025-10-24 13:19:02 -04:00
const button = event . target . closest ( 'button.usa-button' ) || event . target ;
this . currentState = button . value ;
2018-11-29 17:39:58 +00:00
2025-10-24 13:19:02 -04:00
if ( this . currentState === 'add-new-template' && this . singleNotificationChannel ) {
2025-10-06 09:38:54 -04:00
event . preventDefault ( ) ;
2025-10-29 09:49:44 -04:00
window . location = "/services/" + encodeURIComponent ( this . singleChannelService ) + "/templates/add-" + encodeURIComponent ( this . singleNotificationChannel ) ;
2025-10-06 09:38:54 -04:00
} else if ( this . currentState === 'add-new-template' ) {
// Check if a template type is selected
2025-10-24 13:19:02 -04:00
const selectedInput = this . form . querySelector ( 'input[name="add_template_by_template_type"]:checked' ) ;
const selectedTemplateType = selectedInput ? selectedInput . value : null ;
2025-10-06 09:38:54 -04:00
if ( selectedTemplateType ) {
// Template type is selected, let the form submit normally
return true ;
} else {
// No template type selected, show the selection UI
event . preventDefault ( ) ;
2025-10-24 13:19:02 -04:00
this . form . querySelectorAll ( 'input[type=checkbox]' ) . forEach ( input => input . checked = false ) ;
2025-06-09 16:35:01 -07:00
this . selectionStatus . update ( { total : 0 , templates : 0 , folders : 0 } ) ;
2025-10-06 09:38:54 -04:00
if ( this . stateChanged ( ) ) {
this . render ( ) ;
}
}
} else {
2025-10-14 13:20:58 -04:00
// If state is not changing, this is a submit button - allow form submission
if ( this . currentState === this . _lastState ) {
return true ;
}
// Otherwise, show the form UI
2025-10-06 09:38:54 -04:00
event . preventDefault ( ) ;
2020-08-10 18:14:36 +01:00
if ( this . stateChanged ( ) ) {
this . render ( ) ;
2020-08-11 15:44:17 +01:00
}
}
2018-11-29 17:39:58 +00:00
} ;
2019-02-13 17:47:24 +00:00
this . selectionStatus = {
'default' : 'Nothing selected' ,
2020-09-18 11:51:56 +01:00
'selected' : numSelected => {
const getString = key => {
if ( numSelected [ key ] === 0 ) {
return '' ;
} else if ( numSelected [ key ] === 1 ) {
return ` 1 ${ key . substring ( 0 , key . length - 1 ) } ` ;
} else {
return ` ${ numSelected [ key ] } ${ key } ` ;
}
} ;
const results = [ ] ;
if ( numSelected . templates > 0 ) {
results . push ( getString ( 'templates' ) ) ;
}
if ( numSelected . folders > 0 ) {
results . push ( getString ( 'folders' ) ) ;
}
return results . join ( ', ' ) + ' selected' ;
} ,
2019-02-13 17:47:24 +00:00
'update' : numSelected => {
2025-10-24 13:19:02 -04:00
const message = ( numSelected . total > 0 ) ? this . selectionStatus . selected ( numSelected ) : this . selectionStatus . default ;
2019-02-13 17:47:24 +00:00
2025-10-24 13:19:02 -04:00
const counters = document . querySelectorAll ( '.template-list-selected-counter__count' ) ;
counters . forEach ( counter => counter . textContent = message ) ;
if ( this . liveRegionCounter ) {
this . liveRegionCounter . textContent = message ;
}
2019-02-13 17:47:24 +00:00
}
} ;
2018-11-29 17:39:58 +00:00
this . templateFolderCheckboxChanged = function ( ) {
2025-10-24 13:19:02 -04:00
const numSelected = this . countSelectedCheckboxes ( ) ;
2018-11-29 16:20:44 +00:00
2020-09-18 11:51:56 +01:00
if ( this . currentState === 'nothing-selected-buttons' && numSelected . total !== 0 ) {
2018-11-30 16:29:00 +00:00
// user has just selected first item
2018-12-04 14:47:05 +00:00
this . currentState = 'items-selected-buttons' ;
2020-09-18 11:51:56 +01:00
} else if ( this . currentState === 'items-selected-buttons' && numSelected . total === 0 ) {
2018-11-30 16:29:00 +00:00
// user has just deselected last item
2018-12-04 14:47:05 +00:00
this . currentState = 'nothing-selected-buttons' ;
2018-11-29 16:20:44 +00:00
}
2018-11-28 17:40:54 +00:00
2019-03-20 14:04:06 +00:00
if ( this . stateChanged ( ) ) {
this . render ( ) ;
}
2018-12-10 16:53:12 +00:00
2019-02-13 17:47:24 +00:00
this . selectionStatus . update ( numSelected ) ;
2018-12-10 16:53:12 +00:00
2025-10-24 13:19:02 -04:00
const counters = document . querySelectorAll ( '.template-list-selected-counter' ) ;
const shouldShow = this . hasCheckboxes ( ) ;
counters . forEach ( counter => {
counter . style . display = shouldShow ? '' : 'none' ;
} ) ;
2019-01-03 10:50:05 +00:00
} ;
2025-10-06 09:38:54 -04:00
this . templateTypeChanged = function ( ) {
this . updateContinueButtonState ( ) ;
} ;
this . updateContinueButtonState = function ( ) {
2025-10-24 13:19:02 -04:00
const selectedInput = this . form . querySelector ( 'input[name="add_template_by_template_type"]:checked' ) ;
const selectedTemplateType = selectedInput ? selectedInput . value : null ;
const continueButton = this . form . querySelector ( '#add_new_template_form button[value="add-new-template"]' ) ;
2025-10-06 09:38:54 -04:00
2025-10-24 13:19:02 -04:00
if ( continueButton ) {
continueButton . disabled = ! selectedTemplateType ;
2025-10-06 09:38:54 -04:00
}
} ;
2019-01-03 10:50:05 +00:00
this . hasCheckboxes = function ( ) {
2025-10-24 13:19:02 -04:00
return this . form . querySelectorAll ( 'input[type="checkbox"]' ) . length > 0 ;
2018-11-28 17:40:54 +00:00
} ;
this . countSelectedCheckboxes = function ( ) {
2025-10-24 13:19:02 -04:00
const allSelected = Array . from ( this . form . querySelectorAll ( 'input[type="checkbox"]:checked' ) ) ;
// Check for sibling elements to determine if checkbox is for template or folder
// This matches the original jQuery logic: $(el).siblings('.template-list-template')
const templates = allSelected . filter ( el => {
if ( ! el . parentElement ) return false ;
return el . parentElement . querySelector ( '.template-list-template' ) !== null ;
} ) . length ;
const folders = allSelected . filter ( el => {
if ( ! el . parentElement ) return false ;
return el . parentElement . querySelector ( '.template-list-folder' ) !== null ;
} ) . length ;
2020-09-18 11:51:56 +01:00
const results = {
'templates' : templates ,
'folders' : folders ,
'total' : allSelected . length
} ;
return results ;
2018-11-28 17:40:54 +00:00
} ;
this . render = function ( ) {
2025-10-24 13:19:02 -04:00
const currentStateObj = this . states . find ( state => state . key === this . currentState ) ;
2020-09-22 11:45:55 +01:00
let scrollTop ;
2019-01-30 19:12:14 +00:00
2018-11-29 17:39:58 +00:00
// detach everything, unless they are the currentState
2025-10-24 13:19:02 -04:00
this . states . forEach ( state => {
if ( state . key === this . currentState ) {
if ( state . el ) {
this . liveRegionCounter . insertAdjacentElement ( 'beforebegin' , state . el ) ;
}
} else {
if ( state . el && state . el . parentElement ) {
state . el . remove ( ) ;
}
}
} ) ;
2018-12-13 14:25:22 +00:00
2025-06-09 16:35:01 -07:00
if ( this . currentState === 'add-new-template' ) {
2025-10-24 13:19:02 -04:00
this . form . querySelectorAll ( '.template-list-item' ) . forEach ( el => el . classList . add ( 'js-hidden' ) ) ;
const liveSearch = document . querySelector ( '.live-search' ) ;
if ( liveSearch ) liveSearch . classList . add ( 'js-hidden' ) ;
const breadcrumb = document . getElementById ( 'breadcrumb-template-folders' ) ;
if ( breadcrumb ) breadcrumb . classList . add ( 'js-hidden' ) ;
const templateList = document . getElementById ( 'template-list' ) ;
if ( templateList ) templateList . classList . add ( 'js-hidden' ) ;
this . form . querySelectorAll ( 'input[type=checkbox]' ) . forEach ( input => input . checked = false ) ;
2025-06-09 16:35:01 -07:00
this . selectionStatus . update ( { total : 0 , templates : 0 , folders : 0 } ) ;
2025-06-11 14:09:17 -07:00
2025-10-24 13:19:02 -04:00
const pageTitle = document . getElementById ( 'page-title' ) ;
if ( pageTitle ) pageTitle . textContent = 'New Template' ;
const pageDescription = document . getElementById ( 'page-description' ) ;
if ( pageDescription ) pageDescription . textContent = 'Every message starts with a template. Choose to start with a blank template or copy an existing template.' ;
2025-06-11 14:09:17 -07:00
document . title = 'New Templates' ;
2025-10-06 09:38:54 -04:00
// Disable Continue button initially and update based on selection
this . updateContinueButtonState ( ) ;
2025-06-09 16:35:01 -07:00
} else {
2025-10-24 13:19:02 -04:00
this . form . querySelectorAll ( '.template-list-item' ) . forEach ( el => el . classList . remove ( 'js-hidden' ) ) ;
const liveSearch = document . querySelector ( '.live-search' ) ;
if ( liveSearch ) liveSearch . classList . remove ( 'js-hidden' ) ;
const breadcrumb = document . getElementById ( 'breadcrumb-template-folders' ) ;
if ( breadcrumb ) breadcrumb . classList . remove ( 'js-hidden' ) ;
const templateList = document . getElementById ( 'template-list' ) ;
if ( templateList ) templateList . classList . remove ( 'js-hidden' ) ;
const pageTitle = document . getElementById ( 'page-title' ) ;
if ( pageTitle ) pageTitle . textContent = 'Select or create a template' ;
const pageDescription = document . getElementById ( 'page-description' ) ;
if ( pageDescription ) pageDescription . textContent = 'Every message starts with a template. To send, choose or create a template.' ;
2025-06-11 14:09:17 -07:00
document . title = 'Select or create a template' ;
2025-06-09 16:35:01 -07:00
}
if ( currentStateObj && 'setFocus' in currentStateObj ) {
2025-10-24 13:19:02 -04:00
scrollTop = window . scrollY ;
2020-09-22 11:45:55 +01:00
currentStateObj . setFocus ( ) ;
2025-10-24 13:19:02 -04:00
window . scrollTo ( window . scrollX , scrollTop ) ;
2020-09-22 11:45:55 +01:00
}
2018-11-28 17:40:54 +00:00
} ;
2025-10-24 13:19:02 -04:00
const createNothingSelectedButtons = ( ) => {
const div = document . createElement ( 'div' ) ;
div . id = 'nothing_selected' ;
div . innerHTML = `
2019-01-25 16:47:49 +00:00
< div class = "js-stick-at-bottom-when-scrolling" >
2023-07-12 15:43:21 -04:00
< div class = "usa-button-group" >
2025-10-06 09:38:54 -04:00
< button class = "usa-button" value = "add-new-template" aria - expanded = "false" role = "button" >
2023-07-12 15:43:21 -04:00
New template
< / b u t t o n >
2025-10-06 09:38:54 -04:00
< button class = "usa-button usa-button--outline" value = "add-new-folder" aria - expanded = "false" role = "button" >
New folder
< / b u t t o n >
2023-07-12 15:43:21 -04:00
< / d i v >
2019-02-15 13:49:49 +00:00
< div class = "template-list-selected-counter" >
< span class = "template-list-selected-counter__count" aria - hidden = "true" >
$ { this . selectionStatus . default }
< / s p a n >
2019-01-25 16:47:49 +00:00
< / d i v >
2018-12-10 16:53:12 +00:00
< / d i v >
2025-10-24 13:19:02 -04:00
` ;
return div ;
} ;
2018-11-30 16:29:00 +00:00
2025-10-24 13:19:02 -04:00
const createItemsSelectedButtons = ( ) => {
const div = document . createElement ( 'div' ) ;
div . id = 'items_selected' ;
div . innerHTML = `
2019-01-25 16:47:49 +00:00
< div class = "js-stick-at-bottom-when-scrolling" >
2023-07-12 15:43:21 -04:00
< div class = "usa-button-group" >
2025-10-06 09:38:54 -04:00
< button class = "usa-button" value = "move-to-existing-folder" aria - expanded = "false" role = "button" >
2023-07-12 15:43:21 -04:00
Move < span class = "usa-sr-only" > selection to folder < / s p a n >
< / b u t t o n >
2025-10-06 09:38:54 -04:00
< button class = "usa-button usa-button--outline" value = "move-to-new-folder" aria - expanded = "false" role = "button" >
Add to new folder
< / b u t t o n >
2023-07-12 15:43:21 -04:00
< / d i v >
2019-02-15 11:03:22 +00:00
< div class = "template-list-selected-counter" aria - hidden = "true" >
2025-10-06 09:38:54 -04:00
< span class = "template-list-selected-counter__count text-base" aria - hidden = "true" >
2025-10-24 13:19:02 -04:00
$ { this . selectionStatus . selected ( { templates : 1 , folders : 0 , total : 1 } ) }
2019-02-15 13:49:49 +00:00
< / s p a n >
2019-01-25 16:47:49 +00:00
< / d i v >
2018-12-10 16:53:12 +00:00
< / d i v >
2025-10-24 13:19:02 -04:00
` ;
return div ;
} ;
this . nothingSelectedButtons = createNothingSelectedButtons ( ) ;
this . itemsSelectedButtons = createItemsSelectedButtons ( ) ;
2018-11-28 17:40:54 +00:00
} ;
2025-10-06 09:38:54 -04:00
} ) ( window ) ;