diff --git a/package-lock.json b/package-lock.json
index 2a3bb7696d..53388a5732 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8911,6 +8911,33 @@
"url": "https://opencollective.com/popperjs"
}
},
+ "node_modules/@prettier/plugin-pug": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@prettier/plugin-pug/-/plugin-pug-3.4.0.tgz",
+ "integrity": "sha512-Jzd5rE/ellJz3vqfxyVewPsCHXw1dmIzJ3AXhAnqVBKQOj2u73ZS2oUacji8CbQSsYyCy7GXFjXWDlDTMG1x2g==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/Shinigami92"
+ },
+ {
+ "type": "paypal",
+ "url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "pug-lexer": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=9.0.0"
+ },
+ "peerDependencies": {
+ "prettier": "^3.0.0"
+ }
+ },
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -45272,6 +45299,7 @@
"@pollyjs/adapter-node-http": "^6.0.6",
"@pollyjs/core": "^6.0.6",
"@pollyjs/persister-fs": "^6.0.6",
+ "@prettier/plugin-pug": "^3.4.0",
"@replit/codemirror-emacs": "overleaf/codemirror-emacs#4394c03858f27053f8768258e9493866e06e938e",
"@replit/codemirror-indentation-markers": "overleaf/codemirror-indentation-markers#78264032eb286bc47871569ae87bff5ca1c6c161",
"@replit/codemirror-vim": "overleaf/codemirror-vim#1bef138382d948018f3f9b8a4d7a70ab61774e4b",
diff --git a/services/web/.prettierignore b/services/web/.prettierignore
index 94ab5579c2..2e8db8b35b 100644
--- a/services/web/.prettierignore
+++ b/services/web/.prettierignore
@@ -13,3 +13,28 @@ frontend/js/features/source-editor/lezer-latex/latex.terms.mjs
frontend/js/features/source-editor/lezer-bibtex/bibtex.mjs
frontend/js/features/source-editor/lezer-bibtex/bibtex.terms.mjs
frontend/js/features/source-editor/hunspell/wasm/hunspell.mjs
+
+# complex pages
+app/views/project/editor.pug
+app/views/project/editor/**
+modules/open-in-overleaf/app/views/documentation.pug
+modules/references-search/app/views/project/editor/**
+modules/rich-text/app/views/toolbar.pug
+
+# loops
+app/views/referal/bonus.pug
+modules/templates/app/views/tag.pug
+
+# expressions that could not be formatted correctly
+app/views/_mixins/faq_search.pug
+app/views/external/home/v2.pug
+app/views/project/token/access.pug
+app/views/user/primaryEmailCheck.pug
+app/views/user/restricted.pug
+modules/admin-panel/app/views/project/show.pug
+modules/templates/app/views/project/editor/_left-menu.pug
+modules/two-factor-authentication/app/views/_mixins.pug
+
+# minified files
+app/views/_google_analytics.pug
+app/views/_customer_io.pug
diff --git a/services/web/.prettierrc b/services/web/.prettierrc
index 13e31862ff..b99212a874 100644
--- a/services/web/.prettierrc
+++ b/services/web/.prettierrc
@@ -1,9 +1,23 @@
{
"arrowParens": "avoid",
"jsxSingleQuote": false,
+ "pugAttributeSeparator": "as-needed",
+ "pugBracketSpacing": false,
+ "pugClassNotation": "as-is",
+ "pugIdNotation": "as-is",
+ "pugSortAttributesBeginning": ["name", "data-type"],
+ "plugins": ["@prettier/plugin-pug"],
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"tabWidth": 2,
- "useTabs": false
+ "useTabs": false,
+ "overrides": [
+ {
+ "files": "*.pug",
+ "options": {
+ "useTabs": true
+ }
+ }
+ ]
}
diff --git a/services/web/Makefile b/services/web/Makefile
index 6ebbc357c6..f5a7542691 100644
--- a/services/web/Makefile
+++ b/services/web/Makefile
@@ -455,12 +455,19 @@ format: format_styles
format_styles:
npm run --silent format:styles
+format: format_pug
+format_pug:
+ npm run --silent format:pug
+
format_fix:
npm run --silent format:fix
format_styles_fix:
npm run --silent format:styles:fix
+format_pug_fix:
+ npm run --silent format:pug:fix
+
format_in_docker:
$(RUN_LINT_FORMAT) make format -j2 --output-sync
diff --git a/services/web/app/views/_cookie_banner.pug b/services/web/app/views/_cookie_banner.pug
index 2d5631f9c8..56974326cd 100644
--- a/services/web/app/views/_cookie_banner.pug
+++ b/services/web/app/views/_cookie_banner.pug
@@ -1,5 +1,13 @@
-section.cookie-banner.hidden-print.hidden(aria-label="Cookie banner")
- .cookie-banner-content We only use cookies for essential purposes and to improve your experience on our site. You can find out more in our cookie policy.
- .cookie-banner-actions
- button(type="button" class="btn btn-link btn-sm" data-ol-cookie-banner-set-consent="essential") Essential cookies only
- button(type="button" class="btn btn-primary btn-sm" data-ol-cookie-banner-set-consent="all") Accept all cookies
+section.cookie-banner.hidden-print.hidden(aria-label='Cookie banner')
+ .cookie-banner-content We only use cookies for essential purposes and to improve your experience on our site. You can find out more in our cookie policy.
+ .cookie-banner-actions
+ button(
+ type='button'
+ class='btn btn-link btn-sm'
+ data-ol-cookie-banner-set-consent='essential'
+ ) Essential cookies only
+ button(
+ type='button'
+ class='btn btn-primary btn-sm'
+ data-ol-cookie-banner-set-consent='all'
+ ) Accept all cookies
diff --git a/services/web/app/views/_metadata.pug b/services/web/app/views/_metadata.pug
index a784860095..6d7c599546 100644
--- a/services/web/app/views/_metadata.pug
+++ b/services/web/app/views/_metadata.pug
@@ -1,123 +1,140 @@
-
//- Title
-if (metadata && metadata.title)
- title= metadata.title + ' - ' + settings.appName + ', ' + translate("online_latex_editor")
- meta(name="twitter:title", content=metadata.title)
- meta(name="og:title", content=metadata.title)
-else if (typeof(title) == "undefined")
- title= settings.appName + ', '+ translate("online_latex_editor")
- meta(name="twitter:title", content=settings.appName + ', '+ translate("online_latex_editor"))
- meta(name="og:title", content=settings.appName + ', '+ translate("online_latex_editor"))
+if metadata && metadata.title
+ title= metadata.title + ' - ' + settings.appName + ', ' + translate('online_latex_editor')
+ meta(name='twitter:title' content=metadata.title)
+ meta(name='og:title' content=metadata.title)
+else if typeof title == 'undefined'
+ title= settings.appName + ', ' + translate('online_latex_editor')
+ meta(
+ name='twitter:title'
+ content=settings.appName + ', ' + translate('online_latex_editor')
+ )
+ meta(
+ name='og:title'
+ content=settings.appName + ', ' + translate('online_latex_editor')
+ )
else
- title= translate(title) + ' - ' + settings.appName + ', ' + translate("online_latex_editor")
+ title= translate(title) + ' - ' + settings.appName + ', ' + translate('online_latex_editor')
//- to do - not translate?
- meta(name="twitter:title", content=translate(title))
- meta(name="og:title", content=translate(title))
+ meta(name='twitter:title' content=translate(title))
+ meta(name='og:title' content=translate(title))
//- Description
-if (metadata && metadata.description)
- meta(name="description" , content=metadata.description)
- meta(itemprop="description" , content=metadata.description)
+if metadata && metadata.description
+ meta(name='description' content=metadata.description)
+ meta(itemprop='description' content=metadata.description)
//-twitter and og descriptions handeled in their sections below
else
- meta(name="description", content=translate("site_description"))
- meta(itemprop="description", content=translate("site_description"))
+ meta(name='description' content=translate('site_description'))
+ meta(itemprop='description' content=translate('site_description'))
//- Image
-if (metadata && metadata.image && metadata.image.fields)
+if metadata && metadata.image && metadata.image.fields
//- from the CMS
- meta(itemprop="image", content=metadata.image.fields.file.url)
- meta(name="image", content=metadata.image.fields.file.url)
-else if (metadata && metadata.image_src)
+ meta(itemprop='image' content=metadata.image.fields.file.url)
+ meta(name='image' content=metadata.image.fields.file.url)
+else if metadata && metadata.image_src
//- pages with custom metadata images, metadata.image_src is the full image URL
- meta(itemprop="image", content=metadata.image_src)
- meta(name="image", content=metadata.image_src)
-else if (settings.overleaf)
+ meta(itemprop='image' content=metadata.image_src)
+ meta(name='image' content=metadata.image_src)
+else if settings.overleaf
//- the default image for Overleaf
- meta(itemprop="image", content=buildImgPath('ol-brand/overleaf_og_logo.png'))
- meta(name="image", content=buildImgPath('ol-brand/overleaf_og_logo.png'))
+ meta(itemprop='image' content=buildImgPath('ol-brand/overleaf_og_logo.png'))
+ meta(name='image' content=buildImgPath('ol-brand/overleaf_og_logo.png'))
else
//- the default image for Overleaf Community Edition/Server Pro
- meta(itemprop="image", content='/apple-touch-icon.png')
- meta(name="image", content='/apple-touch-icon.png')
+ meta(itemprop='image' content='/apple-touch-icon.png')
+ meta(name='image' content='/apple-touch-icon.png')
//- Keywords
-if (metadata && metadata.keywords)
- meta(name="keywords" content=metadata.keywords)
+if metadata && metadata.keywords
+ meta(name='keywords' content=metadata.keywords)
//- Misc
-meta(itemprop="name", content=settings.appName + ", the Online LaTeX Editor")
+meta(itemprop='name' content=settings.appName + ', the Online LaTeX Editor')
-if (metadata && metadata.robotsNoindexNofollow)
- meta(name="robots" content="noindex, nofollow")
+if metadata && metadata.robotsNoindexNofollow
+ meta(name='robots' content='noindex, nofollow')
//- Twitter
-meta(name="twitter:card", content=metadata && metadata.twitterCardType ? metadata.twitterCardType : 'summary')
-if (settings.social && settings.social.twitter && settings.social.twitter.handle)
- meta(name="twitter:site", content="@" + settings.social.twitter.handle)
-if (metadata && metadata.twitterDescription)
- meta(name="twitter:description", content=metadata.twitterDescription)
+meta(
+ name='twitter:card'
+ content=metadata && metadata.twitterCardType ? metadata.twitterCardType : 'summary'
+)
+if settings.social && settings.social.twitter && settings.social.twitter.handle
+ meta(name='twitter:site' content='@' + settings.social.twitter.handle)
+if metadata && metadata.twitterDescription
+ meta(name='twitter:description' content=metadata.twitterDescription)
else
- meta(name="twitter:description", content=translate("site_description"))
-if (metadata && metadata.twitterImage && metadata.twitterImage.fields)
+ meta(name='twitter:description' content=translate('site_description'))
+if metadata && metadata.twitterImage && metadata.twitterImage.fields
//- from the CMS
- meta(name="twitter:image", content=metadata.twitterImage.fields.file.url)
- meta(name="twitter:image:alt", content=metadata.twitterImage.fields.title)
-else if (settings.overleaf)
+ meta(name='twitter:image' content=metadata.twitterImage.fields.file.url)
+ meta(name='twitter:image:alt' content=metadata.twitterImage.fields.title)
+else if settings.overleaf
//- the default image for Overleaf
- meta(name="twitter:image", content=buildImgPath('ol-brand/overleaf_og_logo.png'))
+ meta(
+ name='twitter:image'
+ content=buildImgPath('ol-brand/overleaf_og_logo.png')
+ )
else
//- the default image for Overleaf Community Edition/Server Pro
- meta(name="twitter:image", content='/apple-touch-icon.png')
+ meta(name='twitter:image' content='/apple-touch-icon.png')
//- Open Graph
//- to do - add og:url
-if (settings.social && settings.social.facebook && settings.social.facebook.appId)
- meta(property="fb:app_id", content=settings.social.facebook.appId)
+if settings.social && settings.social.facebook && settings.social.facebook.appId
+ meta(property='fb:app_id' content=settings.social.facebook.appId)
-if (metadata && metadata.openGraphDescription)
- meta(property="og:description", content=metadata.openGraphDescription)
+if metadata && metadata.openGraphDescription
+ meta(property='og:description' content=metadata.openGraphDescription)
else
- meta(property="og:description", content=translate("site_description"))
+ meta(property='og:description' content=translate('site_description'))
-if (metadata && metadata.openGraphImage && metadata.openGraphImage.fields)
+if metadata && metadata.openGraphImage && metadata.openGraphImage.fields
//- from the CMS
- meta(property="og:image", content=metadata.openGraphImage.fields.file.url)
-else if (settings.overleaf)
+ meta(property='og:image' content=metadata.openGraphImage.fields.file.url)
+else if settings.overleaf
//- the default image for Overleaf
- meta(property="og:image", content=buildImgPath('ol-brand/overleaf_og_logo.png'))
+ meta(
+ property='og:image'
+ content=buildImgPath('ol-brand/overleaf_og_logo.png')
+ )
else
//- the default image for Overleaf Community Edition/Server Pro
- meta(property="og:image", content='/apple-touch-icon.png')
+ meta(property='og:image' content='/apple-touch-icon.png')
-if (metadata && metadata.openGraphType)
- meta(property="og:type", metadata.openGraphType)
+if metadata && metadata.openGraphType
+ meta(property='og:type' metadata.openGraphType)
else
- meta(property="og:type", content="website")
+ meta(property='og:type' content='website')
-if (metadata && metadata.openGraphVideo)
+if metadata && metadata.openGraphVideo
//- from the CMS
- meta(property="og:video", content=metadata.openGraphVideo)
+ meta(property='og:video' content=metadata.openGraphVideo)
//- Viewport
if !metadata || metadata.viewport !== false
- meta(name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes")
+ meta(
+ name='viewport'
+ content='width=device-width, initial-scale=1.0, user-scalable=yes'
+ )
//- Noindex
if settings.robotsNoindex
- meta(name="robots" content="noindex")
+ meta(name='robots' content='noindex')
//- Icons
-link(rel="icon", sizes="32x32", href="/favicon-32x32.png")
-link(rel="icon", sizes="16x16", href="/favicon-16x16.png")
-link(rel="icon", href="/favicon.svg" type="image/svg+xml")
-link(rel="apple-touch-icon", href="/apple-touch-icon.png")
-link(rel="mask-icon", href="/mask-favicon.svg", color="#046530")
+link(rel='icon' sizes='32x32' href='/favicon-32x32.png')
+link(rel='icon' sizes='16x16' href='/favicon-16x16.png')
+link(rel='icon' href='/favicon.svg' type='image/svg+xml')
+link(rel='apple-touch-icon' href='/apple-touch-icon.png')
+link(rel='mask-icon' href='/mask-favicon.svg' color='#046530')
//- Canonical Tag for SEO
-if (metadata && metadata.canonicalURL)
- link(rel="canonical" href=metadata.canonicalURL)
+if metadata && metadata.canonicalURL
+ link(rel='canonical' href=metadata.canonicalURL)
//- Manifest
//- Does not currently contain a start_url to prevent browser installation prompts
-link(rel="manifest" href="/web.sitemanifest")
+link(rel='manifest' href='/web.sitemanifest')
diff --git a/services/web/app/views/_mixins/back_to_btns.pug b/services/web/app/views/_mixins/back_to_btns.pug
index dacd9ea7a2..c3a1f4f76e 100644
--- a/services/web/app/views/_mixins/back_to_btns.pug
+++ b/services/web/app/views/_mixins/back_to_btns.pug
@@ -1,4 +1,6 @@
mixin back-to-btns(settingsAnchor)
.d-flex.flex-column.flex-sm-row.gap-3
- a.btn.btn-secondary(href=`/user/settings${settingsAnchor ? '#' + settingsAnchor : '' }`) #{translate('back_to_account_settings')}
+ a.btn.btn-secondary(
+ href=`/user/settings${settingsAnchor ? '#' + settingsAnchor : '' }`
+ ) #{translate('back_to_account_settings')}
a.btn.btn-secondary(href='/project') #{translate('back_to_your_projects')}
diff --git a/services/web/app/views/_mixins/begin_now_card.pug b/services/web/app/views/_mixins/begin_now_card.pug
index 8f9919553d..641703d606 100644
--- a/services/web/app/views/_mixins/begin_now_card.pug
+++ b/services/web/app/views/_mixins/begin_now_card.pug
@@ -1,10 +1,10 @@
-mixin begin_now_card()
+mixin begin_now_card
- var registerURL = '/register'
- var plansURL = '/user/subscription/plans'
- var isUserLoggedIn = !!getSessionUser()
.begin-now-card
- div.card.card-pattern
+ .card.card-pattern
.card-body
p.dm-mono
span.font-size-display-xs
@@ -16,10 +16,8 @@ mixin begin_now_card()
p #{translate("discover_why_over_people_worldwide_trust_overleaf", {count: settings.userCountInMillions})}
p.card-links
if !isUserLoggedIn
- a.btn.btn-primary.card-link(
- href=registerURL
- ) #{translate("sign_up_for_free")}
+ a.btn.btn-primary.card-link(href=registerURL) #{translate("sign_up_for_free")}
a.btn.card-link(
- class = isUserLoggedIn ? 'btn-primary' : 'btn-secondary'
+ class=isUserLoggedIn ? 'btn-primary' : 'btn-secondary'
href=plansURL
) #{translate("explore_all_plans")}
diff --git a/services/web/app/views/_mixins/bookmarkable_tabset.pug b/services/web/app/views/_mixins/bookmarkable_tabset.pug
index 27ac74ef66..72579c7725 100644
--- a/services/web/app/views/_mixins/bookmarkable_tabset.pug
+++ b/services/web/app/views/_mixins/bookmarkable_tabset.pug
@@ -1,10 +1,10 @@
mixin bookmarkable-tabset-header(id, title, active)
- li(role="presentation")
+ li(role='presentation')
a.nav-link(
href='#' + id
- class=(active ? 'active' : '')
+ class=active ? 'active' : ''
aria-controls=id
- role="tab"
- data-toggle="tab"
+ role='tab'
+ data-toggle='tab'
data-ol-bookmarkable-tab
) #{title}
diff --git a/services/web/app/views/_mixins/bootstrap_js.pug b/services/web/app/views/_mixins/bootstrap_js.pug
index 866b0b4218..746e811bf7 100644
--- a/services/web/app/views/_mixins/bootstrap_js.pug
+++ b/services/web/app/views/_mixins/bootstrap_js.pug
@@ -1,3 +1,3 @@
mixin bootstrap-js(bootstrapVersion)
- each file in (entrypointScripts(bootstrapVersion === 5 ? 'bootstrap-5' : 'bootstrap-3'))
- script(type="text/javascript", nonce=scriptNonce, src=file)
+ each file in entrypointScripts(bootstrapVersion === 5 ? 'bootstrap-5' : 'bootstrap-3')
+ script(type='text/javascript' nonce=scriptNonce src=file)
diff --git a/services/web/app/views/_mixins/eyebrow.pug b/services/web/app/views/_mixins/eyebrow.pug
index c5f01a10db..3eae0b8308 100644
--- a/services/web/app/views/_mixins/eyebrow.pug
+++ b/services/web/app/views/_mixins/eyebrow.pug
@@ -1,5 +1,5 @@
mixin eyebrow(text)
- span.eyebrow-text
- span(aria-hidden="true") {
- span #{text}
- span(aria-hidden="true") }
\ No newline at end of file
+ span.eyebrow-text
+ span(aria-hidden='true') {
+ span #{text}
+ span(aria-hidden='true') }
diff --git a/services/web/app/views/_mixins/faq_search-marketing.pug b/services/web/app/views/_mixins/faq_search-marketing.pug
index aa41d00f9b..1b161dbdf6 100644
--- a/services/web/app/views/_mixins/faq_search-marketing.pug
+++ b/services/web/app/views/_mixins/faq_search-marketing.pug
@@ -1,30 +1,37 @@
mixin faq_search-marketing(headerText, headerClass)
- if (typeof(settings.algolia) != "undefined" && typeof(settings.algolia.indexes) != "undefined" && typeof(settings.algolia.indexes.wiki) != "undefined")
+ if typeof settings.algolia != 'undefined' && typeof settings.algolia.indexes != 'undefined' && typeof settings.algolia.indexes.wiki != 'undefined'
if headerText
div(class=headerClass) #{headerText}
.wiki
- form.project-search.form-horizontal(role="search" data-ol-faq-search)
+ form.project-search.form-horizontal(role='search' data-ol-faq-search)
.form-group.has-feedback.has-feedback-left
.col-sm-12
- input.form-control(type='search', placeholder="Search help library…" aria-label="Search help library…")
- i.fa.fa-search.form-control-feedback-left(aria-hidden="true")
+ input.form-control(
+ type='search'
+ placeholder='Search help library…'
+ aria-label='Search help library…'
+ )
+ i.fa.fa-search.form-control-feedback-left(aria-hidden='true')
i.fa.fa-times.form-control-feedback(
- style="cursor: pointer;",
+ style='cursor: pointer'
hidden
data-ol-clear-search
- aria-hidden="true"
+ aria-hidden='true'
)
button.sr-only(
- type="button"
+ type='button'
hidden
data-ol-clear-search
aria-label=translate('clear_search')
)
- .row(role="region" aria-label="search results")
- .col-md-12()
+ .row(role='region' aria-label='search results')
+ .col-md-12
div(data-ol-search-results-wrapper)
- span.sr-only(aria-live="polite" data-ol-search-sr-help-message)
+ span.sr-only(aria-live='polite' data-ol-search-sr-help-message)
div(data-ol-search-results)
- .row-spaced-small.search-result.card.card-thin(hidden data-ol-search-no-results)
+ .row-spaced-small.search-result.card.card-thin(
+ hidden
+ data-ol-search-no-results
+ )
p #{translate("no_search_results")}
diff --git a/services/web/app/views/_mixins/foot_scripts.pug b/services/web/app/views/_mixins/foot_scripts.pug
index c6b65e81c7..717c46cdd9 100644
--- a/services/web/app/views/_mixins/foot_scripts.pug
+++ b/services/web/app/views/_mixins/foot_scripts.pug
@@ -1,6 +1,11 @@
-mixin foot-scripts()
+mixin foot-scripts
each file in entrypointScripts(entrypoint)
- script(type="text/javascript", nonce=scriptNonce, src=file, defer=deferScripts)
- if (settings.devToolbar.enabled)
- each file in entrypointScripts("devToolbar")
- script(type="text/javascript", nonce=scriptNonce, src=file, defer=deferScripts)
+ script(type='text/javascript' nonce=scriptNonce src=file defer=deferScripts)
+ if settings.devToolbar.enabled
+ each file in entrypointScripts('devToolbar')
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src=file
+ defer=deferScripts
+ )
diff --git a/services/web/app/views/_mixins/formMessages.pug b/services/web/app/views/_mixins/formMessages.pug
index 2fab7e40d8..a14bb2196a 100644
--- a/services/web/app/views/_mixins/formMessages.pug
+++ b/services/web/app/views/_mixins/formMessages.pug
@@ -1,41 +1,35 @@
include ./material_symbol
-mixin formMessages()
- div(
- data-ol-form-messages='',
- role="alert"
- )
+mixin formMessages
+ div(data-ol-form-messages='' role='alert')
mixin formMessagesNewStyle(extraClass = 'form-messages-bottom-margin')
- - const attrs = extraClass ? { 'class': extraClass } : {}
- div(
- data-ol-form-messages-new-style='',
- role="alert"
- )&attributes(attrs)
+ - const attrs = extraClass ? {class: extraClass} : {}
+ div(data-ol-form-messages-new-style='' role='alert')&attributes(attrs)
mixin customFormMessage(key, kind)
if kind === 'success'
- div.alert.alert-success(
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="polite"
+ .alert.alert-success(
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='polite'
)
block
else if kind === 'danger'
- div.alert.alert-danger(
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="assertive"
+ .alert.alert-danger(
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='assertive'
)
block
else
- div.alert.alert-warning(
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="polite"
+ .alert.alert-warning(
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='polite'
)
block
@@ -43,56 +37,50 @@ mixin customFormMessageNewStyle(key, kind, extraClass = 'mb-3')
- extraClass = extraClass ? ' ' + extraClass : ''
if kind === 'success'
div(
- class="notification notification-type-success" + extraClass,
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="polite"
+ class='notification notification-type-success' + extraClass
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='polite'
)
- div.notification-icon
- +material-symbol("check_circle")
- div.notification-content.text-left
+ .notification-icon
+ +material-symbol('check_circle')
+ .notification-content.text-left
block
else if kind === 'danger'
div(
- class="notification notification-type-error" + extraClass,
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="polite"
+ class='notification notification-type-error' + extraClass
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='polite'
)
- div.notification-icon
- +material-symbol("error")
- div.notification-content.text-left
+ .notification-icon
+ +material-symbol('error')
+ .notification-content.text-left
block
else
div(
- class="notification notification-type-warning" + extraClass,
- hidden,
- data-ol-custom-form-message=key,
- role="alert"
- aria-live="polite"
+ class='notification notification-type-warning' + extraClass
+ hidden
+ data-ol-custom-form-message=key
+ role='alert'
+ aria-live='polite'
)
- div.notification-icon
- +material-symbol("warning")
- div.notification-content.text-left
+ .notification-icon
+ +material-symbol('warning')
+ .notification-content.text-left
block
mixin customValidationMessage(key)
- div.invalid-feedback.mt-2(
- hidden,
- data-ol-custom-form-message=key
- )
- i.fa.fa-fw.fa-warning.me-1(aria-hidden="true")
+ .invalid-feedback.mt-2(hidden data-ol-custom-form-message=key)
+ i.fa.fa-fw.fa-warning.me-1(aria-hidden='true')
div
block
mixin customValidationMessageNewStyle(key)
- div.notification.notification-type-error(
- hidden,
- data-ol-custom-form-message=key
- )
- div.notification-icon
- +material-symbol("error")
- div.notification-content.text-left.small
+ .notification.notification-type-error(hidden data-ol-custom-form-message=key)
+ .notification-icon
+ +material-symbol('error')
+ .notification-content.text-left.small
block
diff --git a/services/web/app/views/_mixins/links.pug b/services/web/app/views/_mixins/links.pug
index 566c90ee50..a919cdd74e 100644
--- a/services/web/app/views/_mixins/links.pug
+++ b/services/web/app/views/_mixins/links.pug
@@ -8,7 +8,8 @@ mixin linkAdvisors(linkText, linkClass, track)
- var mb = track && track.mb ? 'true' : null
- var mbSegmentation = track && track.segmentation ? track.segmentation : null
- var trigger = track && track.trigger ? track.trigger : null
- a(href="/advisors"
+ a(
+ href='/advisors'
class=linkClass ? linkClass : ''
event-tracking-ga=gaCategory
event-tracking=gaAction
@@ -20,24 +21,36 @@ mixin linkAdvisors(linkText, linkClass, track)
span #{linkText ? linkText : 'advisor programme'}
mixin linkBenefits(linkText, linkClass)
- a(href=(settings.siteUrl ? settings.siteUrl : '') + "/for/authors" class=linkClass ? linkClass : '')
+ a(
+ href=(settings.siteUrl ? settings.siteUrl : '') + '/for/authors'
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'benefits'}
-
+
mixin linkBlog(linkText, linkClass, slug)
if slug
- a(href=(settings.siteUrl ? settings.siteUrl : '') + "/blog/" + slug class=linkClass ? linkClass : '')
+ a(
+ href=(settings.siteUrl ? settings.siteUrl : '') + '/blog/' + slug
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'blog'}
mixin linkContact(linkText, linkClass)
- a(href=(settings.siteUrl ? settings.siteUrl : '') + "/contact" class=linkClass ? linkClass : '')
+ a(
+ href=(settings.siteUrl ? settings.siteUrl : '') + '/contact'
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'contact'}
mixin linkDash(linkText, linkClass)
- a(href="/project" class=linkClass ? linkClass : '')
+ a(href='/project' class=linkClass ? linkClass : '')
| #{linkText ? linkText : 'project dashboard'}
mixin linkEducation(linkText, linkClass)
- a(href=(settings.siteUrl ? settings.siteUrl : '') + "/for/edu" class=linkClass ? linkClass : '')
+ a(
+ href=(settings.siteUrl ? settings.siteUrl : '') + '/for/edu'
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'teaching toolkit'}
mixin linkInvite(linkText, linkClass, track)
@@ -48,7 +61,8 @@ mixin linkInvite(linkText, linkClass, track)
- var mbSegmentation = track && track.segmentation ? track.segmentation : null
- var trigger = track && track.trigger ? track.trigger : null
- a(href="/user/bonus"
+ a(
+ href='/user/bonus'
class=linkClass ? linkClass : ''
event-tracking-ga=gaCategory
event-tracking=gaAction
@@ -60,7 +74,7 @@ mixin linkInvite(linkText, linkClass, track)
span #{linkText ? linkText : 'invite your friends'}
mixin linkPlansAndPricing(linkText, linkClass)
- a(href="/user/subscription/plans" class=linkClass ? linkClass : '')
+ a(href='/user/subscription/plans' class=linkClass ? linkClass : '')
| #{linkText ? linkText : 'plans and pricing'}
mixin linkPrintNewTab(linkText, linkClass, icon, track)
@@ -71,7 +85,8 @@ mixin linkPrintNewTab(linkText, linkClass, icon, track)
- var mbSegmentation = track && track.segmentation ? track.segmentation : null
- var trigger = track && track.trigger ? track.trigger : null
- a(href='?media=print'
+ a(
+ href='?media=print'
class=linkClass ? linkClass : ''
event-tracking-ga=gaCategory
event-tracking=gaAction
@@ -79,20 +94,26 @@ mixin linkPrintNewTab(linkText, linkClass, icon, track)
event-tracking-trigger=trigger
event-tracking-mb=mb
event-segmentation=mbSegmentation
- target="_BLANK",
- rel="noopener noreferrer"
+ target='_BLANK'
+ rel='noopener noreferrer'
)
if icon
- i(class="fa fa-print")
+ i(class='fa fa-print')
|
span #{linkText ? linkText : 'print'}
mixin linkSignIn(linkText, linkClass, redirect)
- a(href=`/login${redirect ? '?redir=' + redirect : ''}` class=linkClass ? linkClass : '')
+ a(
+ href=`/login${redirect ? '?redir=' + redirect : ''}`
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'sign in'}
mixin linkSignUp(linkText, linkClass, redirect)
- a(href=`/register${redirect ? '?redir=' + redirect : ''}` class=linkClass ? linkClass : '')
+ a(
+ href=`/register${redirect ? '?redir=' + redirect : ''}`
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'sign up'}
mixin linkTweet(linkText, linkClass, tweetText, track)
@@ -103,23 +124,33 @@ mixin linkTweet(linkText, linkClass, tweetText, track)
- var mb = track && track.mb ? 'true' : null
- var mbSegmentation = track && track.segmentation ? track.segmentation : null
- var trigger = track && track.trigger ? track.trigger : null
- a(class="twitter-share-button " + linkClass
+ a(
+ class='twitter-share-button ' + linkClass
event-tracking-ga=gaCategory
event-tracking=gaAction
event-tracking-label=gaLabel
event-tracking-trigger=trigger
event-tracking-mb=mb
event-segmentation=mbSegmentation
- href="https://twitter.com/intent/tweet?text=" + tweetText
- target="_BLANK",
- rel="noopener noreferrer"
+ href='https://twitter.com/intent/tweet?text=' + tweetText
+ target='_BLANK'
+ rel='noopener noreferrer'
) #{linkText ? linkText : 'tweet'}
mixin linkUniversities(linkText, linkClass)
- a(href=(settings.siteUrl ? settings.siteUrl : '') + "/for/universities" class=linkClass ? linkClass : '')
+ a(
+ href=(settings.siteUrl ? settings.siteUrl : '') + '/for/universities'
+ class=linkClass ? linkClass : ''
+ )
| #{linkText ? linkText : 'universities'}
mixin linkWithArrow({text, href, eventTracking, eventSegmentation, eventTrackingTrigger})
- a.link-with-arrow(href=href event-tracking=eventTracking event-segmentation=eventSegmentation, event-tracking-trigger=eventTrackingTrigger event-tracking-mb)
+ a.link-with-arrow(
+ href=href
+ event-tracking=eventTracking
+ event-segmentation=eventSegmentation
+ event-tracking-trigger=eventTrackingTrigger
+ event-tracking-mb
+ )
| #{text}
- +material-symbol("arrow_right_alt")
+ +material-symbol('arrow_right_alt')
diff --git a/services/web/app/views/_mixins/material_symbol.pug b/services/web/app/views/_mixins/material_symbol.pug
index 1e97425faf..e4e8925f93 100644
--- a/services/web/app/views/_mixins/material_symbol.pug
+++ b/services/web/app/views/_mixins/material_symbol.pug
@@ -1,7 +1,8 @@
mixin material-symbol(icon, extraClass = null)
- extraClass = extraClass ? ' ' + extraClass : ''
- span(aria-hidden="true", translate="no", class="material-symbols" + extraClass)&attributes(attributes) #{icon}
-
+ span(aria-hidden='true' translate='no' class='material-symbols' + extraClass)&attributes(attributes)
+ | #{icon}
+
mixin material-symbol-outlined(icon, extraClass = null)
- extraClass = extraClass ? ' ' + extraClass : ''
+material-symbol(icon, 'material-symbols-outlined' + extraClass)&attributes(attributes)
diff --git a/services/web/app/views/_mixins/navbar.pug b/services/web/app/views/_mixins/navbar.pug
index f3482d3b54..0ea2e4e3a0 100644
--- a/services/web/app/views/_mixins/navbar.pug
+++ b/services/web/app/views/_mixins/navbar.pug
@@ -1,23 +1,23 @@
mixin nav-item
- li(role="none")&attributes(attributes)
+ li(role='none')&attributes(attributes)
block
mixin nav-link
- a(role="menuitem").nav-link&attributes(attributes)
+ a.nav-link(role='menuitem')&attributes(attributes)
block
mixin dropdown-menu
- ul(role="menu").dropdown-menu&attributes(attributes)
+ ul.dropdown-menu(role='menu')&attributes(attributes)
block
mixin dropdown-menu-item
- li(role="none")
+ li(role='none')
block
mixin dropdown-menu-link-item
+dropdown-menu-item
- a(role="menuitem").dropdown-item&attributes(attributes)
+ a.dropdown-item(role='menuitem')&attributes(attributes)
block
-
+
mixin dropdown-menu-divider
- li(role="separator").dropdown-divider.d-none.d-lg-block
+ li.dropdown-divider.d-none.d-lg-block(role='separator')
diff --git a/services/web/app/views/_mixins/notification.pug b/services/web/app/views/_mixins/notification.pug
index fb0db79630..482dd540c5 100644
--- a/services/web/app/views/_mixins/notification.pug
+++ b/services/web/app/views/_mixins/notification.pug
@@ -3,25 +3,19 @@ include ./material_symbol
mixin notificationIcon(type)
if type === 'info'
- +material-symbol("info")
+ +material-symbol('info')
else if type === 'success'
- +material-symbol("check_circle")
+ +material-symbol('check_circle')
else if type === 'error'
- +material-symbol("error")
+ +material-symbol('error')
else if type === 'warning'
- +material-symbol("warning")
-
+ +material-symbol('warning')
mixin notification(options)
- var {ariaLive, id, type, title, content, disclaimer, className} = options
- var classNames = `notification notification-type-${type} ${className ? className : ''} ${isActionBelowContent ? 'notification-cta-below-content' : ''}`
- div(
- aria-live=ariaLive,
- role="alert",
- id=id,
- class=classNames
- )
+ div(aria-live=ariaLive role='alert' id=id class=classNames)
.notification-icon
+notificationIcon(type)
.notification-content-and-cta
diff --git a/services/web/app/views/_mixins/pagination.pug b/services/web/app/views/_mixins/pagination.pug
index ef5f62bd0e..a2422e8c5d 100644
--- a/services/web/app/views/_mixins/pagination.pug
+++ b/services/web/app/views/_mixins/pagination.pug
@@ -10,77 +10,74 @@ mixin pagination(pages, page_path, max_btns)
- var max_btns = max_btns || 4
- var prev_page = Math.max(parseInt(pages.current_page, 10) - max_btns, 1)
- var next_page = parseInt(pages.current_page, 10) + 1
- - var next_index = 0;
- - var full_page_path = page_path + "/page/"
+ - var next_index = 0
+ - var full_page_path = page_path + '/page/'
- nav(role="navigation" aria-label=(translate("pagination_navigation")))
+ nav(role='navigation' aria-label=translate('pagination_navigation'))
ul.pagination
if pages.current_page > 1
li
- a(
- aria-label=translate("go_to_first_page")
- href=page_path
- )
- span(aria-hidden="true") <<
+ a(aria-label=translate('go_to_first_page') href=page_path)
+ span(aria-hidden='true') <<
|
| First
li
a(
- aria-label=translate("go_to_previous_page")
+ aria-label=translate('go_to_previous_page')
href=full_page_path + (parseInt(pages.current_page, 10) - 1)
- rel="prev"
+ rel='prev'
)
- span(aria-hidden="true") <
+ span(aria-hidden='true') <
|
| Prev
if pages.current_page - max_btns > 1
- li(aria-hidden="true")
+ li(aria-hidden='true')
span …
while prev_page < pages.current_page
li
a(
- aria-label=translate("go_to_page_x", {page: prev_page})
+ aria-label=translate('go_to_page_x', {page: prev_page})
href=full_page_path + prev_page
) #{prev_page}
- prev_page++
- li(class="active")
+ li(class='active')
span(
- aria-label=translate("current_page_page", {page: pages.current_page})
- aria-current="true"
+ aria-label=translate('current_page_page', {page: pages.current_page})
+ aria-current='true'
) #{pages.current_page}
if pages.current_page < pages.total_pages
while next_page <= pages.total_pages && next_index < max_btns
li
a(
- aria-label=translate("go_to_page_x", {page: next_page})
+ aria-label=translate('go_to_page_x', {page: next_page})
href=full_page_path + next_page
) #{next_page}
- next_page++
- next_index++
- if next_page <= pages.total_pages
- li.ellipses(aria-hidden="true")
+ if next_page <= pages.total_pages
+ li.ellipses(aria-hidden='true')
span …
li
a(
- aria-label=translate("go_to_next_page")
+ aria-label=translate('go_to_next_page')
href=full_page_path + (parseInt(pages.current_page, 10) + 1)
- rel="next"
+ rel='next'
)
| Next
|
- span(aria-hidden="true") >
+ span(aria-hidden='true') >
li
a(
- aria-label=translate("go_to_last_page")
+ aria-label=translate('go_to_last_page')
href=full_page_path + pages.total_pages
)
| Last
|
- span(aria-hidden="true") >>
+ span(aria-hidden='true') >>
diff --git a/services/web/app/views/_mixins/previous_page_link.pug b/services/web/app/views/_mixins/previous_page_link.pug
index 1b646a04d2..9809409d4e 100644
--- a/services/web/app/views/_mixins/previous_page_link.pug
+++ b/services/web/app/views/_mixins/previous_page_link.pug
@@ -2,5 +2,5 @@ include ./material_symbol
mixin previous-page-link(href, text)
a.previous-page-link(href=href)
- +material-symbol-rounded("arrow_left_alt")
+ +material-symbol-rounded('arrow_left_alt')
| #{text}
diff --git a/services/web/app/views/_mixins/quote.pug b/services/web/app/views/_mixins/quote.pug
index 573e0b6b0c..a414c4dcec 100644
--- a/services/web/app/views/_mixins/quote.pug
+++ b/services/web/app/views/_mixins/quote.pug
@@ -3,10 +3,10 @@ mixin quoteLargeTextCentered(quote, person, position, affiliation, link, picture
.quote !{quote}
if pictureUrl
.quote-img
- -var pictureAlt=`Photo of ${person}`
+ - var pictureAlt = `Photo of ${person}`
img(src=pictureUrl alt=pictureAlt)
footer
- div.quote-person
+ .quote-person
strong #{person}
if person && position
div #{position}
@@ -29,27 +29,27 @@ mixin quoteLeftGreenBorder({quote, person, position, affiliation, link})
mixin collinsQuote1
.card.card-dark-green-bg
- -var quote = 'Overleaf is indispensable for us. We use it in our research, thesis writing, project proposals, and manuscripts for publication. When it comes to writing, it’s our main tool.'
- -var quotePerson = 'Christopher Collins'
- -var quotePersonPosition = 'Associate Professor and Lab Director, Ontario Tech University'
- -var quotePersonImg = buildImgPath("advocates/collins.jpg")
+ - var quote = 'Overleaf is indispensable for us. We use it in our research, thesis writing, project proposals, and manuscripts for publication. When it comes to writing, it’s our main tool.'
+ - var quotePerson = 'Christopher Collins'
+ - var quotePersonPosition = 'Associate Professor and Lab Director, Ontario Tech University'
+ - var quotePersonImg = buildImgPath('advocates/collins.jpg')
.card-body
+quoteLargeTextCentered(quote, quotePerson, quotePersonPosition, null, null, quotePersonImg)
mixin collinsQuote2
.card.card-dark-green-bg
- -var quote = 'We are writing collaboratively right up until the last minute. We are faced with deadlines all the time, and Overleaf gives us the ability to polish right up until the last possible second.'
- -var quotePerson = 'Christopher Collins'
- -var quotePersonPosition = 'Associate Professor and Lab Director, Ontario Tech University'
- -var quotePersonImg = buildImgPath("advocates/collins.jpg")
+ - var quote = 'We are writing collaboratively right up until the last minute. We are faced with deadlines all the time, and Overleaf gives us the ability to polish right up until the last possible second.'
+ - var quotePerson = 'Christopher Collins'
+ - var quotePersonPosition = 'Associate Professor and Lab Director, Ontario Tech University'
+ - var quotePersonImg = buildImgPath('advocates/collins.jpg')
.card-body
+quoteLargeTextCentered(quote, quotePerson, quotePersonPosition, null, null, quotePersonImg)
mixin bennettQuote1
.card.card-dark-green-bg
- -var quote = 'With Overleaf, we now have a process for developing technical documentation which has virtually eliminated the time required to properly format and layout documents.'
- -var quotePerson = 'Andrew Bennett'
- -var quotePersonPosition = 'Software Architect, Symplectic'
- -var quotePersonImg = buildImgPath("advocates/bennett.jpg")
+ - var quote = 'With Overleaf, we now have a process for developing technical documentation which has virtually eliminated the time required to properly format and layout documents.'
+ - var quotePerson = 'Andrew Bennett'
+ - var quotePersonPosition = 'Software Architect, Symplectic'
+ - var quotePersonImg = buildImgPath('advocates/bennett.jpg')
.card-body
+quoteLargeTextCentered(quote, quotePerson, quotePersonPosition, null, null, quotePersonImg)
diff --git a/services/web/app/views/_mixins/recaptcha.pug b/services/web/app/views/_mixins/recaptcha.pug
index 24e0c501ea..ec5604c825 100644
--- a/services/web/app/views/_mixins/recaptcha.pug
+++ b/services/web/app/views/_mixins/recaptcha.pug
@@ -1,2 +1,2 @@
-mixin recaptchaConditions()
+mixin recaptchaConditions
.recaptcha-branding !{translate("recaptcha_conditions", {}, [{}, {name: 'a', attrs: {href: 'https://policies.google.com/privacy', rel: 'noopener noreferrer', target: '_blank'}}, {name: 'a', attrs: {href: 'https://policies.google.com/terms', rel: 'noopener noreferrer', target: '_blank'}}])}
diff --git a/services/web/app/views/_mixins/reconfirm_affiliation-marketing.pug b/services/web/app/views/_mixins/reconfirm_affiliation-marketing.pug
index c42a3b439a..f54dd5d4ba 100644
--- a/services/web/app/views/_mixins/reconfirm_affiliation-marketing.pug
+++ b/services/web/app/views/_mixins/reconfirm_affiliation-marketing.pug
@@ -1,14 +1,11 @@
mixin reconfirmAffiliationNotification-marketing(userEmail, location)
- form(
- data-ol-async-form
- action='/user/emails/send-reconfirmation'
- )
- input(name="_csrf" type="hidden" value=csrfToken)
- input(name="email" type="hidden" value=userEmail.email)
- +formMessages()
+ form(data-ol-async-form action='/user/emails/send-reconfirmation')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='email' type='hidden' value=userEmail.email)
+ +formMessages
.reconfirm-notification
- div(data-ol-not-sent style="width:100%;")
+ div(data-ol-not-sent style='width: 100%')
i.fa.fa-warning
- var ssoEnabled = userEmail.affiliation && userEmail.affiliation.institution && userEmail.affiliation.institution.ssoEnabled
@@ -18,16 +15,16 @@ mixin reconfirmAffiliationNotification-marketing(userEmail, location)
data-ol-slow-link
href=`${settings.saml.ukamf.initPath}?university_id=${institutionId}&reconfirm=${location}`
)
- span(data-ol-inflight="idle") #{translate("confirm_affiliation")}
- span(hidden data-ol-inflight="pending") #{translate("pending")}…
+ span(data-ol-inflight='idle') #{translate("confirm_affiliation")}
+ span(hidden data-ol-inflight='pending') #{translate("pending")}…
else
button.btn-reconfirm.btn.btn-sm.btn-info(
- type="submit"
+ type='submit'
data-ol-disabled-inflight
)
- span(data-ol-inflight="idle") #{translate("confirm_affiliation")}
- span(hidden data-ol-inflight="pending") #{translate("pending")}…
+ span(data-ol-inflight='idle') #{translate("confirm_affiliation")}
+ span(hidden data-ol-inflight='pending') #{translate("pending")}…
| !{translate("are_you_still_at", {institutionName: userEmail.affiliation.institution.name}, ['strong'])}
@@ -39,22 +36,19 @@ mixin reconfirmAffiliationNotification-marketing(userEmail, location)
| !{translate("please_reconfirm_institutional_email", {}, [{name: 'a', attrs: {href: '/user/settings?remove=' + userEmail.email}}])}
|
- a(href="/learn/how-to/Institutional_Email_Reconfirmation" target="_blank") #{translate("learn_more")}
+ a(href='/learn/how-to/Institutional_Email_Reconfirmation' target='_blank') #{translate("learn_more")}
div(hidden data-ol-sent)
| !{translate("please_check_your_inbox_to_confirm", {institutionName: userEmail.affiliation.institution.name}, ['strong'])}
|
- button.btn-inline-link(
- type="submit"
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate('resend_confirmation_email')}
- span(hidden data-ol-inflight="pending") #{translate("pending")}…
+ button.btn-inline-link(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate('resend_confirmation_email')}
+ span(hidden data-ol-inflight='pending') #{translate("pending")}…
mixin reconfirmedAffiliationNotification-marketing(userEmail)
.alert.alert-info
.reconfirm-notification
- div(style="width:100%;")
+ div(style='width: 100%')
//- extra div for flex styling
| !{translate("your_affiliation_is_confirmed", {institutionName: userEmail.affiliation.institution.name}, ['strong'])}
|
diff --git a/services/web/app/views/_mixins/terms_of_service.pug b/services/web/app/views/_mixins/terms_of_service.pug
index 0fc3887b42..b0b5aaf81d 100644
--- a/services/web/app/views/_mixins/terms_of_service.pug
+++ b/services/web/app/views/_mixins/terms_of_service.pug
@@ -1,3 +1,3 @@
mixin termsOfServiceAgreement
- div.tos-agreement-notice
+ .tos-agreement-notice
| !{translate("by_registering_you_agree_to_our_terms_of_service", {}, [{name: 'a', attrs: {href: '/legal#Terms', target: '_blank'}}, {name: 'a', attrs: {href: '/legal#Privacy', target: '_blank'}}])}
diff --git a/services/web/app/views/admin/index.pug b/services/web/app/views/admin/index.pug
index aaf2228cbc..7a284d1f41 100644
--- a/services/web/app/views/admin/index.pug
+++ b/services/web/app/views/admin/index.pug
@@ -2,7 +2,7 @@ extends ../layout-marketing
include ../_mixins/bookmarkable_tabset
block content
- .content.content-alt#main-content
+ #main-content.content.content-alt
.container
.row
.col-sm-12
@@ -12,7 +12,7 @@ block content
h1 Admin Panel
.ol-tabs(data-ol-bookmarkable-tabset)
.nav-tabs-container
- ul.nav.nav-tabs.align-left(role="tablist")
+ ul.nav.nav-tabs.align-left(role='tablist')
+bookmarkable-tabset-header('system-messages', 'System Messages', true)
+bookmarkable-tabset-header('open-sockets', 'Open Sockets')
+bookmarkable-tabset-header('open-close-editor', 'Open/Close Editor')
@@ -20,29 +20,28 @@ block content
+bookmarkable-tabset-header('tpds', 'TPDS/Dropbox Management')
.tab-content
- .tab-pane.active(
- role="tabpanel"
- id='system-messages'
- )
+ .tab-pane.active(role='tabpanel' id='system-messages')
each message in systemMessages
ul.system-messages
li.system-message.row-spaced #{message.content}
hr
- form(method='post', action='/admin/messages')
- input(name="_csrf", type="hidden", value=csrfToken)
+ form(method='post' action='/admin/messages')
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
- label.form-label(for="content")
- input.form-control(name="content", type="text", placeholder="Message…", required)
- button.btn.btn-primary(type="submit") Post Message
+ label.form-label(for='content')
+ input.form-control(
+ name='content'
+ type='text'
+ placeholder='Message…'
+ required
+ )
+ button.btn.btn-primary(type='submit') Post Message
hr
- form(method='post', action='/admin/messages/clear')
- input(name="_csrf", type="hidden", value=csrfToken)
- button.btn.btn-danger(type="submit") Clear all messages
+ form(method='post' action='/admin/messages/clear')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ button.btn.btn-danger(type='submit') Clear all messages
- .tab-pane(
- role="tabpanel"
- id='open-sockets'
- )
+ .tab-pane(role='tabpanel' id='open-sockets')
.row-spaced
ul
each agents, url in openSockets
@@ -51,52 +50,56 @@ block content
each agent in agents
li #{agent}
- .tab-pane(
- role="tabpanel"
- id='open-close-editor'
- )
+ .tab-pane(role='tabpanel' id='open-close-editor')
if hasFeature('saas')
| The "Open/Close Editor" feature is not available in SAAS.
else
.row-spaced
- form(method='post',action='/admin/closeEditor')
- input(name="_csrf", type="hidden", value=csrfToken)
- button.btn.btn-danger(type="submit") Close Editor
+ form(method='post' action='/admin/closeEditor')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ button.btn.btn-danger(type='submit') Close Editor
p.small Will stop anyone opening the editor. Will NOT disconnect already connected users.
.row-spaced
- form(method='post',action='/admin/disconnectAllUsers')
- input(name="_csrf", type="hidden", value=csrfToken)
- button.btn.btn-danger(type="submit") Disconnect all users
+ form(method='post' action='/admin/disconnectAllUsers')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ button.btn.btn-danger(type='submit') Disconnect all users
p.small Will force disconnect all users with the editor open. Make sure to close the editor first to avoid them reconnecting.
.row-spaced
- form(method='post',action='/admin/openEditor')
- input(name="_csrf", type="hidden", value=csrfToken)
- button.btn.btn-danger(type="submit") Reopen Editor
+ form(method='post' action='/admin/openEditor')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ button.btn.btn-danger(type='submit') Reopen Editor
p.small Will reopen the editor after closing.
if hasFeature('saas')
- .tab-pane(
- role="tabpanel"
- id='tpds'
- )
+ .tab-pane(role='tabpanel' id='tpds')
h3 Flush project to TPDS
.row
- form.col-xs-6(method='post',action='/admin/flushProjectToTpds')
- input(name="_csrf", type="hidden", value=csrfToken)
+ form.col-xs-6(method='post' action='/admin/flushProjectToTpds')
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
label.form-label(for='project_id') project_id
- input.form-control(type='text', name='project_id', placeholder='project_id', required)
+ input.form-control(
+ name='project_id'
+ type='text'
+ placeholder='project_id'
+ required
+ )
.form-group
button.btn-primary.btn(type='submit') Flush
hr
h3 Poll Dropbox for user
.row
- form.col-xs-6(method='post',action='/admin/pollDropboxForUser')
- input(name="_csrf", type="hidden", value=csrfToken)
+ form.col-xs-6(method='post' action='/admin/pollDropboxForUser')
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
label.form-label(for='user_id') user_id
- input.form-control(type='text', name='user_id', placeholder='user_id', required)
+ input.form-control(
+ name='user_id'
+ type='text'
+ placeholder='user_id'
+ required
+ )
.form-group
button.btn-primary.btn(type='submit') Poll
diff --git a/services/web/app/views/beta_program/opt_in.pug b/services/web/app/views/beta_program/opt_in.pug
index 3122dc127f..c30cb78d9a 100644
--- a/services/web/app/views/beta_program/opt_in.pug
+++ b/services/web/app/views/beta_program/opt_in.pug
@@ -2,14 +2,14 @@ extends ../layout-marketing
include ../_mixins/back_to_btns
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container.beta-opt-in-wrapper
.row
.col-lg-10.offset-lg-1.col-xl-8.offset-xl-2
.card
.card-body
.page-header
- h1
+ h1
| #{translate("sharelatex_beta_program")}
.beta-opt-in
.container-fluid
@@ -28,7 +28,9 @@ block content
ul
li
| #{translate("beta_program_badge_description")}
- span.badge.bg-warning-light-bg.text-warning(aria-label=translate("beta_feature_badge"))
+ span.badge.bg-warning-light-bg.text-warning(
+ aria-label=translate('beta_feature_badge')
+ )
span.badge-content β
li !{translate("you_will_be_able_to_contact_us_any_time_to_share_your_feedback", {}, ['strong'])}.
li !{translate("we_may_also_contact_you_from_time_to_time_by_email_with_a_survey", {}, ['strong'])}.
@@ -40,37 +42,30 @@ block content
if user.betaProgram
form(
data-ol-regular-form
- method="post"
- action="/beta/opt-out"
+ method='post'
+ action='/beta/opt-out'
novalidate
)
- input(type="hidden", name="_csrf", value=csrfToken)
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
- a(
- href="https://forms.gle/CFEsmvZQTAwHCd3X9"
- target="_blank"
- rel="noopener noreferrer"
- ).btn.btn-primary.btn-lg #{translate("give_feedback")}
+ a.btn.btn-primary.btn-lg(
+ href='https://forms.gle/CFEsmvZQTAwHCd3X9'
+ target='_blank'
+ rel='noopener noreferrer'
+ ) #{translate("give_feedback")}
.form-group
button.btn.btn-secondary-info.btn-secondary.btn-sm(
- type="submit"
+ type='submit'
data-ol-disabled-inflight
)
- span(data-ol-inflight="idle") #{translate("beta_program_opt_out_action")}
- span(hidden data-ol-inflight="pending") #{translate("processing")}…
+ span(data-ol-inflight='idle') #{translate("beta_program_opt_out_action")}
+ span(hidden data-ol-inflight='pending') #{translate("processing")}…
else
- form(
- data-ol-regular-form
- method="post",
- action="/beta/opt-in"
- )
- input(type="hidden", name="_csrf", value=csrfToken)
+ form(data-ol-regular-form method='post' action='/beta/opt-in')
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
- button.btn.btn-primary(
- type="submit"
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("beta_program_opt_in_action")}
- span(hidden data-ol-inflight="pending") #{translate("joining")}…
+ button.btn.btn-primary(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("beta_program_opt_in_action")}
+ span(hidden data-ol-inflight='pending') #{translate("joining")}…
.page-separator
- +back-to-btns()
+ +back-to-btns
diff --git a/services/web/app/views/general/400.pug b/services/web/app/views/general/400.pug
index fcc3007e6f..5dad09910f 100644
--- a/services/web/app/views/general/400.pug
+++ b/services/web/app/views/general/400.pug
@@ -1,29 +1,29 @@
extends ../layout/layout-no-js
block vars
- - metadata = { title: 'Something went wrong' }
+ - metadata = {title: 'Something went wrong'}
block body
body.full-height
- main.content.content-alt.full-height#main-content
+ main#main-content.content.content-alt.full-height
.container.full-height
.error-container.full-height
.error-details
p.error-status Something went wrong, sorry.
p.error-description
| There was a problem with your request.
- if(message)
+ if message
|
| The error is:
- if(message)
+ if message
p.error-box
| #{message}
p.error-description
| Please go back and try again.
| If the problem persists, please contact us at
|
- a(href="mailto:" + settings.adminEmail) #{settings.adminEmail}
+ a(href='mailto:' + settings.adminEmail) #{settings.adminEmail}
| .
p.error-actions
- a.error-btn(href="javascript:history.back()") Back
- a.btn.btn-secondary(href="/") Home
+ a.error-btn(href='javascript:history.back()') Back
+ a.btn.btn-secondary(href='/') Home
diff --git a/services/web/app/views/general/404.pug b/services/web/app/views/general/404.pug
index f76eac6997..ce92d6d56e 100644
--- a/services/web/app/views/general/404.pug
+++ b/services/web/app/views/general/404.pug
@@ -1,11 +1,11 @@
extends ../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.error-container
.error-details
p.error-status Not found
p.error-description #{translate("cant_find_page")}
p.error-actions
- a.error-btn(href="/") Home
+ a.error-btn(href='/') Home
diff --git a/services/web/app/views/general/500.pug b/services/web/app/views/general/500.pug
index 41e7440e0d..22d6ceb35c 100644
--- a/services/web/app/views/general/500.pug
+++ b/services/web/app/views/general/500.pug
@@ -1,11 +1,11 @@
extends ../layout/layout-no-js
block vars
- - metadata = { title: 'Something went wrong' }
+ - metadata = {title: 'Something went wrong'}
block body
body.full-height
- main.content.content-alt.full-height#main-content
+ main#main-content.content.content-alt.full-height
.container.full-height
.error-container.full-height
.error-details
@@ -13,11 +13,11 @@ block body
p.error-description Our staff are probably looking into this, but if it continues, please check our status page at
|
|
- a(href="http://" + settings.statusPageUrl) #{settings.statusPageUrl}
+ a(href='http://' + settings.statusPageUrl) #{settings.statusPageUrl}
|
| or contact us at
|
- a(href="mailto:" + settings.adminEmail) #{settings.adminEmail}
+ a(href='mailto:' + settings.adminEmail) #{settings.adminEmail}
| .
p.error-actions
- a.error-btn(href="/") Home
+ a.error-btn(href='/') Home
diff --git a/services/web/app/views/general/closed.pug b/services/web/app/views/general/closed.pug
index b3f8ea2c04..3c1196a4cc 100644
--- a/services/web/app/views/general/closed.pug
+++ b/services/web/app/views/general/closed.pug
@@ -1,7 +1,7 @@
extends ../layout-marketing
block content
- main.content#main-content
+ main#main-content.content
.container
.row
.col-lg-8.offset-lg-2.text-center
diff --git a/services/web/app/views/general/post-gateway.pug b/services/web/app/views/general/post-gateway.pug
index b17e61cb41..c6bbc92d01 100644
--- a/services/web/app/views/general/post-gateway.pug
+++ b/services/web/app/views/general/post-gateway.pug
@@ -15,12 +15,8 @@ block content
.card-body
p.text-center #{translate('processing_your_request')}
- form(
- data-ol-regular-form
- data-ol-auto-submit
- method="POST"
- )
- input(name="_csrf" type="hidden" value=csrfToken)
- input(hidden name="viaGateway" type="submit" value="true")
- for name in Object.keys(form_data)
- input(name=name type="hidden" value=form_data[name])
+ form(data-ol-regular-form data-ol-auto-submit method='POST')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='viaGateway' hidden type='submit' value='true')
+ each name in Object.keys(form_data)
+ input(name=name type='hidden' value=form_data[name])
diff --git a/services/web/app/views/general/unsupported-browser.pug b/services/web/app/views/general/unsupported-browser.pug
index a2c2216315..1fd2c42bdb 100644
--- a/services/web/app/views/general/unsupported-browser.pug
+++ b/services/web/app/views/general/unsupported-browser.pug
@@ -1,11 +1,11 @@
extends ../layout/layout-no-js
block vars
- - metadata = { title: 'Unsupported browser' }
+ - metadata = {title: 'Unsupported browser'}
block body
body.full-height
- main.content.content-alt.full-height#main-content
+ main#main-content.content.content-alt.full-height
.container.full-height
.error-container.full-height
.error-details
@@ -15,7 +15,7 @@ block body
br
| If you think you're seeing this message in error,
|
- a(href="mailto:" + settings.adminEmail) please let us know
+ a(href='mailto:' + settings.adminEmail) please let us know
| .
if fromURL
@@ -33,7 +33,7 @@ block body
p
| Support for beta or developer-preview browser versions cannot be guaranteed. Please
|
- a(href="mailto:" + settings.adminEmail) get in touch
+ a(href='mailto:' + settings.adminEmail) get in touch
|
| if you encounter any issues while using the service with beta or developer-preview releases of supported browsers.
p
@@ -41,5 +41,5 @@ block body
p
| If you cannot upgrade to one of the supported browsers,
|
- a(href="mailto:" + settings.adminEmail) please let us know
+ a(href='mailto:' + settings.adminEmail) please let us know
| .
diff --git a/services/web/app/views/layout-base.pug b/services/web/app/views/layout-base.pug
index 0493281353..b590618387 100644
--- a/services/web/app/views/layout-base.pug
+++ b/services/web/app/views/layout-base.pug
@@ -2,8 +2,8 @@ include ./_mixins/foot_scripts
doctype html
html(
- lang=(currentLngCode || 'en')
- class=(fixedSizeDocument ? 'fixed-size-document' : undefined)
+ lang=currentLngCode || 'en'
+ class=fixedSizeDocument ? 'fixed-size-document' : undefined
)
- metadata = metadata || {}
- let bootstrap5PageStatus = 'enabled' // One of 'disabled' and 'enabled'
@@ -22,91 +22,128 @@ html(
include ./_metadata.pug
- const bootstrapVersion = bootstrap5PageStatus !== 'disabled' && (bootstrap5Override || bootstrap5PageSplitTest === '' || splitTestVariants[bootstrap5PageSplitTest] === 'enabled') ? 5 : 3
-
+
//- Stylesheet
- link(rel='stylesheet', href=buildCssPath(getCssThemeModifier(userSettings, brandVariation, enableIeeeBranding), bootstrapVersion), id="main-stylesheet")
+ link(
+ rel='stylesheet'
+ href=buildCssPath(getCssThemeModifier(userSettings, brandVariation, enableIeeeBranding), bootstrapVersion)
+ id='main-stylesheet'
+ )
block css
each file in entrypointStyles(entrypoint)
- link(rel='stylesheet', href=file)
+ link(rel='stylesheet' href=file)
block _headLinks
- if (typeof suppressRelAlternateLinks == "undefined")
+ if typeof suppressRelAlternateLinks == 'undefined'
if settings.i18n.subdomainLang
each subdomainDetails in settings.i18n.subdomainLang
if !subdomainDetails.hide
- link(rel="alternate", href=subdomainDetails.url + currentUrl, hreflang=subdomainDetails.lngCode)
+ link(
+ rel='alternate'
+ href=subdomainDetails.url + currentUrl
+ hreflang=subdomainDetails.lngCode
+ )
- if (entrypoint !== 'marketing')
- link(rel="preload", href=buildJsPath(currentLngCode + "-json.js"), as="script", nonce=scriptNonce)
+ if entrypoint !== 'marketing'
+ link(
+ rel='preload'
+ href=buildJsPath(currentLngCode + '-json.js')
+ as='script'
+ nonce=scriptNonce
+ )
//- Scripts
- if (typeof suppressGoogleAnalytics == "undefined")
+ if typeof suppressGoogleAnalytics == 'undefined'
include _google_analytics
block meta
- meta(name="ol-csrfToken" content=csrfToken)
+ meta(name='ol-csrfToken' content=csrfToken)
//- Configure dynamically loaded assets (via webpack) to be downloaded from CDN
//- See: https://webpack.js.org/guides/public-path/#on-the-fly
- meta(name="ol-baseAssetPath" content=buildBaseAssetPath())
- meta(name="ol-mathJaxPath" content=mathJaxPath)
- meta(name="ol-dictionariesRoot" content=dictionariesRoot)
+ meta(name='ol-baseAssetPath' content=buildBaseAssetPath())
+ meta(name='ol-mathJaxPath' content=mathJaxPath)
+ meta(name='ol-dictionariesRoot' content=dictionariesRoot)
- meta(name="ol-usersEmail" content=getUserEmail())
- meta(name="ol-ab" data-type="json" content={})
- meta(name="ol-user_id" content=getLoggedInUserId())
+ meta(name='ol-usersEmail' content=getUserEmail())
+ meta(name='ol-ab' data-type='json' content={})
+ meta(name='ol-user_id' content=getLoggedInUserId())
//- Internationalisation settings
- meta(name="ol-i18n" data-type="json" content={
- currentLangCode: currentLngCode
- })
+ meta(
+ name='ol-i18n'
+ data-type='json'
+ content={
+ currentLangCode: currentLngCode,
+ }
+ )
//- Expose some settings globally to the frontend
- meta(name="ol-ExposedSettings" data-type="json" content=ExposedSettings)
- meta(name="ol-splitTestVariants" data-type="json" content=splitTestVariants || {})
- meta(name="ol-splitTestInfo" data-type="json" content=splitTestInfo || {})
+ meta(name='ol-ExposedSettings' data-type='json' content=ExposedSettings)
+ meta(
+ name='ol-splitTestVariants'
+ data-type='json'
+ content=splitTestVariants || {}
+ )
+ meta(name='ol-splitTestInfo' data-type='json' content=splitTestInfo || {})
- if (typeof settings.algolia != "undefined")
- meta(name="ol-algolia" data-type="json" content={
- appId: settings.algolia.app_id,
- apiKey: settings.algolia.read_only_api_key,
- indexes: settings.algolia.indexes
- })
+ if typeof settings.algolia != 'undefined'
+ meta(
+ name='ol-algolia'
+ data-type='json'
+ content={
+ appId: settings.algolia.app_id,
+ apiKey: settings.algolia.read_only_api_key,
+ indexes: settings.algolia.indexes,
+ }
+ )
- meta(name="ol-isManagedAccount" data-type="boolean" content=isManagedAccount)
+ meta(
+ name='ol-isManagedAccount'
+ data-type='boolean'
+ content=isManagedAccount
+ )
each restriction in userRestrictions || []
- meta(name='ol-cannot-' + restriction data-type="boolean" content=true)
- meta(name="ol-bootstrapVersion" data-type="json" content=bootstrapVersion)
+ meta(name='ol-cannot-' + restriction data-type='boolean' content)
+ meta(name='ol-bootstrapVersion' data-type='json' content=bootstrapVersion)
block head-scripts
- body(class={
- 'thin-footer': showThinFooter,
- 'website-redesign': isWebsiteRedesign === true || websiteRedesignOverride,
- 'application-page': isApplicationPage
- }, data-theme="default")
- if(settings.recaptcha && settings.recaptcha.siteKeyV3)
- script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=" + settings.recaptcha.siteKeyV3, defer=deferScripts)
+ body(
+ class={
+ 'thin-footer': showThinFooter,
+ 'website-redesign': isWebsiteRedesign === true || websiteRedesignOverride,
+ 'application-page': isApplicationPage,
+ }
+ data-theme='default'
+ )
+ if settings.recaptcha && settings.recaptcha.siteKeyV3
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://www.recaptcha.net/recaptcha/api.js?render=' + settings.recaptcha.siteKeyV3
+ defer=deferScripts
+ )
- if (typeof suppressSkipToContent == "undefined")
- a(class="skip-to-content" href="#main-content") #{translate('skip_to_content')}
+ if typeof suppressSkipToContent == 'undefined'
+ a(class='skip-to-content' href='#main-content') #{translate('skip_to_content')}
block body
- if (settings.devToolbar.enabled)
- div#dev-toolbar
+ if settings.devToolbar.enabled
+ #dev-toolbar
block foot-scripts
+foot-scripts
include _customer_io
- script(type="text/javascript", nonce=scriptNonce).
- window.addEventListener('DOMContentLoaded', function() {
+ script(type='text/javascript' nonce=scriptNonce).
+ window.addEventListener('DOMContentLoaded', function () {
//- Look for bundle
var cdnBlocked = typeof Frontend === 'undefined'
//- Prevent loops
- var noCdnAlreadyInUrl = window.location.href.indexOf("nocdn=true") != -1
- if (cdnBlocked && !noCdnAlreadyInUrl && navigator.userAgent.indexOf("Googlebot") == -1) {
+ var noCdnAlreadyInUrl = window.location.href.indexOf('nocdn=true') != -1
+ if (cdnBlocked && !noCdnAlreadyInUrl && navigator.userAgent.indexOf('Googlebot') == -1) {
//- Set query param, server will not set CDN url
- window.location.search += "&nocdn=true";
+ window.location.search += '&nocdn=true'
}
})
diff --git a/services/web/app/views/layout-marketing.pug b/services/web/app/views/layout-marketing.pug
index 20126beda3..b54c30f033 100644
--- a/services/web/app/views/layout-marketing.pug
+++ b/services/web/app/views/layout-marketing.pug
@@ -7,7 +7,7 @@ block entrypointVar
- entrypoint = 'marketing'
block body
- if (typeof suppressNavbar === "undefined")
+ if typeof suppressNavbar === 'undefined'
if bootstrapVersion === 5
include layout/navbar-marketing-bootstrap-5
else
@@ -15,7 +15,7 @@ block body
block content
- if (typeof suppressFooter === "undefined")
+ if typeof suppressFooter === 'undefined'
if showThinFooter
if bootstrapVersion === 5
include layout/thin-footer-bootstrap-5
@@ -24,13 +24,13 @@ block body
else
include layout/fat-footer
- if (typeof(suppressCookieBanner) == 'undefined')
+ if typeof suppressCookieBanner == 'undefined'
include _cookie_banner
if bootstrapVersion === 5
- != moduleIncludes("contactModal-marketing-bootstrap-5", locals)
+ != moduleIncludes('contactModal-marketing-bootstrap-5', locals)
else
- != moduleIncludes("contactModal-marketing", locals)
+ != moduleIncludes('contactModal-marketing', locals)
block prepend foot-scripts
+bootstrap-js(bootstrapVersion)
diff --git a/services/web/app/views/layout-react.pug b/services/web/app/views/layout-react.pug
index be875b29f8..94ff3ba247 100644
--- a/services/web/app/views/layout-react.pug
+++ b/services/web/app/views/layout-react.pug
@@ -7,10 +7,10 @@ include ./_mixins/bootstrap_js
block entrypointVar
- entrypoint = 'marketing'
-
+
block isApplicationPageVar
- isApplicationPage = true
-
+
block append meta
- const canDisplayAdminMenu = hasAdminAccess()
- const canDisplayAdminRedirect = canRedirectToAdminDomain()
@@ -22,44 +22,52 @@ block append meta
- const enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
- const showSignUpLink = hasFeature('registration-page')
- meta(name="ol-navbar" data-type="json" content={
- customLogo: settings.nav.custom_logo,
- title: nav.title,
- canDisplayAdminMenu,
- canDisplayAdminRedirect,
- canDisplaySplitTestMenu,
- canDisplaySurveyMenu,
- canDisplayScriptLogMenu,
- enableUpgradeButton,
- suppressNavbarRight: !!suppressNavbarRight,
- suppressNavContentLinks: !!suppressNavContentLinks,
- showSubscriptionLink: nav.showSubscriptionLink,
- showSignUpLink: showSignUpLink,
- currentUrl: currentUrl,
- sessionUser: sessionUser ? { email: sessionUser.email} : undefined,
- adminUrl: settings.adminUrl,
- items: cloneAndTranslateText(nav.header_extras)
- })
- meta(name="ol-footer" data-type="json" content={
- showThinFooter: showThinFooter,
- showPoweredBy: !hasFeature('saas') && !settings.nav.hide_powered_by,
- subdomainLang: settings.i18n.subdomainLang,
- translatedLanguages: settings.translatedLanguages,
- leftItems: cloneAndTranslateText(settings.nav.left_footer),
- rightItems: settings.nav.right_footer
- })
+ meta(
+ name='ol-navbar'
+ data-type='json'
+ content={
+ customLogo: settings.nav.custom_logo,
+ title: nav.title,
+ canDisplayAdminMenu,
+ canDisplayAdminRedirect,
+ canDisplaySplitTestMenu,
+ canDisplaySurveyMenu,
+ canDisplayScriptLogMenu,
+ enableUpgradeButton,
+ suppressNavbarRight: !!suppressNavbarRight,
+ suppressNavContentLinks: !!suppressNavContentLinks,
+ showSubscriptionLink: nav.showSubscriptionLink,
+ showSignUpLink: showSignUpLink,
+ currentUrl: currentUrl,
+ sessionUser: sessionUser ? {email: sessionUser.email} : undefined,
+ adminUrl: settings.adminUrl,
+ items: cloneAndTranslateText(nav.header_extras),
+ }
+ )
+ meta(
+ name='ol-footer'
+ data-type='json'
+ content={
+ showThinFooter: showThinFooter,
+ showPoweredBy: !hasFeature('saas') && !settings.nav.hide_powered_by,
+ subdomainLang: settings.i18n.subdomainLang,
+ translatedLanguages: settings.translatedLanguages,
+ leftItems: cloneAndTranslateText(settings.nav.left_footer),
+ rightItems: settings.nav.right_footer,
+ }
+ )
block body
- if (typeof suppressNavbar === "undefined")
+ if typeof suppressNavbar === 'undefined'
include layout/navbar-marketing-react-bootstrap-5
block content
- if (typeof suppressFooter === "undefined")
+ if typeof suppressFooter === 'undefined'
if showThinFooter
include layout/thin-footer-bootstrap-5
else
include layout/fat-footer-react-bootstrap-5
- if (typeof suppressCookieBanner === "undefined")
+ if typeof suppressCookieBanner === 'undefined'
include _cookie_banner
diff --git a/services/web/app/views/layout-website-redesign.pug b/services/web/app/views/layout-website-redesign.pug
index d04d4b1202..5d7bce6c4d 100644
--- a/services/web/app/views/layout-website-redesign.pug
+++ b/services/web/app/views/layout-website-redesign.pug
@@ -7,7 +7,7 @@ block entrypointVar
- entrypoint = 'marketing'
block body
- if (typeof(suppressNavbar) == "undefined")
+ if typeof suppressNavbar == 'undefined'
if bootstrapVersion === 5
include layout/navbar-marketing-bootstrap-5
else
@@ -17,23 +17,23 @@ block body
//- bootstrapVersion needed here, because plans.pug uses both BS version
//- If the `plans-page-bs5` split test has been completed, remove bootstrapVersion logic
- if (typeof(suppressFooter) == "undefined")
+ if typeof suppressFooter == 'undefined'
if showThinFooter
if bootstrapVersion === 5
include layout/thin-footer-bootstrap-5
- else
+ else
include layout/thin-footer
else
include layout/fat-footer-website-redesign
- if (typeof(suppressCookieBanner) == 'undefined')
+ if typeof suppressCookieBanner == 'undefined'
include _cookie_banner
block contactModal
if bootstrapVersion === 5
- != moduleIncludes("contactModal-marketing-bootstrap-5", locals)
+ != moduleIncludes('contactModal-marketing-bootstrap-5', locals)
else
- != moduleIncludes("contactModal-marketing", locals)
+ != moduleIncludes('contactModal-marketing', locals)
block prepend foot-scripts
+bootstrap-js(bootstrapVersion)
diff --git a/services/web/app/views/layout/fat-footer-base.pug b/services/web/app/views/layout/fat-footer-base.pug
index 2e3dd2074f..e8380939f6 100644
--- a/services/web/app/views/layout/fat-footer-base.pug
+++ b/services/web/app/views/layout/fat-footer-base.pug
@@ -1,9 +1,9 @@
.fat-footer-base
.fat-footer-base-section.fat-footer-base-meta
- .fat-footer-base-item
+ .fat-footer-base-item
.fat-footer-base-copyright © #{new Date().getFullYear()} Overleaf
- a(href="/legal") #{translate('privacy_and_terms')}
- a(href="https://www.digital-science.com/security-certifications/") #{translate('compliance')}
+ a(href='/legal') #{translate('privacy_and_terms')}
+ a(href='https://www.digital-science.com/security-certifications/') #{translate('compliance')}
ul.fat-footer-base-item.list-unstyled.fat-footer-base-language
if bootstrapVersion === 5
include language-picker-bootstrap-5
@@ -11,22 +11,53 @@
include language-picker
.fat-footer-base-section.fat-footer-base-social
.fat-footer-base-item
- a.fat-footer-social.x-logo(href="https://x.com/overleaf")
- svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1227" height="25")
- path(d="M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z")
+ a.fat-footer-social.x-logo(href='https://x.com/overleaf')
+ svg(
+ xmlns='http://www.w3.org/2000/svg'
+ viewBox='0 0 1200 1227'
+ height='25'
+ )
+ path(
+ d='M714.163 519.284L1160.89 0H1055.03L667.137 450.887L357.328 0H0L468.492 681.821L0 1226.37H105.866L515.491 750.218L842.672 1226.37H1200L714.137 519.284H714.163ZM569.165 687.828L521.697 619.934L144.011 79.6944H306.615L611.412 515.685L658.88 583.579L1055.08 1150.3H892.476L569.165 687.854V687.828Z'
+ )
span.visually-hidden #{translate("app_on_x", {social: "X"})}
- a.fat-footer-social.facebook-logo(href="https://www.facebook.com/overleaf.editor")
- svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 666.66668 666.66717" height="25")
+ a.fat-footer-social.facebook-logo(
+ href='https://www.facebook.com/overleaf.editor'
+ )
+ svg(
+ xmlns='http://www.w3.org/2000/svg'
+ viewBox='0 0 666.66668 666.66717'
+ height='25'
+ )
defs
- clipPath(id="a" clipPathUnits="userSpaceOnUse")
- path(d="M0 700h700V0H0Z")
- g(clip-path="url(#a)" transform="matrix(1.33333 0 0 -1.33333 -133.333 800)")
- path.background(d="M0 0c0 138.071-111.929 250-250 250S-500 138.071-500 0c0-117.245 80.715-215.622 189.606-242.638v166.242h-51.552V0h51.552v32.919c0 85.092 38.508 124.532 122.048 124.532 15.838 0 43.167-3.105 54.347-6.211V81.986c-5.901.621-16.149.932-28.882.932-40.993 0-56.832-15.528-56.832-55.9V0h81.659l-14.028-76.396h-67.631v-171.773C-95.927-233.218 0-127.818 0 0" fill="#0866ff" transform="translate(600 350)")
- path.text(d="m0 0 14.029 76.396H-67.63v27.019c0 40.372 15.838 55.899 56.831 55.899 12.733 0 22.981-.31 28.882-.931v69.253c-11.18 3.106-38.509 6.212-54.347 6.212-83.539 0-122.048-39.441-122.048-124.533V76.396h-51.552V0h51.552v-166.242a250.559 250.559 0 0 1 60.394-7.362c10.254 0 20.358.632 30.288 1.831V0Z" fill="#fff" transform="translate(447.918 273.604)")
+ clipPath(id='a' clipPathUnits='userSpaceOnUse')
+ path(d='M0 700h700V0H0Z')
+ g(
+ clip-path='url(#a)'
+ transform='matrix(1.33333 0 0 -1.33333 -133.333 800)'
+ )
+ path.background(
+ d='M0 0c0 138.071-111.929 250-250 250S-500 138.071-500 0c0-117.245 80.715-215.622 189.606-242.638v166.242h-51.552V0h51.552v32.919c0 85.092 38.508 124.532 122.048 124.532 15.838 0 43.167-3.105 54.347-6.211V81.986c-5.901.621-16.149.932-28.882.932-40.993 0-56.832-15.528-56.832-55.9V0h81.659l-14.028-76.396h-67.631v-171.773C-95.927-233.218 0-127.818 0 0'
+ fill='#0866ff'
+ transform='translate(600 350)'
+ )
+ path.text(
+ d='m0 0 14.029 76.396H-67.63v27.019c0 40.372 15.838 55.899 56.831 55.899 12.733 0 22.981-.31 28.882-.931v69.253c-11.18 3.106-38.509 6.212-54.347 6.212-83.539 0-122.048-39.441-122.048-124.533V76.396h-51.552V0h51.552v-166.242a250.559 250.559 0 0 1 60.394-7.362c10.254 0 20.358.632 30.288 1.831V0Z'
+ fill='#fff'
+ transform='translate(447.918 273.604)'
+ )
span.visually-hidden #{translate("app_on_x", {social: "Facebook"})}
- a.fat-footer-social.linkedin-logo(href="https://www.linkedin.com/company/writelatex-limited")
- svg(xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72 72" height="25")
- g(fill="none" fill-rule="evenodd")
- path.background(fill="#0B66C3" d="M8 72h56a8 8 0 0 0 8-8V8a8 8 0 0 0-8-8H8a8 8 0 0 0-8 8v56a8 8 0 0 0 8 8")
- path.text(fill="#FFF" d="M62 62H51.316V43.802c0-4.99-1.896-7.777-5.845-7.777-4.296 0-6.54 2.901-6.54 7.777V62H28.632V27.333H38.93v4.67s3.096-5.729 10.453-5.729c7.353 0 12.617 4.49 12.617 13.777zM16.35 22.794c-3.508 0-6.35-2.864-6.35-6.397C10 12.864 12.842 10 16.35 10c3.507 0 6.347 2.864 6.347 6.397 0 3.533-2.84 6.397-6.348 6.397ZM11.032 62h10.736V27.333H11.033V62")
+ a.fat-footer-social.linkedin-logo(
+ href='https://www.linkedin.com/company/writelatex-limited'
+ )
+ svg(xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 72' height='25')
+ g(fill='none' fill-rule='evenodd')
+ path.background(
+ fill='#0B66C3'
+ d='M8 72h56a8 8 0 0 0 8-8V8a8 8 0 0 0-8-8H8a8 8 0 0 0-8 8v56a8 8 0 0 0 8 8'
+ )
+ path.text(
+ fill='#FFF'
+ d='M62 62H51.316V43.802c0-4.99-1.896-7.777-5.845-7.777-4.296 0-6.54 2.901-6.54 7.777V62H28.632V27.333H38.93v4.67s3.096-5.729 10.453-5.729c7.353 0 12.617 4.49 12.617 13.777zM16.35 22.794c-3.508 0-6.35-2.864-6.35-6.397C10 12.864 12.842 10 16.35 10c3.507 0 6.347 2.864 6.347 6.397 0 3.533-2.84 6.397-6.348 6.397ZM11.032 62h10.736V27.333H11.033V62'
+ )
span.visually-hidden #{translate("app_on_x", {social: "LinkedIn"})}
diff --git a/services/web/app/views/layout/fat-footer-website-redesign.pug b/services/web/app/views/layout/fat-footer-website-redesign.pug
index cd68e1daf6..ba6286a296 100644
--- a/services/web/app/views/layout/fat-footer-website-redesign.pug
+++ b/services/web/app/views/layout/fat-footer-website-redesign.pug
@@ -1,84 +1,87 @@
footer.fat-footer.hidden-print.website-redesign-fat-footer
- .fat-footer-container(role="navigation" aria-label=translate('footer_navigation'))
+ .fat-footer-container(
+ role='navigation'
+ aria-label=translate('footer_navigation')
+ )
.fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined)
- .footer-section#footer-brand
- a(href='/', aria-label=settings.appName).footer-brand
-
+ #footer-brand.footer-section
+ a.footer-brand(href='/' aria-label=settings.appName)
+
.footer-section
h2.footer-section-heading #{translate('About')}
-
+
ul.list-unstyled
li
- a(href="/about") #{translate('footer_about_us')}
+ a(href='/about') #{translate('footer_about_us')}
li
- a(href="/about/values") #{translate('our_values')}
+ a(href='/about/values') #{translate('our_values')}
li
- a(href="https://digitalscience.pinpointhq.com/") #{translate('careers')}
+ a(href='https://digitalscience.pinpointhq.com/') #{translate('careers')}
li
- a(href="/for/press") !{translate('press_and_awards')}
+ a(href='/for/press') !{translate('press_and_awards')}
li
- a(href="/blog") #{translate('blog')}
-
+ a(href='/blog') #{translate('blog')}
+
.footer-section
h2.footer-section-heading #{translate('learn')}
-
+
ul.list-unstyled
li
- a(href="/learn/latex/Learn_LaTeX_in_30_minutes") #{translate('latex_in_thirty_minutes')}
+ a(href='/learn/latex/Learn_LaTeX_in_30_minutes') #{translate('latex_in_thirty_minutes')}
li
- a(href="/latex/templates") #{translate('templates')}
+ a(href='/latex/templates') #{translate('templates')}
li
- a(href="/events/webinars") #{translate('webinars')}
+ a(href='/events/webinars') #{translate('webinars')}
li
- a(href="/learn/latex/Tutorials") #{translate('tutorials')}
+ a(href='/learn/latex/Tutorials') #{translate('tutorials')}
li
- a(href="/learn/latex/Inserting_Images") #{translate('how_to_insert_images')}
+ a(href='/learn/latex/Inserting_Images') #{translate('how_to_insert_images')}
li
- a(href="/learn/latex/Tables") #{translate('how_to_create_tables')}
-
+ a(href='/learn/latex/Tables') #{translate('how_to_create_tables')}
+
.footer-section
h2.footer-section-heading !{translate('footer_plans_and_pricing')}
-
+
ul.list-unstyled
li
- a(href="/learn/how-to/Overleaf_premium_features") #{translate('premium_features')}
+ a(href='/learn/how-to/Overleaf_premium_features') #{translate('premium_features')}
li
- a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')}
+ a(href='/user/subscription/plans?itm_referrer=footer-for-indv-groups') !{translate('for_individuals_and_groups')}
li
- a(href="/for/enterprises") #{translate('for_business')}
+ a(href='/for/enterprises') #{translate('for_business')}
li
- a(href="/for/universities") #{translate('for_universities')}
+ a(href='/for/universities') #{translate('for_universities')}
li
a(
data-ol-for-students-link
- href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
+ href='/user/subscription/plans?itm_referrer=footer-for-students#student-annual'
) #{translate('for_students')}
li
- a(href="/for/government") #{translate('for_government')}
-
+ a(href='/for/government') #{translate('for_government')}
+
.footer-section
h2.footer-section-heading #{translate('get_involved')}
-
+
ul.list-unstyled
li
- a(href="/for/community/advisors") #{translate('become_an_advisor')}
+ a(href='/for/community/advisors') #{translate('become_an_advisor')}
li
- a(href="https://forms.gle/67PSpN1bLnjGCmPQ9") #{translate('let_us_know_what_you_think')}
+ a(href='https://forms.gle/67PSpN1bLnjGCmPQ9') #{translate('let_us_know_what_you_think')}
if user
li
- a(href="/beta/participate") #{translate('join_beta_program')}
-
+ a(href='/beta/participate') #{translate('join_beta_program')}
+
.footer-section
h2.footer-section-heading #{translate('help')}
-
+
ul.list-unstyled
li
- a(href="/about/why-latex") #{translate('why_latex')}
+ a(href='/about/why-latex') #{translate('why_latex')}
li
- a(href="/learn") #{translate('Documentation')}
+ a(href='/learn') #{translate('Documentation')}
li
- a(href="/contact") #{translate('footer_contact_us')}
+ a(href='/contact') #{translate('footer_contact_us')}
li
- a(href="https://status.overleaf.com/") #{translate('website_status')}
-
+ a(href='https://status.overleaf.com/') #{translate('website_status')}
+
include fat-footer-base
diff --git a/services/web/app/views/layout/fat-footer.pug b/services/web/app/views/layout/fat-footer.pug
index d319a217cb..c7c19bd4a3 100644
--- a/services/web/app/views/layout/fat-footer.pug
+++ b/services/web/app/views/layout/fat-footer.pug
@@ -1,84 +1,87 @@
footer.fat-footer.hidden-print
- .fat-footer-container(role="navigation" aria-label=translate('footer_navigation'))
+ .fat-footer-container(
+ role='navigation'
+ aria-label=translate('footer_navigation')
+ )
.fat-footer-sections(class=hideFatFooter ? 'hidden' : undefined)
- .footer-section#footer-brand
- a(href='/', aria-label=settings.appName).footer-brand
-
+ #footer-brand.footer-section
+ a.footer-brand(href='/' aria-label=settings.appName)
+
.footer-section
h2.footer-section-heading #{translate('About')}
-
+
ul.list-unstyled
li
- a(href="/about") #{translate('footer_about_us')}
+ a(href='/about') #{translate('footer_about_us')}
li
- a(href="/about/values") #{translate('our_values')}
+ a(href='/about/values') #{translate('our_values')}
li
- a(href="https://digitalscience.pinpointhq.com/") #{translate('careers')}
+ a(href='https://digitalscience.pinpointhq.com/') #{translate('careers')}
li
- a(href="/for/press") !{translate('press_and_awards')}
+ a(href='/for/press') !{translate('press_and_awards')}
li
- a(href="/blog") #{translate('blog')}
-
+ a(href='/blog') #{translate('blog')}
+
.footer-section
h2.footer-section-heading #{translate('learn')}
-
+
ul.list-unstyled
li
- a(href="/learn/latex/Learn_LaTeX_in_30_minutes") #{translate('latex_in_thirty_minutes')}
+ a(href='/learn/latex/Learn_LaTeX_in_30_minutes') #{translate('latex_in_thirty_minutes')}
li
- a(href="/latex/templates") #{translate('templates')}
+ a(href='/latex/templates') #{translate('templates')}
li
- a(href="/events/webinars") #{translate('webinars')}
+ a(href='/events/webinars') #{translate('webinars')}
li
- a(href="/learn/latex/Tutorials") #{translate('tutorials')}
+ a(href='/learn/latex/Tutorials') #{translate('tutorials')}
li
- a(href="/learn/latex/Inserting_Images") #{translate('how_to_insert_images')}
+ a(href='/learn/latex/Inserting_Images') #{translate('how_to_insert_images')}
li
- a(href="/learn/latex/Tables") #{translate('how_to_create_tables')}
-
+ a(href='/learn/latex/Tables') #{translate('how_to_create_tables')}
+
.footer-section
h2.footer-section-heading !{translate('footer_plans_and_pricing')}
-
+
ul.list-unstyled
li
- a(href="/learn/how-to/Overleaf_premium_features") #{translate('premium_features')}
+ a(href='/learn/how-to/Overleaf_premium_features') #{translate('premium_features')}
li
- a(href="/user/subscription/plans?itm_referrer=footer-for-indv-groups") !{translate('for_individuals_and_groups')}
+ a(href='/user/subscription/plans?itm_referrer=footer-for-indv-groups') !{translate('for_individuals_and_groups')}
li
- a(href="/for/enterprises") #{translate('for_enterprise')}
+ a(href='/for/enterprises') #{translate('for_enterprise')}
li
- a(href="/for/universities") #{translate('for_universities')}
+ a(href='/for/universities') #{translate('for_universities')}
li
a(
data-ol-for-students-link
- href="/user/subscription/plans?itm_referrer=footer-for-students#student-annual"
+ href='/user/subscription/plans?itm_referrer=footer-for-students#student-annual'
) #{translate('for_students')}
li
- a(href="/for/government") #{translate('for_government')}
-
+ a(href='/for/government') #{translate('for_government')}
+
.footer-section
h2.footer-section-heading #{translate('get_involved')}
-
+
ul.list-unstyled
li
- a(href="/for/community/advisors") #{translate('become_an_advisor')}
+ a(href='/for/community/advisors') #{translate('become_an_advisor')}
li
- a(href="https://forms.gle/67PSpN1bLnjGCmPQ9") #{translate('let_us_know_what_you_think')}
+ a(href='https://forms.gle/67PSpN1bLnjGCmPQ9') #{translate('let_us_know_what_you_think')}
if user
li
- a(href="/beta/participate") #{translate('join_beta_program')}
-
+ a(href='/beta/participate') #{translate('join_beta_program')}
+
.footer-section
h2.footer-section-heading #{translate('help')}
-
+
ul.list-unstyled
li
- a(href="/about/why-latex") #{translate('why_latex')}
+ a(href='/about/why-latex') #{translate('why_latex')}
li
- a(href="/learn") #{translate('Documentation')}
+ a(href='/learn') #{translate('Documentation')}
li
- a(href="/contact") #{translate('footer_contact_us')}
+ a(href='/contact') #{translate('footer_contact_us')}
li
- a(href="https://status.overleaf.com/") #{translate('website_status')}
-
+ a(href='https://status.overleaf.com/') #{translate('website_status')}
+
include fat-footer-base
diff --git a/services/web/app/views/layout/language-picker-bootstrap-5.pug b/services/web/app/views/layout/language-picker-bootstrap-5.pug
index 44997a8ca4..09f8f58c7d 100644
--- a/services/web/app/views/layout/language-picker-bootstrap-5.pug
+++ b/services/web/app/views/layout/language-picker-bootstrap-5.pug
@@ -1,27 +1,35 @@
include ../_mixins/material_symbol
-li.dropdown.dropup.subdued(dropdown).language-picker
+li.dropdown.dropup.subdued.language-picker(dropdown)
button#language-picker-toggle.btn.btn-link.btn-inline-link(
- dropdown-toggle,
- data-ol-lang-selector-tooltip,
- data-bs-toggle="dropdown",
- aria-haspopup="true",
- aria-expanded="false",
- aria-label="Select " + translate('language'),
+ dropdown-toggle
+ data-ol-lang-selector-tooltip
+ data-bs-toggle='dropdown'
+ aria-haspopup='true'
+ aria-expanded='false'
+ aria-label='Select ' + translate('language')
tooltip=translate('language')
title=translate('language')
)
- +material-symbol("translate")
+ +material-symbol('translate')
|
span.language-picker-text #{settings.translatedLanguages[currentLngCode]}
- ul.dropdown-menu.dropdown-menu-sm-width(role="menu" aria-labelledby="language-picker-toggle")
+ ul.dropdown-menu.dropdown-menu-sm-width(
+ role='menu'
+ aria-labelledby='language-picker-toggle'
+ )
li.dropdown-header #{translate("language")}
each subdomainDetails, subdomain in settings.i18n.subdomainLang
if !subdomainDetails.hide
- let isActive = subdomainDetails.lngCode === currentLngCode
li.lng-option
- a.menu-indent(href=subdomainDetails.url+currentUrlWithQueryParams, role="menuitem", class=isActive ? 'dropdown-item active' : 'dropdown-item', aria-selected=isActive ? 'true' : 'false')
+ a.menu-indent(
+ href=subdomainDetails.url + currentUrlWithQueryParams
+ role='menuitem'
+ class=isActive ? 'dropdown-item active' : 'dropdown-item'
+ aria-selected=isActive ? 'true' : 'false'
+ )
| #{settings.translatedLanguages[subdomainDetails.lngCode]}
if subdomainDetails.lngCode === currentLngCode
- +material-symbol("check", "dropdown-item-trailing-icon")
+ +material-symbol('check', 'dropdown-item-trailing-icon')
diff --git a/services/web/app/views/layout/language-picker.pug b/services/web/app/views/layout/language-picker.pug
index d26d8a8bf7..e88ff716ec 100644
--- a/services/web/app/views/layout/language-picker.pug
+++ b/services/web/app/views/layout/language-picker.pug
@@ -1,13 +1,13 @@
-li.dropdown.dropup.subdued(dropdown).language-picker
- a.dropdown-toggle#language-picker-toggle(
- href="#",
- dropdown-toggle,
- data-ol-lang-selector-tooltip,
- data-toggle="dropdown",
- role="button"
- aria-haspopup="true",
- aria-expanded="false",
- aria-label="Select " + translate('language'),
+li.dropdown.dropup.subdued.language-picker(dropdown)
+ a#language-picker-toggle.dropdown-toggle(
+ href='#'
+ dropdown-toggle
+ data-ol-lang-selector-tooltip
+ data-toggle='dropdown'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ aria-label='Select ' + translate('language')
tooltip=translate('language')
title=translate('language')
)
@@ -15,10 +15,13 @@ li.dropdown.dropup.subdued(dropdown).language-picker
|
| #{settings.translatedLanguages[currentLngCode]}
- ul.dropdown-menu(role="menu" aria-labelledby="language-picker-toggle")
+ ul.dropdown-menu(role='menu' aria-labelledby='language-picker-toggle')
li.dropdown-header #{translate("language")}
each subdomainDetails, subdomain in settings.i18n.subdomainLang
if !subdomainDetails.hide
li.lng-option
- a.menu-indent(href=subdomainDetails.url+currentUrlWithQueryParams role="menuitem")
+ a.menu-indent(
+ href=subdomainDetails.url + currentUrlWithQueryParams
+ role='menuitem'
+ )
| #{settings.translatedLanguages[subdomainDetails.lngCode]}
diff --git a/services/web/app/views/layout/layout-no-js.pug b/services/web/app/views/layout/layout-no-js.pug
index b5bf3cc434..76a31b72a5 100644
--- a/services/web/app/views/layout/layout-no-js.pug
+++ b/services/web/app/views/layout/layout-no-js.pug
@@ -1,18 +1,20 @@
doctype html
-html(lang="en")
-
+html(lang='en')
- metadata = metadata || {}
block vars
head
- if (metadata && metadata.title)
+ if metadata && metadata.title
title= metadata.title
if metadata && metadata.viewport
- meta(name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes")
+ meta(
+ name='viewport'
+ content='width=device-width, initial-scale=1.0, user-scalable=yes'
+ )
- link(rel="icon", href="/favicon.ico")
+ link(rel='icon' href='/favicon.ico')
if buildCssPath
- link(rel="stylesheet", href=buildCssPath('', 5))
+ link(rel='stylesheet' href=buildCssPath('', 5))
block body
diff --git a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
index c581ab29ce..29b12a056d 100644
--- a/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
+++ b/services/web/app/views/layout/navbar-marketing-bootstrap-5.pug
@@ -1,26 +1,32 @@
include ../_mixins/navbar
-nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
- 'website-redesign-navbar': isWebsiteRedesign
-})
+nav.navbar.navbar-default.navbar-main.navbar-expand-lg(
+ class={
+ 'website-redesign-navbar': isWebsiteRedesign,
+ }
+)
.container-fluid.navbar-container
.navbar-header
if settings.nav.custom_logo
- a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
- else if (nav.title)
- a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
+ a.navbar-brand(
+ href='/'
+ aria-label=settings.appName
+ style='background-image:url("' + settings.nav.custom_logo + '")'
+ )
+ else if nav.title
+ a.navbar-title(href='/' aria-label=settings.appName) #{nav.title}
else
- a(href='/', aria-label=settings.appName).navbar-brand
+ a.navbar-brand(href='/' aria-label=settings.appName)
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
- if (enableUpgradeButton)
+ if enableUpgradeButton
a.btn.btn-primary.me-2.d-md-none(
- href="/user/subscription/plans"
- event-tracking="upgrade-button-click"
- event-tracking-mb="true"
- event-tracking-label="upgrade"
- event-tracking-trigger="click"
- event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
+ href='/user/subscription/plans'
+ event-tracking='upgrade-button-click'
+ event-tracking-mb='true'
+ event-tracking-label='upgrade'
+ event-tracking-trigger='click'
+ event-segmentation={source: 'dashboard-top', projectDashboardReact: 'enabled', isDashboardSidebarHidden: 'true', isScreenWidthLessThan768px: 'true'}
) #{translate("upgrade")}
- var canDisplayAdminMenu = hasAdminAccess()
@@ -29,45 +35,45 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
- if (typeof suppressNavbarRight === "undefined")
+ if typeof suppressNavbarRight === 'undefined'
button.navbar-toggler.collapsed(
- type="button",
- data-bs-toggle="collapse",
- data-bs-target="#navbar-main-collapse"
- aria-controls="navbar-main-collapse"
- aria-expanded="false"
- aria-label="Toggle " + translate('navigation')
+ type='button'
+ data-bs-toggle='collapse'
+ data-bs-target='#navbar-main-collapse'
+ aria-controls='navbar-main-collapse'
+ aria-expanded='false'
+ aria-label='Toggle ' + translate('navigation')
)
- i.fa.fa-bars(aria-hidden="true")
+ i.fa.fa-bars(aria-hidden='true')
- .navbar-collapse.collapse#navbar-main-collapse
- ul.nav.navbar-nav.navbar-right.ms-auto(role="menubar")
- if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
+ #navbar-main-collapse.navbar-collapse.collapse
+ ul.nav.navbar-nav.navbar-right.ms-auto(role='menubar')
+ if canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu
+nav-item.dropdown.subdued
button.dropdown-toggle(
- aria-haspopup="true",
- aria-expanded="false",
- data-bs-toggle="dropdown"
- role="menuitem"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "admin", "location": "top-menu"}
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-bs-toggle='dropdown'
+ role='menuitem'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'admin', location: 'top-menu'}
)
| Admin
+dropdown-menu.dropdown-menu-end
if canDisplayAdminMenu
- +dropdown-menu-link-item()(href="/admin") Manage Site
- +dropdown-menu-link-item()(href="/admin/user") Manage Users
- +dropdown-menu-link-item()(href="/admin/project") Project URL Lookup
+ +dropdown-menu-link-item(href='/admin') Manage Site
+ +dropdown-menu-link-item(href='/admin/user') Manage Users
+ +dropdown-menu-link-item(href='/admin/project') Project URL Lookup
if canDisplayAdminRedirect
- +dropdown-menu-link-item()(href=settings.adminUrl) Switch to Admin
+ +dropdown-menu-link-item(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
- +dropdown-menu-link-item()(href="/admin/split-test") Manage Feature Flags
+ +dropdown-menu-link-item(href='/admin/split-test') Manage Feature Flags
if canDisplaySurveyMenu
- +dropdown-menu-link-item()(href="/admin/survey") Manage Surveys
+ +dropdown-menu-link-item(href='/admin/survey') Manage Surveys
if canDisplayScriptLogMenu
- +dropdown-menu-link-item()(href="/admin/script-logs") View Script Logs
+ +dropdown-menu-link-item(href='/admin/script-logs') View Script Logs
// loop over header_extras
each item in nav.header_extras
@@ -86,14 +92,14 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
if item.dropdown
+nav-item.dropdown(class=item.class)
button.dropdown-toggle(
- aria-haspopup="true",
- aria-expanded="false",
- data-bs-toggle="dropdown"
- role="menuitem"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": item.trackingKey, "location": "top-menu"}
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-bs-toggle='dropdown'
+ role='menuitem'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
)
| !{translate(item.text)}
+dropdown-menu.dropdown-menu-end
@@ -101,31 +107,41 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
if child.divider
+dropdown-menu-divider
else if child.isContactUs
- +dropdown-menu-link-item()(data-ol-open-contact-form-modal="contact-us" data-bs-target="#contactUsModal" href data-bs-toggle="modal" event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
+ +dropdown-menu-link-item(
+ data-ol-open-contact-form-modal='contact-us'
+ data-bs-target='#contactUsModal'
+ href
+ data-bs-toggle='modal'
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'contact', location: 'top-menu'}
+ )
span
| #{translate("contact_us")}
else
if child.url
- +dropdown-menu-link-item()(
- href=child.url,
- class=child.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ item: child.trackingKey, location: 'top-menu' }
+ +dropdown-menu-link-item(
+ href=child.url
+ class=child.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: child.trackingKey, location: 'top-menu'}
) !{translate(child.text)}
else
- +dropdown-menu-item !{translate(child.text)}
+ +dropdown-menu-item
+ | !{translate(child.text)}
else
+nav-item(class=item.class)
if item.url
+nav-link(
- href=item.url,
- class=item.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ item: item.trackingKey, location: 'top-menu' }
+ href=item.url
+ class=item.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
) !{translate(item.text)}
else
| !{translate(item.text)}
@@ -136,48 +152,48 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
if hasFeature('registration-page')
+nav-item.primary
+nav-link(
- href="/register"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
+ href='/register'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'register', location: 'top-menu'}
) #{translate('sign_up')}
// login link
+nav-item
+nav-link(
- href="/login"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
+ href='/login'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'login', location: 'top-menu'}
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
+nav-item
- +nav-link(href="/project") #{translate('Projects')}
+ +nav-link(href='/project') #{translate('Projects')}
+nav-item.dropdown
button.dropdown-toggle(
- aria-haspopup="true",
- aria-expanded="false",
- data-bs-toggle="dropdown"
- role="menuitem"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "account", "location": "top-menu"}
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-bs-toggle='dropdown'
+ role='menuitem'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'account', location: 'top-menu'}
)
| #{translate('Account')}
+dropdown-menu.dropdown-menu-end
+dropdown-menu-item
- div.disabled.dropdown-item #{getSessionUser().email}
+ .disabled.dropdown-item #{getSessionUser().email}
+dropdown-menu-divider
- +dropdown-menu-link-item()(href="/user/settings") #{translate('account_settings')}
+ +dropdown-menu-link-item(href='/user/settings') #{translate('account_settings')}
if nav.showSubscriptionLink
- +dropdown-menu-link-item()(href="/user/subscription") #{translate('subscription')}
+ +dropdown-menu-link-item(href='/user/subscription') #{translate('subscription')}
+dropdown-menu-divider
+dropdown-menu-item
//-
@@ -185,14 +201,10 @@ nav.navbar.navbar-default.navbar-main.navbar-expand-lg(class={
this is that if the button is inside the form, screen readers will not count it in the total
number of menu items.
button.btn-link.text-left.dropdown-menu-button.dropdown-item(
- role="menuitem",
- tabindex="-1"
- form="logOutForm"
+ role='menuitem'
+ tabindex='-1'
+ form='logOutForm'
)
| #{translate('log_out')}
- form(
- method="POST",
- action="/logout",
- id="logOutForm"
- )
- input(name='_csrf', type='hidden', value=csrfToken)
+ form(method='POST' action='/logout' id='logOutForm')
+ input(name='_csrf' type='hidden' value=csrfToken)
diff --git a/services/web/app/views/layout/navbar-marketing.pug b/services/web/app/views/layout/navbar-marketing.pug
index c5e9f2e0bf..4d374bd8ad 100644
--- a/services/web/app/views/layout/navbar-marketing.pug
+++ b/services/web/app/views/layout/navbar-marketing.pug
@@ -1,32 +1,44 @@
-nav.navbar.navbar-default.navbar-main(class={
- 'website-redesign-navbar': isWebsiteRedesign
-})
+nav.navbar.navbar-default.navbar-main(
+ class={
+ 'website-redesign-navbar': isWebsiteRedesign,
+ }
+)
.container-fluid
.navbar-header
- if (typeof(suppressNavbarRight) == "undefined")
+ if typeof suppressNavbarRight == 'undefined'
button.navbar-toggle.collapsed(
- type="button",
- data-toggle="collapse",
- data-target="#navbar-main-collapse"
- aria-label="Toggle " + translate('navigation')
+ type='button'
+ data-toggle='collapse'
+ data-target='#navbar-main-collapse'
+ aria-label='Toggle ' + translate('navigation')
)
- i.fa.fa-bars(aria-hidden="true")
+ i.fa.fa-bars(aria-hidden='true')
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
- if (enableUpgradeButton)
+ if enableUpgradeButton
+ //- prettier-ignore
a.btn.btn-primary.pull-right.me-2.visible-xs(
- href="/user/subscription/plans"
- event-tracking="upgrade-button-click"
- event-tracking-mb="true"
- event-tracking-label="upgrade"
- event-tracking-trigger="click"
- event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
+ href='/user/subscription/plans'
+ event-tracking='upgrade-button-click'
+ event-tracking-mb='true'
+ event-tracking-label='upgrade'
+ event-tracking-trigger='click'
+ event-segmentation={
+ source: "dashboard-top",
+ "project-dashboard-react": "enabled",
+ "is-dashboard-sidebar-hidden": "true",
+ "is-screen-width-less-than-768px": "true"
+ }
) #{translate("upgrade")}
if settings.nav.custom_logo
- a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
- else if (nav.title)
- a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
+ a.navbar-brand(
+ href='/'
+ aria-label=settings.appName
+ style='background-image:url("' + settings.nav.custom_logo + '")'
+ )
+ else if nav.title
+ a.navbar-title(href='/' aria-label=settings.appName) #{nav.title}
else
- a(href='/', aria-label=settings.appName).navbar-brand
+ a.navbar-brand(href='/' aria-label=settings.appName)
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
@@ -34,44 +46,44 @@ nav.navbar.navbar-default.navbar-main(class={
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
- if (typeof(suppressNavbarRight) == "undefined")
- .navbar-collapse.collapse#navbar-main-collapse
+ if typeof suppressNavbarRight == 'undefined'
+ #navbar-main-collapse.navbar-collapse.collapse
ul.nav.navbar-nav.navbar-right
- if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
+ if canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu
li.dropdown.subdued
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "admin", "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'admin', location: 'top-menu'}
)
| Admin
span.caret
ul.dropdown-menu
if canDisplayAdminMenu
li
- a(href="/admin") Manage Site
+ a(href='/admin') Manage Site
li
- a(href="/admin/user") Manage Users
+ a(href='/admin/user') Manage Users
li
- a(href="/admin/project") Project URL Lookup
+ a(href='/admin/project') Project URL Lookup
if canDisplayAdminRedirect
li
a(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
li
- a(href="/admin/split-test") Manage Feature Flags
+ a(href='/admin/split-test') Manage Feature Flags
if canDisplaySurveyMenu
li
- a(href="/admin/survey") Manage Surveys
+ a(href='/admin/survey') Manage Surveys
if canDisplayScriptLogMenu
li
- a(href="/admin/script-logs") View Script Logs
+ a(href='/admin/script-logs') View Script Logs
// loop over header_extras
each item in nav.header_extras
@@ -90,15 +102,15 @@ nav.navbar.navbar-default.navbar-main(class={
if item.dropdown
li.dropdown(class=item.class)
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": item.trackingKey, "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
)
| !{translate(item.text)}
span.caret
@@ -108,18 +120,25 @@ nav.navbar.navbar-default.navbar-main(class={
li.divider
else if child.isContactUs
li
- a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
+ a(
+ data-ol-open-contact-form-modal='contact-us'
+ href
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'contact', location: 'top-menu'}
+ )
span
| #{translate("contact_us")}
else
li
if child.url
a(
- href=child.url,
- class=child.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
+ href=child.url
+ class=child.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
event-segmentation={item: item.trackingKey, location: 'top-menu'}
) !{translate(child.text)}
else
@@ -128,12 +147,12 @@ nav.navbar.navbar-default.navbar-main(class={
li(class=item.class)
if item.url
a(
- href=item.url,
- class=item.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ item: item.trackingKey, location: 'top-menu' }
+ href=item.url
+ class=item.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
) !{translate(item.text)}
else
| !{translate(item.text)}
@@ -144,54 +163,54 @@ nav.navbar.navbar-default.navbar-main(class={
if hasFeature('registration-page')
li.primary
a(
- href="/register"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
+ href='/register'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'register', location: 'top-menu'}
) #{translate('sign_up')}
// login link
li
a(
- href="/login"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
+ href='/login'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'login', location: 'top-menu'}
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
li
- a(href="/project") #{translate('Projects')}
+ a(href='/project') #{translate('Projects')}
li.dropdown
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "account", "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'account', location: 'top-menu'}
)
| #{translate('Account')}
span.caret
ul.dropdown-menu
li
- div.subdued #{getSessionUser().email}
+ .subdued #{getSessionUser().email}
li.divider.hidden-xs.hidden-sm
li
- a(href="/user/settings") #{translate('account_settings')}
+ a(href='/user/settings') #{translate('account_settings')}
if nav.showSubscriptionLink
li
- a(href="/user/subscription") #{translate('subscription')}
+ a(href='/user/subscription') #{translate('subscription')}
li.divider.hidden-xs.hidden-sm
li
- form(method="POST" action="/logout")
- input(name='_csrf', type='hidden', value=csrfToken)
+ form(method='POST' action='/logout')
+ input(name='_csrf' type='hidden' value=csrfToken)
button.btn-link.text-left.dropdown-menu-button #{translate('log_out')}
diff --git a/services/web/app/views/layout/navbar-website-redesign.pug b/services/web/app/views/layout/navbar-website-redesign.pug
index 8ea71861c0..0a8337c2f5 100644
--- a/services/web/app/views/layout/navbar-website-redesign.pug
+++ b/services/web/app/views/layout/navbar-website-redesign.pug
@@ -1,30 +1,39 @@
nav.navbar.navbar-default.navbar-main.website-redesign-navbar
.container-fluid
.navbar-header
- if (typeof(suppressNavbarRight) == "undefined")
+ if typeof suppressNavbarRight == 'undefined'
button.navbar-toggle.collapsed(
- type="button",
- data-toggle="collapse",
- data-target="#navbar-main-collapse"
- aria-label="Toggle " + translate('navigation')
+ type='button'
+ data-toggle='collapse'
+ data-target='#navbar-main-collapse'
+ aria-label='Toggle ' + translate('navigation')
)
- i.fa.fa-bars(aria-hidden="true")
+ i.fa.fa-bars(aria-hidden='true')
- var enableUpgradeButton = projectDashboardReact && usersBestSubscription && (usersBestSubscription.type === 'free' || usersBestSubscription.type === 'standalone-ai-add-on')
- if (enableUpgradeButton)
+ if enableUpgradeButton
a.btn.btn-primary.pull-right.me-2.visible-xs(
- href="/user/subscription/plans"
- event-tracking="upgrade-button-click"
- event-tracking-mb="true"
- event-tracking-label="upgrade"
- event-tracking-trigger="click"
- event-segmentation='{"source": "dashboard-top", "project-dashboard-react": "enabled", "is-dashboard-sidebar-hidden": "true", "is-screen-width-less-than-768px": "true"}'
+ href='/user/subscription/plans'
+ event-tracking='upgrade-button-click'
+ event-tracking-mb='true'
+ event-tracking-label='upgrade'
+ event-tracking-trigger='click'
+ event-segmentation={
+ source: 'dashboard-top',
+ projectDashboardReact: 'enabled',
+ isDashboardSidebarHidden: 'true',
+ isScreenWidthLessThan768px: 'true',
+ }
) #{translate("upgrade")}
if settings.nav.custom_logo
- a(href='/', aria-label=settings.appName, style='background-image:url("'+settings.nav.custom_logo+'")').navbar-brand
- else if (nav.title)
- a(href='/', aria-label=settings.appName).navbar-title #{nav.title}
+ a.navbar-brand(
+ href='/'
+ aria-label=settings.appName
+ style='background-image:url("' + settings.nav.custom_logo + '")'
+ )
+ else if nav.title
+ a.navbar-title(href='/' aria-label=settings.appName) #{nav.title}
else
- a(href='/', aria-label=settings.appName).navbar-brand
+ a.navbar-brand(href='/' aria-label=settings.appName)
- var canDisplayAdminMenu = hasAdminAccess()
- var canDisplayAdminRedirect = canRedirectToAdminDomain()
@@ -32,44 +41,44 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar
- var canDisplaySurveyMenu = hasFeature('saas') && canDisplayAdminMenu
- var canDisplayScriptLogMenu = hasFeature('saas') && canDisplayAdminMenu
- if (typeof(suppressNavbarRight) == "undefined")
- .navbar-collapse.collapse#navbar-main-collapse
+ if typeof suppressNavbarRight == 'undefined'
+ #navbar-main-collapse.navbar-collapse.collapse
ul.nav.navbar-nav.navbar-right
- if (canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu)
+ if canDisplayAdminMenu || canDisplayAdminRedirect || canDisplaySplitTestMenu
li.dropdown.subdued
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "admin", "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'admin', location: 'top-menu'}
)
| Admin
span.caret
ul.dropdown-menu
if canDisplayAdminMenu
li
- a(href="/admin") Manage Site
+ a(href='/admin') Manage Site
li
- a(href="/admin/user") Manage Users
+ a(href='/admin/user') Manage Users
li
- a(href="/admin/project") Project URL Lookup
+ a(href='/admin/project') Project URL Lookup
if canDisplayAdminRedirect
li
a(href=settings.adminUrl) Switch to Admin
if canDisplaySplitTestMenu
li
- a(href="/admin/split-test") Manage Feature Flags
+ a(href='/admin/split-test') Manage Feature Flags
if canDisplaySurveyMenu
li
- a(href="/admin/survey") Manage Surveys
+ a(href='/admin/survey') Manage Surveys
if canDisplayScriptLogMenu
li
- a(href="/admin/script-logs") View Script Logs
+ a(href='/admin/script-logs') View Script Logs
// loop over header_extras
each item in nav.header_extras
@@ -88,15 +97,15 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar
if item.dropdown
li.dropdown(class=item.class)
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": item.trackingKey, "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
)
| !{translate(item.text)}
span.caret
@@ -106,18 +115,25 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar
li.divider
else if child.isContactUs
li
- a(data-ol-open-contact-form-modal="contact-us" href event-tracking="menu-click" event-tracking-mb="true" event-tracking-trigger="click" event-segmentation={"item": "contact", "location": "top-menu"})
+ a(
+ data-ol-open-contact-form-modal='contact-us'
+ href
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'contact', location: 'top-menu'}
+ )
span
| #{translate("contact_us")}
else
li
if child.url
a(
- href=child.url,
- class=child.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
+ href=child.url
+ class=child.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
event-segmentation={item: child.trackingKey, location: 'top-menu'}
) !{translate(child.text)}
else
@@ -126,12 +142,12 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar
li(class=item.class)
if item.url
a(
- href=item.url,
- class=item.class,
- event-tracking="menu-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ item: item.trackingKey, location: 'top-menu' }
+ href=item.url
+ class=item.class
+ event-tracking='menu-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: item.trackingKey, location: 'top-menu'}
) !{translate(item.text)}
else
| !{translate(item.text)}
@@ -142,54 +158,54 @@ nav.navbar.navbar-default.navbar-main.website-redesign-navbar
if hasFeature('registration-page')
li.primary
a(
- href="/register"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'register', location: 'top-menu' }
+ href='/register'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'register', location: 'top-menu'}
) #{translate('sign_up')}
// login link
li.secondary
a(
- href="/login"
- event-tracking="menu-click"
- event-tracking-action="clicked"
- event-tracking-trigger="click"
- event-tracking-mb="true"
- event-segmentation={ page: currentUrl, item: 'login', location: 'top-menu' }
+ href='/login'
+ event-tracking='menu-click'
+ event-tracking-action='clicked'
+ event-tracking-trigger='click'
+ event-tracking-mb='true'
+ event-segmentation={page: currentUrl, item: 'login', location: 'top-menu'}
) #{translate('log_in')}
// projects link and account menu
if getSessionUser()
li.secondary
- a(href="/project") #{translate('Projects')}
+ a(href='/project') #{translate('Projects')}
li.secondary.dropdown
a.dropdown-toggle(
- href="#",
- role="button",
- aria-haspopup="true",
- aria-expanded="false",
- data-toggle="dropdown"
- event-tracking="menu-expand"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={"item": "account", "location": "top-menu"}
+ href='#'
+ role='button'
+ aria-haspopup='true'
+ aria-expanded='false'
+ data-toggle='dropdown'
+ event-tracking='menu-expand'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={item: 'account', location: 'top-menu'}
)
| #{translate('Account')}
span.caret
ul.dropdown-menu
li
- div.subdued #{getSessionUser().email}
+ .subdued #{getSessionUser().email}
li.divider.hidden-xs.hidden-sm
li
- a(href="/user/settings") #{translate('account_settings')}
+ a(href='/user/settings') #{translate('account_settings')}
if nav.showSubscriptionLink
li
- a(href="/user/subscription") #{translate('subscription')}
+ a(href='/user/subscription') #{translate('subscription')}
li.divider.hidden-xs.hidden-sm
li
- form(method="POST" action="/logout")
- input(name='_csrf', type='hidden', value=csrfToken)
+ form(method='POST' action='/logout')
+ input(name='_csrf' type='hidden' value=csrfToken)
button.btn-link.text-left.dropdown-menu-button #{translate('log_out')}
diff --git a/services/web/app/views/layout/thin-footer-bootstrap-5.pug b/services/web/app/views/layout/thin-footer-bootstrap-5.pug
index 1f06a054fc..4c29933ab1 100644
--- a/services/web/app/views/layout/thin-footer-bootstrap-5.pug
+++ b/services/web/app/views/layout/thin-footer-bootstrap-5.pug
@@ -25,7 +25,7 @@ footer.site-footer
each item in nav.left_footer
li
if item.url
- a(href=item.url, class=item.class) !{translate(item.text)}
+ a(href=item.url class=item.class) !{translate(item.text)}
else
| !{item.text}
@@ -33,6 +33,6 @@ footer.site-footer
each item in nav.right_footer
li
if item.url
- a(href=item.url, class=item.class, aria-label=item.label) !{item.text}
+ a(href=item.url class=item.class aria-label=item.label) !{item.text}
else
| !{item.text}
diff --git a/services/web/app/views/layout/thin-footer.pug b/services/web/app/views/layout/thin-footer.pug
index 6eeecf628a..879e337983 100644
--- a/services/web/app/views/layout/thin-footer.pug
+++ b/services/web/app/views/layout/thin-footer.pug
@@ -27,7 +27,7 @@ footer.site-footer
each item in nav.left_footer
li
if item.url
- a(href=item.url, class=item.class) !{translate(item.text)}
+ a(href=item.url class=item.class) !{translate(item.text)}
else
| !{item.text}
@@ -35,6 +35,6 @@ footer.site-footer
each item in nav.right_footer
li
if item.url
- a(href=item.url, class=item.class, aria-label=item.label) !{item.text}
+ a(href=item.url class=item.class aria-label=item.label) !{item.text}
else
| !{item.text}
diff --git a/services/web/app/views/project/editor/new_from_template.pug b/services/web/app/views/project/editor/new_from_template.pug
index b1b5ae1e25..c84288a21a 100644
--- a/services/web/app/views/project/editor/new_from_template.pug
+++ b/services/web/app/views/project/editor/new_from_template.pug
@@ -1,36 +1,36 @@
extends ../../layout-marketing
block vars
- - var suppressFooter = true
- - var suppressCookieBanner = true
- - var suppressSkipToContent = true
+ - var suppressFooter = true
+ - var suppressCookieBanner = true
+ - var suppressSkipToContent = true
block content
- .editor.full-size
- .loading-screen()
- .loading-screen-brand-container
- .loading-screen-brand(
- style="height: 20%;"
- )
+ .editor.full-size
+ .loading-screen()
+ .loading-screen-brand-container
+ .loading-screen-brand(
+ style="height: 20%;"
+ )
- h3.loading-screen-label() #{translate("Opening template")}
- span.loading-screen-ellip .
- span.loading-screen-ellip .
- span.loading-screen-ellip .
+ h3.loading-screen-label() #{translate("Opening template")}
+ span.loading-screen-ellip .
+ span.loading-screen-ellip .
+ span.loading-screen-ellip .
- form(
- data-ol-regular-form
- data-ol-auto-submit
- method='POST'
- action='/project/new/template/'
- )
- input(type="hidden", name="_csrf", value=csrfToken)
- input(type="hidden" name="templateId" value=templateId)
- input(type="hidden" name="templateVersionId" value=templateVersionId)
- input(type="hidden" name="templateName" value=name)
- input(type="hidden" name="compiler" value=compiler)
- input(type="hidden" name="imageName" value=imageName)
- input(type="hidden" name="mainFile" value=mainFile)
- if brandVariationId
- input(type="hidden" name="brandVariationId" value=brandVariationId)
- input(hidden type="submit")
+ form(
+ data-ol-regular-form
+ data-ol-auto-submit
+ method='POST'
+ action='/project/new/template/'
+ )
+ input(type="hidden", name="_csrf", value=csrfToken)
+ input(type="hidden" name="templateId" value=templateId)
+ input(type="hidden" name="templateVersionId" value=templateVersionId)
+ input(type="hidden" name="templateName" value=name)
+ input(type="hidden" name="compiler" value=compiler)
+ input(type="hidden" name="imageName" value=imageName)
+ input(type="hidden" name="mainFile" value=mainFile)
+ if brandVariationId
+ input(type="hidden" name="brandVariationId" value=brandVariationId)
+ input(hidden type="submit")
diff --git a/services/web/app/views/project/ide-react-detached.pug b/services/web/app/views/project/ide-react-detached.pug
index 8109da7f74..ca1a178bbf 100644
--- a/services/web/app/views/project/ide-react-detached.pug
+++ b/services/web/app/views/project/ide-react-detached.pug
@@ -11,7 +11,7 @@ block vars
- metadata.robotsNoindexNofollow = true
block content
- #pdf-preview-detached-root()
+ #pdf-preview-detached-root
block append meta
include editor/_meta
diff --git a/services/web/app/views/project/ide-react.pug b/services/web/app/views/project/ide-react.pug
index bc30f69202..8af9de8296 100644
--- a/services/web/app/views/project/ide-react.pug
+++ b/services/web/app/views/project/ide-react.pug
@@ -15,7 +15,7 @@ block content
main#ide-root
.loading-screen
.loading-screen-brand-container
- .loading-screen-brand(style="height: 20%;")
+ .loading-screen-brand(style='height: 20%')
h3.loading-screen-label #{translate("loading")}
span.loading-screen-ellip .
span.loading-screen-ellip .
@@ -25,4 +25,9 @@ block append meta
include editor/_meta
block prepend foot-scripts
- script(type="text/javascript", nonce=scriptNonce, src=(wsUrl || '/socket.io') + '/socket.io.js', defer=deferScripts)
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src=(wsUrl || '/socket.io') + '/socket.io.js'
+ defer=deferScripts
+ )
diff --git a/services/web/app/views/project/invite/not-valid.pug b/services/web/app/views/project/invite/not-valid.pug
index b4cbc1be1b..3722ab7919 100644
--- a/services/web/app/views/project/invite/not-valid.pug
+++ b/services/web/app/views/project/invite/not-valid.pug
@@ -1,18 +1,18 @@
extends ../../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-md-8.col-md-offset-2.offset-md-2
.card.project-invite-invalid
.card-body
.page-header.text-center
- h1 #{translate("invite_not_valid")}
+ h1 #{translate("invite_not_valid")}
.row.text-center
.col-12.col-md-12
p
| #{translate("invite_not_valid_description")}.
.row.text-center.actions
.col-12.col-md-12
- a.btn.btn-secondary-info.btn-secondary(href="/project") #{translate("back_to_your_projects")}
+ a.btn.btn-secondary-info.btn-secondary(href='/project') #{translate("back_to_your_projects")}
diff --git a/services/web/app/views/project/invite/show.pug b/services/web/app/views/project/invite/show.pug
index a18518c716..503ec78796 100644
--- a/services/web/app/views/project/invite/show.pug
+++ b/services/web/app/views/project/invite/show.pug
@@ -1,7 +1,7 @@
extends ../../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-12.col-md-8.col-md-offset-2.offset-md-2
@@ -20,16 +20,16 @@ block content
.col-12.col-md-12
form.form(
data-ol-regular-form
- method="POST",
- action="/project/"+invite.projectId+"/invite/token/"+token+"/accept"
+ method='POST'
+ action='/project/' + invite.projectId + '/invite/token/' + token + '/accept'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- input(name='token', type='hidden', value=token)
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='token' type='hidden' value=token)
.form-group.text-center
button.btn.btn-lg.btn-primary(
- type="submit"
+ type='submit'
data-ol-disabled-inflight
)
- span(data-ol-inflight="idle") #{translate("join_project")}
- span(hidden data-ol-inflight="pending") #{translate("joining")}…
+ span(data-ol-inflight='idle') #{translate("join_project")}
+ span(hidden data-ol-inflight='pending') #{translate("joining")}…
.form-group.text-center
diff --git a/services/web/app/views/project/list-react.pug b/services/web/app/views/project/list-react.pug
index 60e7d0c0fc..fa7bc24c09 100644
--- a/services/web/app/views/project/list-react.pug
+++ b/services/web/app/views/project/list-react.pug
@@ -9,35 +9,83 @@ block vars
- const suppressFooter = true
block append meta
- meta(name="ol-usersBestSubscription" data-type="json" content=usersBestSubscription)
- meta(name="ol-notifications" data-type="json" content=notifications)
- meta(name="ol-notificationsInstitution" data-type="json" content=notificationsInstitution)
- meta(name="ol-userEmails" data-type="json" content=userEmails)
- meta(name="ol-allInReconfirmNotificationPeriods" data-type="json" content=allInReconfirmNotificationPeriods)
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-userAffiliations" data-type="json" content=userAffiliations)
- meta(name="ol-reconfirmedViaSAML" content=reconfirmedViaSAML)
- meta(name="ol-survey" data-type="json" content=survey)
- meta(name="ol-tags" data-type="json" content=tags)
- meta(name="ol-portalTemplates" data-type="json" content=portalTemplates)
- meta(name="ol-prefetchedProjectsBlob" data-type="json" content=prefetchedProjectsBlob)
- if (suggestedLanguageSubdomainConfig)
- meta(name="ol-suggestedLanguage" data-type="json" content=Object.assign(suggestedLanguageSubdomainConfig, {
- lngName: translate(suggestedLanguageSubdomainConfig.lngCode),
- imgUrl: buildImgPath("flags/24/" + suggestedLanguageSubdomainConfig.lngCode + ".png")
- }))
- meta(name="ol-currentUrl" data-type="string" content=currentUrl)
- meta(name="ol-showGroupsAndEnterpriseBanner" data-type="boolean" content=showGroupsAndEnterpriseBanner)
- meta(name="ol-groupsAndEnterpriseBannerVariant" data-type="string" content=groupsAndEnterpriseBannerVariant)
- meta(name="ol-showInrGeoBanner" data-type="boolean" content=showInrGeoBanner)
- meta(name="ol-showBrlGeoBanner" data-type="boolean" content=showBrlGeoBanner)
- meta(name="ol-recommendedCurrency" data-type="string" content=recommendedCurrency)
- meta(name="ol-showLATAMBanner" data-type="boolean" content=showLATAMBanner)
- meta(name="ol-groupSubscriptionsPendingEnrollment" data-type="json" content=groupSubscriptionsPendingEnrollment)
- meta(name="ol-hasIndividualPaidSubscription" data-type="boolean" content=hasIndividualPaidSubscription)
- meta(name="ol-groupSsoSetupSuccess" data-type="boolean" content=groupSsoSetupSuccess)
- meta(name="ol-showUSGovBanner" data-type="boolean" content=showUSGovBanner)
- meta(name="ol-usGovBannerVariant" data-type="string" content=usGovBannerVariant)
+ meta(
+ name='ol-usersBestSubscription'
+ data-type='json'
+ content=usersBestSubscription
+ )
+ meta(name='ol-notifications' data-type='json' content=notifications)
+ meta(
+ name='ol-notificationsInstitution'
+ data-type='json'
+ content=notificationsInstitution
+ )
+ meta(name='ol-userEmails' data-type='json' content=userEmails)
+ meta(
+ name='ol-allInReconfirmNotificationPeriods'
+ data-type='json'
+ content=allInReconfirmNotificationPeriods
+ )
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-userAffiliations' data-type='json' content=userAffiliations)
+ meta(name='ol-reconfirmedViaSAML' content=reconfirmedViaSAML)
+ meta(name='ol-survey' data-type='json' content=survey)
+ meta(name='ol-tags' data-type='json' content=tags)
+ meta(name='ol-portalTemplates' data-type='json' content=portalTemplates)
+ meta(
+ name='ol-prefetchedProjectsBlob'
+ data-type='json'
+ content=prefetchedProjectsBlob
+ )
+ if suggestedLanguageSubdomainConfig
+ meta(
+ name='ol-suggestedLanguage'
+ data-type='json'
+ content=Object.assign(suggestedLanguageSubdomainConfig, {
+ lngName: translate(suggestedLanguageSubdomainConfig.lngCode),
+ imgUrl: buildImgPath('flags/24/' + suggestedLanguageSubdomainConfig.lngCode + '.png'),
+ })
+ )
+ meta(name='ol-currentUrl' data-type='string' content=currentUrl)
+ meta(
+ name='ol-showGroupsAndEnterpriseBanner'
+ data-type='boolean'
+ content=showGroupsAndEnterpriseBanner
+ )
+ meta(
+ name='ol-groupsAndEnterpriseBannerVariant'
+ data-type='string'
+ content=groupsAndEnterpriseBannerVariant
+ )
+ meta(name='ol-showInrGeoBanner' data-type='boolean' content=showInrGeoBanner)
+ meta(name='ol-showBrlGeoBanner' data-type='boolean' content=showBrlGeoBanner)
+ meta(
+ name='ol-recommendedCurrency'
+ data-type='string'
+ content=recommendedCurrency
+ )
+ meta(name='ol-showLATAMBanner' data-type='boolean' content=showLATAMBanner)
+ meta(
+ name='ol-groupSubscriptionsPendingEnrollment'
+ data-type='json'
+ content=groupSubscriptionsPendingEnrollment
+ )
+ meta(
+ name='ol-hasIndividualPaidSubscription'
+ data-type='boolean'
+ content=hasIndividualPaidSubscription
+ )
+ meta(
+ name='ol-groupSsoSetupSuccess'
+ data-type='boolean'
+ content=groupSsoSetupSuccess
+ )
+ meta(name='ol-showUSGovBanner' data-type='boolean' content=showUSGovBanner)
+ meta(
+ name='ol-usGovBannerVariant'
+ data-type='string'
+ content=usGovBannerVariant
+ )
block content
#project-list-root
diff --git a/services/web/app/views/project/token/access-react.pug b/services/web/app/views/project/token/access-react.pug
index eabfd18eb6..80b91f1a99 100644
--- a/services/web/app/views/project/token/access-react.pug
+++ b/services/web/app/views/project/token/access-react.pug
@@ -7,11 +7,11 @@ block vars
- var suppressFooter = true
- var suppressCookieBanner = true
- var suppressSkipToContent = true
-
+
block append meta
- meta(name="ol-postUrl" data-type="string" content=postUrl)
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-postUrl' data-type='string' content=postUrl)
+ meta(name='ol-user' data-type='json' content=user)
block content
- .content.content-alt#main-content
- div#token-access-page
+ #main-content.content.content-alt
+ #token-access-page
diff --git a/services/web/app/views/project/token/sharing-updates.pug b/services/web/app/views/project/token/sharing-updates.pug
index 66d8ac9077..d1818be0af 100644
--- a/services/web/app/views/project/token/sharing-updates.pug
+++ b/services/web/app/views/project/token/sharing-updates.pug
@@ -9,9 +9,9 @@ block vars
- var suppressSkipToContent = true
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-project_id" data-type="string" content=projectId)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-project_id' data-type='string' content=projectId)
block content
- .content.content-alt#main-content
- div#sharing-updates-page
+ #main-content.content.content-alt
+ #sharing-updates-page
diff --git a/services/web/app/views/subscriptions/add-seats.pug b/services/web/app/views/subscriptions/add-seats.pug
index bcbf5be666..6fa644ee46 100644
--- a/services/web/app/views/subscriptions/add-seats.pug
+++ b/services/web/app/views/subscriptions/add-seats.pug
@@ -4,13 +4,17 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/add-seats'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-groupName", data-type="string", content=groupName)
- meta(name="ol-subscriptionId", data-type="string", content=subscriptionId)
- meta(name="ol-totalLicenses", data-type="number", content=totalLicenses)
- meta(name="ol-isProfessional", data-type="boolean", content=isProfessional)
- meta(name="ol-isCollectionMethodManual", data-type="boolean", content=isCollectionMethodManual)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-groupName' data-type='string' content=groupName)
+ meta(name='ol-subscriptionId' data-type='string' content=subscriptionId)
+ meta(name='ol-totalLicenses' data-type='number' content=totalLicenses)
+ meta(name='ol-isProfessional' data-type='boolean' content=isProfessional)
+ meta(
+ name='ol-isCollectionMethodManual'
+ data-type='boolean'
+ content=isCollectionMethodManual
+ )
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
#add-seats-root
diff --git a/services/web/app/views/subscriptions/canceled-subscription-react.pug b/services/web/app/views/subscriptions/canceled-subscription-react.pug
index 3a89234fd9..a33732e1f6 100644
--- a/services/web/app/views/subscriptions/canceled-subscription-react.pug
+++ b/services/web/app/views/subscriptions/canceled-subscription-react.pug
@@ -4,7 +4,7 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/canceled-subscription'
block append meta
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-user' data-type='json' content=user)
block content
- main.content.content-alt#subscription-canceled-root
+ main#subscription-canceled-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/dashboard-react.pug b/services/web/app/views/subscriptions/dashboard-react.pug
index 2b6251f2a3..b253097d25 100644
--- a/services/web/app/views/subscriptions/dashboard-react.pug
+++ b/services/web/app/views/subscriptions/dashboard-react.pug
@@ -1,36 +1,91 @@
extends ../layout-react
block entrypointVar
- - entrypoint = 'pages/user/subscription/dashboard'
+ - entrypoint = 'pages/user/subscription/dashboard'
block head-scripts
- script(type="text/javascript", nonce=scriptNonce, src="https://js.recurly.com/v4/recurly.js")
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://js.recurly.com/v4/recurly.js'
+ )
block append meta
- meta(name="ol-subscription" data-type="json" content=personalSubscription)
- meta(name="ol-userCanExtendTrial" data-type="boolean" content=userCanExtendTrial)
- meta(name="ol-managedGroupSubscriptions" data-type="json" content=managedGroupSubscriptions)
- meta(name="ol-memberGroupSubscriptions" data-type="json" content=memberGroupSubscriptions)
- meta(name="ol-managedInstitutions" data-type="json" content=managedInstitutions)
- meta(name="ol-managedPublishers" data-type="json" content=managedPublishers)
- meta(name="ol-planCodesChangingAtTermEnd" data-type="json", content=planCodesChangingAtTermEnd)
- meta(name="ol-currentInstitutionsWithLicence" data-type="json" content=currentInstitutionsWithLicence)
- meta(name="ol-hasSubscription" data-type="boolean" content=hasSubscription)
- meta(name="ol-fromPlansPage" data-type="boolean" content=fromPlansPage)
- meta(name="ol-plans" data-type="json" content=plans)
- meta(name="ol-groupSettingsAdvertisedFor" data-type="json" content=groupSettingsAdvertisedFor)
- meta(name="ol-canUseFlexibleLicensing" data-type="boolean", content=canUseFlexibleLicensing)
- meta(name="ol-showGroupDiscount" data-type="boolean", content=showGroupDiscount)
- meta(name="ol-groupSettingsEnabledFor" data-type="json" content=groupSettingsEnabledFor)
- meta(name="ol-hasAiAssistViaWritefull" data-type="boolean", content=hasAiAssistViaWritefull)
- meta(name="ol-aiAssistViaWritefullSource" data-type="string", content=aiAssistViaWritefullSource)
- meta(name="ol-user" data-type="json" content=user)
- if (personalSubscription && personalSubscription.payment)
- meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
- meta(name="ol-stripeUKApiKey" content=settings.apis.stripeUK.publishableKey)
- meta(name="ol-recommendedCurrency" content=personalSubscription.payment.currency)
- meta(name="ol-groupPlans" data-type="json" content=groupPlans)
+ meta(name='ol-subscription' data-type='json' content=personalSubscription)
+ meta(
+ name='ol-userCanExtendTrial'
+ data-type='boolean'
+ content=userCanExtendTrial
+ )
+ meta(
+ name='ol-managedGroupSubscriptions'
+ data-type='json'
+ content=managedGroupSubscriptions
+ )
+ meta(
+ name='ol-memberGroupSubscriptions'
+ data-type='json'
+ content=memberGroupSubscriptions
+ )
+ meta(
+ name='ol-managedInstitutions'
+ data-type='json'
+ content=managedInstitutions
+ )
+ meta(name='ol-managedPublishers' data-type='json' content=managedPublishers)
+ meta(
+ name='ol-planCodesChangingAtTermEnd'
+ data-type='json'
+ content=planCodesChangingAtTermEnd
+ )
+ meta(
+ name='ol-currentInstitutionsWithLicence'
+ data-type='json'
+ content=currentInstitutionsWithLicence
+ )
+ meta(name='ol-hasSubscription' data-type='boolean' content=hasSubscription)
+ meta(name='ol-fromPlansPage' data-type='boolean' content=fromPlansPage)
+ meta(name='ol-plans' data-type='json' content=plans)
+ meta(
+ name='ol-groupSettingsAdvertisedFor'
+ data-type='json'
+ content=groupSettingsAdvertisedFor
+ )
+ meta(
+ name='ol-canUseFlexibleLicensing'
+ data-type='boolean'
+ content=canUseFlexibleLicensing
+ )
+ meta(
+ name='ol-showGroupDiscount'
+ data-type='boolean'
+ content=showGroupDiscount
+ )
+ meta(
+ name='ol-groupSettingsEnabledFor'
+ data-type='json'
+ content=groupSettingsEnabledFor
+ )
+ meta(
+ name='ol-hasAiAssistViaWritefull'
+ data-type='boolean'
+ content=hasAiAssistViaWritefull
+ )
+ meta(
+ name='ol-aiAssistViaWritefullSource'
+ data-type='string'
+ content=aiAssistViaWritefullSource
+ )
+ meta(name='ol-user' data-type='json' content=user)
+ if personalSubscription && personalSubscription.payment
+ meta(name='ol-recurlyApiKey' content=settings.apis.recurly.publicKey)
+ meta(name='ol-stripeUKApiKey' content=settings.apis.stripeUK.publishableKey)
+ meta(
+ name='ol-recommendedCurrency'
+ content=personalSubscription.payment.currency
+ )
+ meta(name='ol-groupPlans' data-type='json' content=groupPlans)
block content
- main.content.content-alt#main-content
- #subscription-dashboard-root
+ main#main-content.content.content-alt
+ #subscription-dashboard-root
diff --git a/services/web/app/views/subscriptions/manually-collected-subscription.pug b/services/web/app/views/subscriptions/manually-collected-subscription.pug
index ba6bf73473..a693ac749f 100644
--- a/services/web/app/views/subscriptions/manually-collected-subscription.pug
+++ b/services/web/app/views/subscriptions/manually-collected-subscription.pug
@@ -4,8 +4,8 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/manually-collected-subscription'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-groupName", data-type="string", content=groupName)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-groupName' data-type='string' content=groupName)
block content
- main.content.content-alt#manually-collected-subscription-root
+ main#manually-collected-subscription-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/missing-billing-information.pug b/services/web/app/views/subscriptions/missing-billing-information.pug
index 416bac65f5..d0a0e05ae8 100644
--- a/services/web/app/views/subscriptions/missing-billing-information.pug
+++ b/services/web/app/views/subscriptions/missing-billing-information.pug
@@ -4,8 +4,8 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/missing-billing-information'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-groupName", data-type="string", content=groupName)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-groupName' data-type='string' content=groupName)
block content
- main.content.content-alt#missing-billing-information-root
+ main#missing-billing-information-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/plans/_faq_new.pug b/services/web/app/views/subscriptions/plans/_faq_new.pug
index 3c926fb22d..760f27b1a4 100644
--- a/services/web/app/views/subscriptions/plans/_faq_new.pug
+++ b/services/web/app/views/subscriptions/plans/_faq_new.pug
@@ -9,7 +9,7 @@ include ../../_mixins/material_symbol
.row.row-spaced-extra-large
.col-md-12.faq-heading-container
h2
- +eyebrow(translate("frequently_asked_questions"))
+ +eyebrow(translate('frequently_asked_questions'))
| #{translate("your_questions_answered")}
.row
@@ -18,74 +18,62 @@ include ../../_mixins/material_symbol
class={
'plans-faq-tabs': bootstrapVersion === 5,
'ol-tabs': bootstrapVersion === 5,
- 'ol-tabs-scrollable': bootstrapVersion === 3
+ 'ol-tabs-scrollable': bootstrapVersion === 3,
}
)
.nav-tabs-container
- ul.nav.nav-tabs(role="tablist")
+ ul.nav.nav-tabs(role='tablist')
//- In the bs5 version of plans page, the `active` class need to be added to the `a` tag instead of the parent `li` tag
//- If the `plans-page-bs5` split test has been completed, remove the `active` class from the `li` tag since we're not using it anymore
//- If the `plans-page-bs5` split test has been completed, remove the `data-toggle` because it is not needed anymore (bs5 uses `data-bs-toggle`)
- li(
- role="presentation"
- class={
- active: bootstrapVersion === 3
- }
- )
+ li(role='presentation' class={
+ active: bootstrapVersion === 3,
+ })
a(
- role="tab"
- data-toggle="tab"
- data-bs-toggle="tab"
+ role='tab'
+ data-toggle='tab'
+ data-bs-toggle='tab'
href='#' + managingYourSubscription
aria-controls=managingYourSubscription
class={
- active: bootstrapVersion === 5
+ active: bootstrapVersion === 5,
}
)
| #{translate('managing_your_subscription')}
- li(role="presentation")
+ li(role='presentation')
a(
- role="tab"
- data-toggle="tab"
- data-bs-toggle="tab"
+ role='tab'
+ data-toggle='tab'
+ data-bs-toggle='tab'
href='#' + overleafIndividualPlans
aria-controls=overleafIndividualPlans
)
| #{translate('overleaf_individual_plans')}
- li(role="presentation")
+ li(role='presentation')
a(
- role="tab"
- data-toggle="tab"
- data-bs-toggle="tab"
+ role='tab'
+ data-toggle='tab'
+ data-bs-toggle='tab'
href='#' + overleafGroupPlans
aria-controls=overleafGroupPlans
)
| #{translate('overleaf_group_plans')}
.tab-content
- .tab-pane.active(
- role="tabpanel"
- id=managingYourSubscription
- )
- +managingYourSubscription()
- .tab-pane(
- role="tabpanel"
- id=overleafIndividualPlans
- )
- +overleafIndividualPlans()
- .tab-pane(
- role="tabpanel"
- id=overleafGroupPlans
- )
- +overleafGroupPlans()
+ .tab-pane.active(role='tabpanel' id=managingYourSubscription)
+ +managingYourSubscription
+ .tab-pane(role='tabpanel' id=overleafIndividualPlans)
+ +overleafIndividualPlans
+ .tab-pane(role='tabpanel' id=overleafGroupPlans)
+ +overleafGroupPlans
.row
.col-xs-12.plans-faq-support
span #{translate('still_have_questions')}
button(
- data-ol-open-contact-form-modal="general"
- data-bs-toggle=bootstrapVersion === 5 ? "modal" : undefined
- data-bs-target=bootstrapVersion === 5 ? "#contactUsModal" : undefined
+ data-ol-open-contact-form-modal='general'
+ data-bs-toggle=bootstrapVersion === 5 ? 'modal' : undefined
+ data-bs-target=bootstrapVersion === 5 ? '#contactUsModal' : undefined
)
- span(style="margin-right: 4px") #{translate('contact_support')}
- +material-symbol-rounded("arrow_right_alt", "icon-md")
+ span(style='margin-right: 4px') #{translate('contact_support')}
+ +material-symbol-rounded('arrow_right_alt', 'icon-md')
diff --git a/services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug b/services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug
index a598f4774c..59eac8efac 100644
--- a/services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug
+++ b/services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug
@@ -1,357 +1,353 @@
//- If the `plans-page-bs5` split test has been completed, remove the `data-toggle` and `data-target` because it is not needed anymore (bs5 uses `data-bs-toggle` and `data-bs-target`)
include ../../_mixins/material_symbol
-
-mixin managingYourSubscription()
+
+mixin managingYourSubscription
.ol-accordions-container
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#managingYourSubscriptionQ1"
- data-bs-toggle="collapse"
- data-bs-target="#managingYourSubscriptionQ1"
- aria-expanded="false"
- aria-controls="managingYourSubscriptionQ1"
+ type='button'
+ data-toggle='collapse'
+ data-target='#managingYourSubscriptionQ1'
+ data-bs-toggle='collapse'
+ data-bs-target='#managingYourSubscriptionQ1'
+ aria-expanded='false'
+ aria-controls='managingYourSubscriptionQ1'
)
| Can I change plans or cancel later?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="managingYourSubscriptionQ1")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='managingYourSubscriptionQ1')
.custom-accordion-body
- span Yes, you can do this at any time by going to
- strong Account > Subscription
+ span Yes, you can do this at any time by going to
+ strong Account > Subscription
span when logged in to Overleaf. You can change plans, switch between monthly and annual billing options, or cancel to downgrade to the free plan. When canceling, your subscription will continue until the end of the billing period.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#managingYourSubscriptionQ2"
- data-bs-toggle="collapse"
- data-bs-target="#managingYourSubscriptionQ2"
- aria-expanded="false"
- aria-controls="managingYourSubscriptionQ2"
+ type='button'
+ data-toggle='collapse'
+ data-target='#managingYourSubscriptionQ2'
+ data-bs-toggle='collapse'
+ data-bs-target='#managingYourSubscriptionQ2'
+ aria-expanded='false'
+ aria-controls='managingYourSubscriptionQ2'
)
| If I change or cancel my Overleaf plan, will I lose my projects?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="managingYourSubscriptionQ2")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='managingYourSubscriptionQ2')
.custom-accordion-body
| No. Changing or canceling your plan won’t affect your projects, the only change will be to the features available to you. You can see which features are available only on paid plans in the comparison table.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#managingYourSubscriptionQ3"
- data-bs-toggle="collapse"
- data-bs-target="#managingYourSubscriptionQ3"
- aria-expanded="false"
- aria-controls="managingYourSubscriptionQ3"
+ type='button'
+ data-toggle='collapse'
+ data-target='#managingYourSubscriptionQ3'
+ data-bs-toggle='collapse'
+ data-bs-target='#managingYourSubscriptionQ3'
+ aria-expanded='false'
+ aria-controls='managingYourSubscriptionQ3'
)
| Can I pay by invoice or purchase order?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="managingYourSubscriptionQ3")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='managingYourSubscriptionQ3')
.custom-accordion-body
| This is possible when you’re purchasing a group subscription for five or more people, or a site license. For individual subscriptions, we can only accept payment online via credit card, debit card, or PayPal.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#managingYourSubscriptionQ4"
- data-bs-toggle="collapse"
- data-bs-target="#managingYourSubscriptionQ4"
- aria-expanded="false"
- aria-controls="managingYourSubscriptionQ4"
+ type='button'
+ data-toggle='collapse'
+ data-target='#managingYourSubscriptionQ4'
+ data-bs-toggle='collapse'
+ data-bs-target='#managingYourSubscriptionQ4'
+ aria-expanded='false'
+ aria-controls='managingYourSubscriptionQ4'
)
| How do I view/update the credit card being charged for my subscription?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="managingYourSubscriptionQ4")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='managingYourSubscriptionQ4')
.custom-accordion-body
- | You can view and update the card on file by going to Account >
+ | You can view and update the card on file by going to Account >
a.inline-green-link(
- target="_blank"
- href="/user/subscription"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/user/subscription'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span Subscription
| .
-
-
-
-mixin overleafIndividualPlans()
+mixin overleafIndividualPlans
.ol-accordions-container
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ1"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ1"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ1"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ1'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ1'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ1'
)
| How does the free trial work?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ1")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ1')
.custom-accordion-body
- span You get full access to your chosen plan during your 7-day free trial, and there’s no obligation to continue beyond the trial. Your card will be charged at the end of your trial unless you cancel before then. To cancel, go to
- strong Account >
+ span You get full access to your chosen plan during your 7-day free trial, and there’s no obligation to continue beyond the trial. Your card will be charged at the end of your trial unless you cancel before then. To cancel, go to
+ strong Account >
+ |
a.inline-green-link(
- target="_blank"
- href="/user/subscription"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/user/subscription'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span Subscription
- span when logged in to Overleaf (the trial will continue for the full 7 days).
+ span when logged in to Overleaf (the trial will continue for the full 7 days).
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ2"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ2"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ2"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ2'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ2'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ2'
)
| What’s a collaborator on an Overleaf individual subscription?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ2")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ2')
.custom-accordion-body
- | A collaborator is someone you invite to work with you on a project. So, for example, on our Standard plan you can have up to 10 people collaborating with you on any given project.
+ | A collaborator is someone you invite to work with you on a project. So, for example, on our Standard plan you can have up to 10 people collaborating with you on any given project.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ3"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ3"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ3"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ3'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ3'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ3'
)
| The individual Standard plan has 10 project collaborators, does it mean that 10 people will be upgraded?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ3")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ3')
.custom-accordion-body
- span No. Only the subscriber’s account will be upgraded. An individual Standard subscription allows you to invite 10 people per project to edit the project with you. Your collaborators can access features such as the full document history and extended compile time, but
- strong only
+ span No. Only the subscriber’s account will be upgraded. An individual Standard subscription allows you to invite 10 people per project to edit the project with you. Your collaborators can access features such as the full document history and extended compile time, but
+ strong only
span for the project(s) they’re working on with you. If your collaborators want access to those features on their own projects, they will need to purchase their own subscription. (If you work with the same people regularly, you might find a group subscription more cost effective.)
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ4"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ4"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ4"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ4'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ4'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ4'
)
| Do collaborators also have access to the editing and collaboration features I’ve paid for?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ4")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ4')
.custom-accordion-body
- span If you have an Overleaf subscription, then your project collaborators will have access to features like real-time track changes and document history, but
- strong only
+ span If you have an Overleaf subscription, then your project collaborators will have access to features like real-time track changes and document history, but
+ strong only
span for the project(s) they’re working on with you. If your collaborators want access to those features on their own projects, they will need to purchase their own subscription. (If you work with the same people regularly, you might find a group subscription more cost effective.)
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ5"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ5"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ5"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ5'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ5'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ5'
)
| Can I purchase an individual plan on behalf of someone else?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ5")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ5')
.custom-accordion-body
- | Individual subscriptions must be purchased by the account that will be the end user. If you want to purchase a plan for someone else, you’ll need to provide them with relevant payment details to enable them to make the purchase.
+ | Individual subscriptions must be purchased by the account that will be the end user. If you want to purchase a plan for someone else, you’ll need to provide them with relevant payment details to enable them to make the purchase.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ6"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ6"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ6"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ6'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ6'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ6'
)
| Who is eligible for the Student plan?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ6")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ6')
.custom-accordion-body
| As the name suggests, the Student plan is only for students at educational institutions. This includes graduate students.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafIndividualPlansQ7"
- data-bs-toggle="collapse"
- data-bs-target="#overleafIndividualPlansQ7"
- aria-expanded="false"
- aria-controls="overleafIndividualPlansQ7"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafIndividualPlansQ7'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafIndividualPlansQ7'
+ aria-expanded='false'
+ aria-controls='overleafIndividualPlansQ7'
)
| Can I transfer an individual subscription to someone else?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafIndividualPlansQ7")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafIndividualPlansQ7')
.custom-accordion-body
- | No. Individual plans can’t be transferred.
+ | No. Individual plans can’t be transferred.
-
-
-
-
-mixin overleafGroupPlans()
+mixin overleafGroupPlans
.ol-accordions-container
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafGroupPlansQ1"
- data-bs-toggle="collapse"
- data-bs-target="#overleafGroupPlansQ1"
- aria-expanded="false"
- aria-controls="overleafGroupPlansQ1"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafGroupPlansQ1'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafGroupPlansQ1'
+ aria-expanded='false'
+ aria-controls='overleafGroupPlansQ1'
)
| What’s the difference between users and collaborators on an Overleaf group subscription?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafGroupPlansQ1")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafGroupPlansQ1')
.custom-accordion-body
- div On any of our group plans, the number of users refers to the number of people you can invite to join your group. All of these people will have access to the plan’s paid-for features across all their projects, such as real-time track changes and document history.
- div.mt-2 Collaborators are people that your group users may invite to work with them on their projects. So, for example, if you have the Group Standard plan, the users in your group can invite up to 10 people to work with them on a project. And if you have the Group Professional plan, your users can invite as many people to work with them as they want.
+ div On any of our group plans, the number of users refers to the number of people you can invite to join your group. All of these people will have access to the plan’s paid-for features across all their projects, such as real-time track changes and document history.
+ .mt-2 Collaborators are people that your group users may invite to work with them on their projects. So, for example, if you have the Group Standard plan, the users in your group can invite up to 10 people to work with them on a project. And if you have the Group Professional plan, your users can invite as many people to work with them as they want.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafGroupPlansQ2"
- data-bs-toggle="collapse"
- data-bs-target="#overleafGroupPlansQ2"
- aria-expanded="false"
- aria-controls="overleafGroupPlansQ2"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafGroupPlansQ2'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafGroupPlansQ2'
+ aria-expanded='false'
+ aria-controls='overleafGroupPlansQ2'
)
| What is the benefit of purchasing an Overleaf Group plan?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafGroupPlansQ2")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafGroupPlansQ2')
.custom-accordion-body
- | Our Group subscriptions allow you to purchase access to our premium features for multiple people. They’re easy to manage, help save on paperwork, and allow groups of 5 or more to purchase via purchase order (PO). We also offer discounts on purchases of Group subscriptions for more than 20 users; just get in touch with our
+ | Our Group subscriptions allow you to purchase access to our premium features for multiple people. They’re easy to manage, help save on paperwork, and allow groups of 5 or more to purchase via purchase order (PO). We also offer discounts on purchases of Group subscriptions for more than 20 users; just get in touch with our
a.inline-green-link(
- target="_blank"
- href="/for/contact-sales"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/for/contact-sales'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span Sales team
| .
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafGroupPlansQ3"
- data-bs-toggle="collapse"
- data-bs-target="#overleafGroupPlansQ3"
- aria-expanded="false"
- aria-controls="overleafGroupPlansQ3"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafGroupPlansQ3'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafGroupPlansQ3'
+ aria-expanded='false'
+ aria-controls='overleafGroupPlansQ3'
)
| Who is eligible for the educational discount?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafGroupPlansQ3")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafGroupPlansQ3')
.custom-accordion-body
- | The educational discount for group subscriptions is for students or faculty who are using Overleaf primarily for teaching.
+ | The educational discount for group subscriptions is for students or faculty who are using Overleaf primarily for teaching.
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafGroupPlansQ4"
- data-bs-toggle="collapse"
- data-bs-target="#overleafGroupPlansQ4"
- aria-expanded="false"
- aria-controls="overleafGroupPlansQ4"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafGroupPlansQ4'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafGroupPlansQ4'
+ aria-expanded='false'
+ aria-controls='overleafGroupPlansQ4'
)
| How do I add more licenses to my group subscription, and what will it cost?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafGroupPlansQ4")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafGroupPlansQ4')
.custom-accordion-body
- div
- | You can add up to 20 licenses using the
+ div
+ | You can add up to 20 licenses using the
a.inline-green-link(
- target="_blank"
- href="/user/subscription"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/user/subscription'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span subscription management page
- | accessed by going to Account >
+ |
+ | accessed by going to Account >
a.inline-green-link(
- target="_blank"
- href="/user/subscription"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/user/subscription'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span Subscription
- | when logged into Overleaf. The cost per license will be prorated at the current per license rate, and will end with your existing renewal date.
- div.mt-2
- | If you need more than 20 licenses added to your subscription, please
+ |
+ | when logged into Overleaf. The cost per license will be prorated at the current per license rate, and will end with your existing renewal date.
+ .mt-2
+ | If you need more than 20 licenses added to your subscription, please
a.inline-green-link(
- target="_blank"
- href="/for/contact-sales"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/for/contact-sales'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span contact the Sales team
| .
.custom-accordion-item
button.custom-accordion-header.collapsed(
- type="button"
- data-toggle="collapse"
- data-target="#overleafGroupPlansQ5"
- data-bs-toggle="collapse"
- data-bs-target="#overleafGroupPlansQ5"
- aria-expanded="false"
- aria-controls="overleafGroupPlansQ5"
+ type='button'
+ data-toggle='collapse'
+ data-target='#overleafGroupPlansQ5'
+ data-bs-toggle='collapse'
+ data-bs-target='#overleafGroupPlansQ5'
+ aria-expanded='false'
+ aria-controls='overleafGroupPlansQ5'
)
| How do I upgrade my plan from Group Standard to Group Professional?
span.custom-accordion-icon
- +material-symbol-outlined("keyboard_arrow_down")
- .collapse(id="overleafGroupPlansQ5")
+ +material-symbol-outlined('keyboard_arrow_down')
+ .collapse(id='overleafGroupPlansQ5')
.custom-accordion-body
- | You can upgrade your plan from Group Standard to Group Professional on the
+ | You can upgrade your plan from Group Standard to Group Professional on the
a.inline-green-link(
- target="_blank"
- href="/user/subscription"
- event-tracking="plans-page-click"
- event-tracking-mb="true"
- event-tracking-trigger="click"
- event-segmentation={ button: 'contact', location: 'faq' }
+ target='_blank'
+ href='/user/subscription'
+ event-tracking='plans-page-click'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
+ event-segmentation={button: 'contact', location: 'faq'}
)
span subscription management page
| .
diff --git a/services/web/app/views/subscriptions/preview-change.pug b/services/web/app/views/subscriptions/preview-change.pug
index 5330eb8684..2eaca5ac6a 100644
--- a/services/web/app/views/subscriptions/preview-change.pug
+++ b/services/web/app/views/subscriptions/preview-change.pug
@@ -4,10 +4,14 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/preview-change'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-subscriptionChangePreview" data-type="json" content=changePreview)
- meta(name="ol-purchaseReferrer" data-type="string" content=purchaseReferrer)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(
+ name='ol-subscriptionChangePreview'
+ data-type='json'
+ content=changePreview
+ )
+ meta(name='ol-purchaseReferrer' data-type='string' content=purchaseReferrer)
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
#subscription-preview-change
diff --git a/services/web/app/views/subscriptions/subtotal-limit-exceeded.pug b/services/web/app/views/subscriptions/subtotal-limit-exceeded.pug
index 4457383e93..df734232d6 100644
--- a/services/web/app/views/subscriptions/subtotal-limit-exceeded.pug
+++ b/services/web/app/views/subscriptions/subtotal-limit-exceeded.pug
@@ -4,8 +4,8 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/subtotal-limit-exceeded'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-groupName", data-type="string", content=groupName)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-groupName' data-type='string' content=groupName)
block content
- main.content.content-alt#subtotal-limit-exceeded-root
+ main#subtotal-limit-exceeded-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/successful-subscription-react.pug b/services/web/app/views/subscriptions/successful-subscription-react.pug
index 5ce208b034..9437b93b67 100644
--- a/services/web/app/views/subscriptions/successful-subscription-react.pug
+++ b/services/web/app/views/subscriptions/successful-subscription-react.pug
@@ -4,9 +4,9 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/successful-subscription'
block append meta
- meta(name="ol-subscription" data-type="json" content=personalSubscription)
- meta(name="ol-postCheckoutRedirect" content=postCheckoutRedirect)
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-subscription' data-type='json' content=personalSubscription)
+ meta(name='ol-postCheckoutRedirect' content=postCheckoutRedirect)
+ meta(name='ol-user' data-type='json' content=user)
block content
- main.content.content-alt#subscription-success-root
+ main#subscription-success-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/team/group-invites.pug b/services/web/app/views/subscriptions/team/group-invites.pug
index 81c70f1885..18286fd403 100644
--- a/services/web/app/views/subscriptions/team/group-invites.pug
+++ b/services/web/app/views/subscriptions/team/group-invites.pug
@@ -4,8 +4,8 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-invites'
block append meta
- meta(name="ol-teamInvites" data-type="json" content=teamInvites)
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-teamInvites' data-type='json' content=teamInvites)
+ meta(name='ol-user' data-type='json' content=user)
block content
- main.content.content-alt.team-invite#group-invites-root
+ main#group-invites-root.content.content-alt.team-invite
diff --git a/services/web/app/views/subscriptions/team/invite-managed.pug b/services/web/app/views/subscriptions/team/invite-managed.pug
index d31f12656b..4010731c3f 100644
--- a/services/web/app/views/subscriptions/team/invite-managed.pug
+++ b/services/web/app/views/subscriptions/team/invite-managed.pug
@@ -4,16 +4,20 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/invite-managed'
block append meta
- meta(name="ol-inviteToken" content=inviteToken)
- meta(name="ol-inviterName" content=inviterName)
- meta(name="ol-expired" data-type="boolean" content=expired)
- meta(name="ol-alreadyEnrolled" data-type="boolean" content=alreadyEnrolled)
- meta(name="ol-validationStatus" data-type="json" content=validationStatus)
- meta(name="ol-currentManagedUserAdminEmail" data-type="string" content=currentManagedUserAdminEmail)
- meta(name="ol-groupSSOActive" data-type="boolean" content=groupSSOActive)
- meta(name="ol-subscriptionId" data-type="string" content=subscriptionId)
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-usersSubscription" data-type="json" content=usersSubscription)
+ meta(name='ol-inviteToken' content=inviteToken)
+ meta(name='ol-inviterName' content=inviterName)
+ meta(name='ol-expired' data-type='boolean' content=expired)
+ meta(name='ol-alreadyEnrolled' data-type='boolean' content=alreadyEnrolled)
+ meta(name='ol-validationStatus' data-type='json' content=validationStatus)
+ meta(
+ name='ol-currentManagedUserAdminEmail'
+ data-type='string'
+ content=currentManagedUserAdminEmail
+ )
+ meta(name='ol-groupSSOActive' data-type='boolean' content=groupSSOActive)
+ meta(name='ol-subscriptionId' data-type='string' content=subscriptionId)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-usersSubscription' data-type='json' content=usersSubscription)
block content
- main.content.content-alt.team-invite#invite-managed-root
+ main#invite-managed-root.content.content-alt.team-invite
diff --git a/services/web/app/views/subscriptions/team/invite.pug b/services/web/app/views/subscriptions/team/invite.pug
index 1b2ecb4646..717ccef611 100644
--- a/services/web/app/views/subscriptions/team/invite.pug
+++ b/services/web/app/views/subscriptions/team/invite.pug
@@ -4,14 +4,22 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/invite'
block append meta
- meta(name="ol-hasIndividualPaidSubscription" data-type="boolean" content=hasIndividualPaidSubscription)
- meta(name="ol-inviterName" data-type="string" content=inviterName)
- meta(name="ol-inviteToken" data-type="string" content=inviteToken)
- meta(name="ol-currentManagedUserAdminEmail" data-type="string" content=currentManagedUserAdminEmail)
- meta(name="ol-expired" data-type="boolean" content=expired)
- meta(name="ol-groupSSOActive" data-type="boolean" content=groupSSOActive)
- meta(name="ol-subscriptionId" data-type="string" content=subscriptionId)
- meta(name="ol-user" data-type="json" content=user)
+ meta(
+ name='ol-hasIndividualPaidSubscription'
+ data-type='boolean'
+ content=hasIndividualPaidSubscription
+ )
+ meta(name='ol-inviterName' data-type='string' content=inviterName)
+ meta(name='ol-inviteToken' data-type='string' content=inviteToken)
+ meta(
+ name='ol-currentManagedUserAdminEmail'
+ data-type='string'
+ content=currentManagedUserAdminEmail
+ )
+ meta(name='ol-expired' data-type='boolean' content=expired)
+ meta(name='ol-groupSSOActive' data-type='boolean' content=groupSSOActive)
+ meta(name='ol-subscriptionId' data-type='string' content=subscriptionId)
+ meta(name='ol-user' data-type='json' content=user)
block content
- main.content.content-alt#invite-root
+ main#invite-root.content.content-alt
diff --git a/services/web/app/views/subscriptions/team/invite_logged_out.pug b/services/web/app/views/subscriptions/team/invite_logged_out.pug
index e5930aba4f..3e471fb4c9 100644
--- a/services/web/app/views/subscriptions/team/invite_logged_out.pug
+++ b/services/web/app/views/subscriptions/team/invite_logged_out.pug
@@ -1,12 +1,12 @@
extends ../../layout-marketing
block append meta
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-user' data-type='json' content=user)
block content
- var colClass = bootstrapVersion === 5 ? 'col-lg-8 m-auto' : 'col-md-8 col-md-offset-2'
- main.content.content-alt.team-invite#main-content
+ main#main-content.content.content-alt.team-invite
.container
.row
div(class=colClass)
@@ -16,15 +16,19 @@ block content
// TODO: Remove `team-invite-name` once we fully migrated to Bootstrap 5
h1.text-center !{translate("invited_to_group", {inviterName: inviterName, appName: appName }, [{name: 'span', attrs: {class: 'team-invite-name'}}])}
- if (accountExists)
+ if accountExists
div
p #{translate("invited_to_group_login_benefits", {appName: appName})}
p #{translate("invited_to_group_login", {emailAddress: emailAddress})}
p
- a.btn.btn-primary(href=`/login?redir=/subscription/invites/${inviteToken}${groupSSOActive ? "&hide_sso_login=true" : ""}`) #{translate("login_to_accept_invitation")}
+ a.btn.btn-primary(
+ href=`/login?redir=/subscription/invites/${inviteToken}${groupSSOActive ? "&hide_sso_login=true" : ""}`
+ ) #{translate("login_to_accept_invitation")}
else
div
p #{translate("invited_to_group_register_benefits", {appName: appName})}
p #{translate("invited_to_group_register", {inviterName: inviterName})}
p
- a.btn.btn-primary(href=`/register?redir=/subscription/invites/${inviteToken}${groupSSOActive ? "&hide_sso_login=true" : ""}`) #{translate("register_to_accept_invitation")}
+ a.btn.btn-primary(
+ href=`/register?redir=/subscription/invites/${inviteToken}${groupSSOActive ? "&hide_sso_login=true" : ""}`
+ ) #{translate("register_to_accept_invitation")}
diff --git a/services/web/app/views/subscriptions/upgrade-group-subscription-react.pug b/services/web/app/views/subscriptions/upgrade-group-subscription-react.pug
index 4347a2a633..0c7f4ce993 100644
--- a/services/web/app/views/subscriptions/upgrade-group-subscription-react.pug
+++ b/services/web/app/views/subscriptions/upgrade-group-subscription-react.pug
@@ -4,10 +4,14 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/upgrade-group-subscription'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-subscriptionChangePreview" data-type="json" content=changePreview)
- meta(name="ol-totalLicenses", data-type="number", content=totalLicenses)
- meta(name="ol-groupName", data-type="string", content=groupName)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(
+ name='ol-subscriptionChangePreview'
+ data-type='json'
+ content=changePreview
+ )
+ meta(name='ol-totalLicenses' data-type='number' content=totalLicenses)
+ meta(name='ol-groupName' data-type='string' content=groupName)
block content
- main.content.content-alt#upgrade-group-subscription-root
+ main#upgrade-group-subscription-root.content.content-alt
diff --git a/services/web/app/views/user/accountSuspended.pug b/services/web/app/views/user/accountSuspended.pug
index 7231713416..1a03beb4df 100644
--- a/services/web/app/views/user/accountSuspended.pug
+++ b/services/web/app/views/user/accountSuspended.pug
@@ -6,7 +6,7 @@ block vars
- metadata.robotsNoindexNofollow = true
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container-custom-sm.mx-auto
.card
.card-body
diff --git a/services/web/app/views/user/compromised_password.pug b/services/web/app/views/user/compromised_password.pug
index c66a07415a..48017b0ea7 100644
--- a/services/web/app/views/user/compromised_password.pug
+++ b/services/web/app/views/user/compromised_password.pug
@@ -9,5 +9,5 @@ block entrypointVar
- entrypoint = 'pages/compromised-password'
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
#compromised-password
diff --git a/services/web/app/views/user/confirmSecondaryEmail.pug b/services/web/app/views/user/confirmSecondaryEmail.pug
index 181e58e4ce..4f143c16dc 100644
--- a/services/web/app/views/user/confirmSecondaryEmail.pug
+++ b/services/web/app/views/user/confirmSecondaryEmail.pug
@@ -8,7 +8,7 @@ block entrypointVar
- entrypoint = 'pages/user/confirm-secondary-email'
block append meta
- meta(name="ol-email" content=email)
+ meta(name='ol-email' content=email)
block content
main.content.content-alt
diff --git a/services/web/app/views/user/confirm_email.pug b/services/web/app/views/user/confirm_email.pug
index 13e911f386..d783996076 100644
--- a/services/web/app/views/user/confirm_email.pug
+++ b/services/web/app/views/user/confirm_email.pug
@@ -2,56 +2,50 @@ extends ../layout-marketing
include ../_mixins/notification
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-lg-8.offset-lg-2.col-xl-6.offset-xl-3
.card
.card-body
- .page-header(data-ol-hide-on-error-message="confirm-email-wrong-user")
+ .page-header(data-ol-hide-on-error-message='confirm-email-wrong-user')
h1 #{translate("confirm_email")}
+ form(method='POST' action='/logout' id='logoutForm')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='redirect' type='hidden' value=currentUrlWithQueryParams)
form(
- method="POST"
- action="/logout"
- id="logoutForm"
+ name='confirmEmailForm'
+ data-ol-async-form
+ data-ol-auto-submit
+ action='/user/emails/confirm'
+ method='POST'
+ id='confirmEmailForm'
)
- input(type="hidden", name="_csrf", value=csrfToken)
- input(type="hidden", name="redirect", value=currentUrlWithQueryParams)
- form(
- data-ol-async-form,
- data-ol-auto-submit,
- name="confirmEmailForm"
- action="/user/emails/confirm",
- method="POST",
- id="confirmEmailForm",
- )
- input(type="hidden", name="_csrf", value=csrfToken)
- input(type="hidden", name="token", value=token)
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='token' type='hidden' value=token)
div(data-ol-not-sent)
- +formMessages()
- div(data-ol-custom-form-message="confirm-email-wrong-user" hidden)
+ +formMessages
+ div(data-ol-custom-form-message='confirm-email-wrong-user' hidden)
h1.h3 #{translate("we_cant_confirm_this_email")}
p !{translate("to_confirm_email_address_you_must_be_logged_in_with_the_requesting_account")}
p !{translate("you_are_currently_logged_in_as", {email: getUserEmail()})}
.actions
- button.btn-primary.btn.w-100(
- form="logoutForm"
- ) #{translate('log_in_with_a_different_account')}
+ button.btn-primary.btn.w-100(form='logoutForm') #{translate('log_in_with_a_different_account')}
.actions
button.btn-primary.btn.w-100(
- type='submit',
+ type='submit'
data-ol-disabled-inflight
- data-ol-hide-on-error-message="confirm-email-wrong-user"
+ data-ol-hide-on-error-message='confirm-email-wrong-user'
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('confirm')}
- span(hidden data-ol-inflight="pending")
- span(role='status').spinner-border.spinner-border-sm.mx-2
+ span(hidden data-ol-inflight='pending')
+ span.spinner-border.spinner-border-sm.mx-2(role='status')
div(hidden data-ol-sent)
- +notification({ariaLive: 'polite', type: 'success', className: 'mb-3', content: translate("thank_you_email_confirmed")})
- div.text-center
- a.btn.btn-primary(href="/user/settings")
+ +notification({ariaLive: 'polite', type: 'success', className: 'mb-3', content: translate('thank_you_email_confirmed')})
+ .text-center
+ a.btn.btn-primary(href='/user/settings')
| #{translate('go_to_account_settings')}
diff --git a/services/web/app/views/user/email-preferences.pug b/services/web/app/views/user/email-preferences.pug
index 86ebc5f841..2071f64705 100644
--- a/services/web/app/views/user/email-preferences.pug
+++ b/services/web/app/views/user/email-preferences.pug
@@ -2,7 +2,7 @@ extends ../layout-marketing
include ../_mixins/back_to_btns
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-lg-10.offset-lg-1.col-xl-8.offset-xl-2
@@ -10,9 +10,9 @@ block content
.card-body
.page-header
h1 #{translate("newsletter_info_title")}
-
+
p #{translate("newsletter_info_summary")}
-
+
- var submitAction
if subscribed
- submitAction = '/user/newsletter/unsubscribe'
@@ -20,28 +20,28 @@ block content
else
- submitAction = '/user/newsletter/subscribe'
p !{translate("newsletter_info_unsubscribed", {}, ['strong'])}
-
+
form(
+ name='newsletterForm'
data-ol-async-form
data-ol-reload-on-success
- name="newsletterForm"
action=submitAction
- method="POST"
+ method='POST'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessages()
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessages
p.actions.text-center
if subscribed
- button.btn-danger.btn(type='submit', data-ol-disabled-inflight)
- span(data-ol-inflight="idle") #{translate("unsubscribe")}
- span(hidden data-ol-inflight="pending") #{translate("saving")}…
+ button.btn-danger.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("unsubscribe")}
+ span(hidden data-ol-inflight='pending') #{translate("saving")}…
else
- button.btn-primary.btn(type='submit', data-ol-disabled-inflight)
- span(data-ol-inflight="idle") #{translate("subscribe")}
- span(hidden data-ol-inflight="pending") #{translate("saving")}…
-
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("subscribe")}
+ span(hidden data-ol-inflight='pending') #{translate("saving")}…
+
if subscribed
p #{translate("newsletter_info_note")}
-
+
.page-separator
- +back-to-btns()
+ +back-to-btns
diff --git a/services/web/app/views/user/login.pug b/services/web/app/views/user/login.pug
index 1ad77cb8b4..03112a0e16 100644
--- a/services/web/app/views/user/login.pug
+++ b/services/web/app/views/user/login.pug
@@ -1,7 +1,7 @@
extends ../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-lg-6.offset-lg-3.col-xl-4.offset-xl-4
@@ -11,10 +11,10 @@ block content
if login_support_title
h1 !{login_support_title}
else
- h1 #{translate("log_in")}
- form(data-ol-async-form, name="loginForm", action='/login', method="POST")
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessagesNewStyle()
+ h1 #{translate("log_in")}
+ form(name='loginForm' data-ol-async-form action='/login' method='POST')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessagesNewStyle
+customFormMessageNewStyle('invalid-password-retry-or-reset', 'danger')
| !{translate('email_or_password_wrong_try_again_or_reset', {}, [{ name: 'a', attrs: { href: '/user/password/reset', 'aria-describedby': 'resetPasswordDescription' } }])}
span.visually-hidden(id='resetPasswordDescription')
@@ -23,28 +23,24 @@ block content
| !{translate('password_compromised_try_again_or_use_known_device_or_reset', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}, {name: 'a', attrs: {href: '/user/password/reset', target: '_blank'}}])}.
.form-group
input.form-control(
- type='email',
- name='email',
- required,
- placeholder='email@example.com',
- autofocus="true"
+ name='email'
+ type='email'
+ required
+ placeholder='email@example.com'
+ autofocus='true'
)
.form-group
input.form-control(
- type='password',
- name='password',
- required,
- placeholder='********',
+ name='password'
+ type='password'
+ required
+ placeholder='********'
)
.actions
- button.btn-primary.btn(
- type='submit',
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("login")}
- span(hidden data-ol-inflight="pending") #{translate("logging_in")}…
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("login")}
+ span(hidden data-ol-inflight='pending') #{translate("logging_in")}…
a.float-end(href='/user/password/reset') #{translate("forgot_your_password")}?
if login_support_text
hr
- p.text-center !{login_support_text}
-
+ p.text-center !{login_support_text}
diff --git a/services/web/app/views/user/one_time_login.pug b/services/web/app/views/user/one_time_login.pug
index 648f6d93c1..e5d50c5a2d 100644
--- a/services/web/app/views/user/one_time_login.pug
+++ b/services/web/app/views/user/one_time_login.pug
@@ -1,7 +1,7 @@
extends ../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-lg-6.offset-lg-3.col-xl-4.offset-xl-4
@@ -13,6 +13,6 @@ block content
p
| Please
|
- a(href="/login") log in
+ a(href='/login') log in
|
| to continue working on your projects.
diff --git a/services/web/app/views/user/passwordReset-bs5.pug b/services/web/app/views/user/passwordReset-bs5.pug
index 08e0a71b9d..f69553b849 100644
--- a/services/web/app/views/user/passwordReset-bs5.pug
+++ b/services/web/app/views/user/passwordReset-bs5.pug
@@ -11,51 +11,55 @@ block content
- var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset)
if showCaptcha
- script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit")
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://www.recaptcha.net/recaptcha/api.js?render=explicit'
+ )
div(
- id="recaptcha"
- class="g-recaptcha"
+ id='recaptcha'
+ class='g-recaptcha'
data-sitekey=settings.recaptcha.siteKey
- data-size="invisible"
- data-badge="inline"
+ data-size='invisible'
+ data-badge='inline'
)
- main#main-content(data-ol-captcha-retry-trigger-area="")
- a.auth-aux-logo(href="/")
- img(src=buildImgPath("ol-brand/overleaf-o-dark.svg") alt=settings.appName)
+ main#main-content(data-ol-captcha-retry-trigger-area='')
+ a.auth-aux-logo(href='/')
+ img(src=buildImgPath('ol-brand/overleaf-o-dark.svg') alt=settings.appName)
.auth-aux-container
form(
+ name='passwordResetForm'
+ captcha-action-name=showCaptcha ? 'passwordReset' : false
data-ol-async-form
- name="passwordResetForm"
- action="/user/password/reset"
- method="POST"
- captcha=(showCaptcha ? '' : false)
- captcha-action-name=(showCaptcha ? "passwordReset" : false)
+ action='/user/password/reset'
+ method='POST'
+ captcha=showCaptcha ? '' : false
)
if error === 'password_reset_token_expired'
h1.h3.mb-3.mt-0 #{translate("sorry_your_token_expired")}
p #{translate('please_request_a_new_password_reset_email_and_follow_the_link')}.
else
h1.h3.mb-3.mt-0(data-ol-not-sent) #{translate("password_reset_sentence_case")}
- h1.h3.mb-3.mt-0(hidden data-ol-sent) #{translate("check_your_email")}
+ h1.h3.mb-3.mt-0(hidden data-ol-sent) #{translate("check_your_email")}
p.mb-3.pb-3(data-ol-not-sent) #{translate("enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password")}.
div(data-ol-not-sent)
- +formMessagesNewStyle()
+ +formMessagesNewStyle
if error && error !== 'password_reset_token_expired'
+notification({ariaLive: 'assertive', type: 'error', className: 'mb-3', content: translate(error)})
- div(data-ol-custom-form-message="no-password-allowed-due-to-sso" hidden)
- +notification({ariaLive: 'polite', type: 'error', className: 'mb-3', content: translate("you_cant_reset_password_due_to_sso", {}, [{name: 'a', attrs: {href: '/sso-login'}}])})
- input(type="hidden" name="_csrf" value=csrfToken)
+ div(data-ol-custom-form-message='no-password-allowed-due-to-sso' hidden)
+ +notification({ariaLive: 'polite', type: 'error', className: 'mb-3', content: translate('you_cant_reset_password_due_to_sso', {}, [{name: 'a', attrs: {href: '/sso-login'}}])})
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group.mb-3
label.form-label(for='email') #{translate("email")}
- input.form-control#email(
- aria-label="email"
- type='email'
+ input#email.form-control(
name='email'
+ aria-label='email'
+ type='email'
required
- autocomplete="username"
+ autocomplete='username'
autofocus
)
.actions
@@ -64,14 +68,14 @@ block content
data-ol-disabled-inflight
aria-label=translate('reset_password_sentence_case')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate("reset_password_sentence_case")}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate("requesting_password_reset")}…
- a.btn.btn-ghost.w-100.mb-3(href="/login") #{translate("back_to_log_in")}
+ a.btn.btn-ghost.w-100.mb-3(href='/login') #{translate("back_to_log_in")}
div(hidden data-ol-sent)
p.mb-4 #{translate('password_reset_email_sent')}
- a.btn.btn-primary.w-100.mb-3(href="/login") #{translate('back_to_log_in')}
+ a.btn.btn-primary.w-100.mb-3(href='/login') #{translate('back_to_log_in')}
if showCaptcha
+recaptchaConditions
diff --git a/services/web/app/views/user/passwordReset.pug b/services/web/app/views/user/passwordReset.pug
index ed806c32cd..e3396a5cc0 100644
--- a/services/web/app/views/user/passwordReset.pug
+++ b/services/web/app/views/user/passwordReset.pug
@@ -9,77 +9,81 @@ block content
- var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset)
if showCaptcha
- script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit")
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://www.recaptcha.net/recaptcha/api.js?render=explicit'
+ )
div(
- id="recaptcha"
- class="g-recaptcha"
+ id='recaptcha'
+ class='g-recaptcha'
data-sitekey=settings.recaptcha.siteKey
- data-size="invisible"
- data-badge="inline"
+ data-size='invisible'
+ data-badge='inline'
)
- main.content.content-alt#main-content(data-ol-captcha-retry-trigger-area="")
+ main#main-content.content.content-alt(data-ol-captcha-retry-trigger-area='')
.container-custom-sm.mx-auto
.card
form(
+ name='passwordResetForm'
+ captcha-action-name=showCaptcha ? 'passwordReset' : false
data-ol-async-form
- name="passwordResetForm"
- action="/user/password/reset",
- method="POST",
- captcha=(showCaptcha ? '' : false),
- captcha-action-name=(showCaptcha ? "passwordReset" : false),
+ action='/user/password/reset'
+ method='POST'
+ captcha=showCaptcha ? '' : false
)
if error === 'password_reset_token_expired'
h3.mt-0.mb-2 #{translate("sorry_your_token_expired")}
p #{translate('please_request_a_new_password_reset_email_and_follow_the_link')}.
else
h3.mt-0.mb-2(data-ol-not-sent) #{translate("password_reset")}
- h3.mt-0.mb-2(hidden data-ol-sent) #{translate("check_your_email")}
+ h3.mt-0.mb-2(hidden data-ol-sent) #{translate("check_your_email")}
p(data-ol-not-sent) #{translate("enter_your_email_address_below_and_we_will_send_you_a_link_to_reset_your_password")}.
div(data-ol-not-sent)
- +formMessages()
+ +formMessages
if error && error !== 'password_reset_token_expired'
- div.alert.alert-danger.mb-2(
- role="alert"
- aria-live="assertive"
- )
+ .alert.alert-danger.mb-2(role='alert' aria-live='assertive')
| #{translate(error)}
- div(data-ol-custom-form-message="no-password-allowed-due-to-sso" hidden)
- .notification.notification-type-error(aria-live="polite" style="margin-bottom: 10px;")
+ div(data-ol-custom-form-message='no-password-allowed-due-to-sso' hidden)
+ .notification.notification-type-error(
+ aria-live='polite'
+ style='margin-bottom: 10px'
+ )
.notification-icon
- +material-symbol-rounded("error")
+ +material-symbol-rounded('error')
.notification-content-and-cta
.notification-content
p
| !{translate("you_cant_reset_password_due_to_sso", {}, [{name: 'a', attrs: {href: '/sso-login'}}])}
- input(type="hidden", name="_csrf", value=csrfToken)
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group.mb-3
label(for='email') #{translate("email")}
- input.form-control#email(
- aria-label="email"
- type='email',
- name='email',
- placeholder=translate("enter_your_email_address"),
- required,
- autocomplete="username",
+ input#email.form-control(
+ name='email'
+ aria-label='email'
+ type='email'
+ placeholder=translate('enter_your_email_address')
+ required
+ autocomplete='username'
autofocus
)
.actions
button.btn.btn-primary.w-100(
- type='submit',
- data-ol-disabled-inflight,
+ type='submit'
+ data-ol-disabled-inflight
aria-label=translate('request_password_reset_to_reconfirm')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate("request_password_reset")}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate("requesting_password_reset")}…
div(hidden data-ol-sent)
p.mb-4 #{translate('password_reset_email_sent')}
- a(href="/login") #{translate('back_to_log_in')}
+ a(href='/login') #{translate('back_to_log_in')}
if showCaptcha
+recaptchaConditions
diff --git a/services/web/app/views/user/primaryEmailCheck-bs5.pug b/services/web/app/views/user/primaryEmailCheck-bs5.pug
index b25136927a..f45f15d0ca 100644
--- a/services/web/app/views/user/primaryEmailCheck-bs5.pug
+++ b/services/web/app/views/user/primaryEmailCheck-bs5.pug
@@ -7,36 +7,36 @@ block vars
block content
main#main-content
.auth-aux-container
- img.w-50.d-block(src=buildImgPath("ol-brand/overleaf.svg") alt=settings.appName)
+ img.w-50.d-block(
+ src=buildImgPath('ol-brand/overleaf.svg')
+ alt=settings.appName
+ )
h1.h3.mb-3 #{translate("keep_your_account_safe")}
div(data-ol-multi-submit)
p.small.mb-4
| !{translate("primary_email_check_question", { email: getUserEmail() }, ["strong"])}
form(
data-ol-async-form
- action="/user/emails/primary-email-check"
- method="POST"
+ action='/user/emails/primary-email-check'
+ method='POST'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessagesNewStyle()
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessagesNewStyle
- button.btn.btn-primary.w-100.mb-3(
- type='submit'
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("yes_that_is_correct")}
- span(hidden data-ol-inflight="pending") #{translate("confirming")}…
+ button.btn.btn-primary.w-100.mb-3(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("yes_that_is_correct")}
+ span(hidden data-ol-inflight='pending') #{translate("confirming")}…
a.btn.btn-secondary.w-100.mb-4(
- href="/user/settings#add-email"
+ href='/user/settings#add-email'
data-ol-slow-link
- event-tracking="primary-email-check-change-email"
- event-tracking-mb="true"
- event-tracking-trigger="click"
+ event-tracking='primary-email-check-change-email'
+ event-tracking-mb='true'
+ event-tracking-trigger='click'
)
- span(data-ol-inflight="idle") #{translate("no_update_email")}
- span(hidden data-ol-inflight="pending") #{translate("redirecting")}…
+ span(data-ol-inflight='idle') #{translate("no_update_email")}
+ span(hidden data-ol-inflight='pending') #{translate("redirecting")}…
p.small.mb-2
- | #{translate("keep_your_email_updated")}
+ | #{translate("keep_your_email_updated")}
p.small
- | !{translate("learn_more_about_emails", {}, [{name: 'a', attrs: {href: '/learn/how-to/Keeping_your_account_secure', 'event-tracking': 'primary-email-check-learn-more', 'event-tracking-mb': 'true', 'event-tracking-trigger': 'click' }}])}
+ | !{translate("learn_more_about_emails", {}, [{name: 'a', attrs: {href: '/learn/how-to/Keeping_your_account_secure', 'event-tracking': 'primary-email-check-learn-more', 'event-tracking-mb': 'true', 'event-tracking-trigger': 'click' }}])}
diff --git a/services/web/app/views/user/reconfirm-bs5.pug b/services/web/app/views/user/reconfirm-bs5.pug
index fce9a44295..e8e640d10c 100644
--- a/services/web/app/views/user/reconfirm-bs5.pug
+++ b/services/web/app/views/user/reconfirm-bs5.pug
@@ -5,46 +5,50 @@ block vars
- isWebsiteRedesign = true
block content
- - var email = reconfirm_email ? reconfirm_email : ""
+ - var email = reconfirm_email ? reconfirm_email : ''
- var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset)
if showCaptcha
- script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit")
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://www.recaptcha.net/recaptcha/api.js?render=explicit'
+ )
div(
- id="recaptcha"
- class="g-recaptcha"
+ id='recaptcha'
+ class='g-recaptcha'
data-sitekey=settings.recaptcha.siteKey
- data-size="invisible"
- data-badge="inline"
+ data-size='invisible'
+ data-badge='inline'
)
- main#main-content(data-ol-captcha-retry-trigger-area="")
- .container.auth-aux-container(style="max-width: 420px;")
+ main#main-content(data-ol-captcha-retry-trigger-area='')
+ .container.auth-aux-container(style='max-width: 420px')
form(
+ name='reconfirmAccountForm'
+ captcha-action-name=showCaptcha ? 'passwordReset' : false
data-ol-async-form
- name="reconfirmAccountForm"
- action="/user/reconfirm"
- method="POST"
+ action='/user/reconfirm'
+ method='POST'
aria-label=translate('request_reconfirmation_email')
- captcha=(showCaptcha ? '' : false)
- captcha-action-name=(showCaptcha ? "passwordReset" : false)
+ captcha=showCaptcha ? '' : false
)
h1.h5.mb-3 #{translate("reconfirm_account")}
p #{translate('reconfirm_explained')}
- |
+ |
a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail}
| .
-
- div(data-ol-not-sent)
- +formMessagesNewStyle()
- input(type="hidden" name="_csrf" value=csrfToken)
+ div(data-ol-not-sent)
+ +formMessagesNewStyle
+
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group.mb-3
label.form-label(for='email') #{translate("please_enter_email")}
input.form-control(
- aria-label="email"
- type='email'
name='email'
+ aria-label='email'
+ type='email'
placeholder='email@example.com'
required
autofocus
@@ -52,20 +56,17 @@ block content
)
.actions
button.btn.btn-primary.w-100(
- style="white-space: normal;"
+ style='white-space: normal'
type='submit'
data-ol-disabled-inflight
aria-label=translate('request_password_reset_to_reconfirm')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('request_password_reset_to_reconfirm')}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate('request_password_reset_to_reconfirm')}…
div(hidden data-ol-sent)
- div.alert.alert-success(
- role="alert"
- aria-live="polite"
- )
+ .alert.alert-success(role='alert' aria-live='polite')
span #{translate('password_reset_email_sent')}
if showCaptcha
diff --git a/services/web/app/views/user/reconfirm.pug b/services/web/app/views/user/reconfirm.pug
index 23b77d278d..8cfe2ec218 100644
--- a/services/web/app/views/user/reconfirm.pug
+++ b/services/web/app/views/user/reconfirm.pug
@@ -5,20 +5,24 @@ block vars
- bootstrap5PageStatus = 'disabled'
block content
- - var email = reconfirm_email ? reconfirm_email : ""
+ - var email = reconfirm_email ? reconfirm_email : ''
- var showCaptcha = settings.recaptcha && settings.recaptcha.siteKey && !(settings.recaptcha.disabled && settings.recaptcha.disabled.passwordReset)
if showCaptcha
- script(type="text/javascript", nonce=scriptNonce, src="https://www.recaptcha.net/recaptcha/api.js?render=explicit")
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src='https://www.recaptcha.net/recaptcha/api.js?render=explicit'
+ )
div(
- id="recaptcha"
- class="g-recaptcha"
+ id='recaptcha'
+ class='g-recaptcha'
data-sitekey=settings.recaptcha.siteKey
- data-size="invisible"
- data-badge="inline"
+ data-size='invisible'
+ data-badge='inline'
)
- main.content.content-alt#main-content(data-ol-captcha-retry-trigger-area="")
+ main#main-content.content.content-alt(data-ol-captcha-retry-trigger-area='')
.container
.row
.col-sm-12.col-md-6.col-md-offset-3
@@ -28,44 +32,41 @@ block content
a(href=`mailto:${settings.adminEmail}`) #{settings.adminEmail}
| .
form(
+ name='reconfirmAccountForm'
+ captcha-action-name=showCaptcha ? 'passwordReset' : false
data-ol-async-form
- name="reconfirmAccountForm"
- action="/user/reconfirm",
- method="POST",
+ action='/user/reconfirm'
+ method='POST'
aria-label=translate('request_reconfirmation_email')
- captcha=(showCaptcha ? '' : false),
- captcha-action-name=(showCaptcha ? "passwordReset" : false)
+ captcha=showCaptcha ? '' : false
)
div(data-ol-not-sent)
- +formMessages()
-
- input(type="hidden", name="_csrf", value=csrfToken)
+ +formMessages
+
+ input(name='_csrf' type='hidden' value=csrfToken)
.form-group
label(for='email') #{translate("please_enter_email")}
input.form-control(
- aria-label="email"
- type='email',
- name='email',
- placeholder='email@example.com',
- required,
+ name='email'
+ aria-label='email'
+ type='email'
+ placeholder='email@example.com'
+ required
autofocus
value=email
)
.actions
button.btn.btn-primary(
- type='submit',
- data-ol-disabled-inflight,
+ type='submit'
+ data-ol-disabled-inflight
aria-label=translate('request_password_reset_to_reconfirm')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('request_password_reset_to_reconfirm')}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate('request_password_reset_to_reconfirm')}…
div(hidden data-ol-sent)
- div.alert.alert-success(
- role="alert"
- aria-live="polite"
- )
+ .alert.alert-success(role='alert' aria-live='polite')
span #{translate('password_reset_email_sent')}
.row
.col-sm-12.col-md-6.col-md-offset-3
diff --git a/services/web/app/views/user/register.pug b/services/web/app/views/user/register.pug
index c35f3c04f0..8aa40e8b35 100644
--- a/services/web/app/views/user/register.pug
+++ b/services/web/app/views/user/register.pug
@@ -4,7 +4,7 @@ block vars
- bootstrap5PageStatus = 'disabled'
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.registration_message
@@ -15,12 +15,12 @@ block content
| #{translate("join_sl_to_view_project")}.
div
| #{translate("already_have_sl_account")}
- a(href="/login") #{translate("login_here")}
+ a(href='/login') #{translate("login_here")}
else if newTemplateData.templateName !== undefined
h1 #{translate("register_to_edit_template", {templateName:newTemplateData.templateName})}
div #{translate("already_have_sl_account")}
- a(href="/login") #{translate("login_here")}
+ a(href='/login') #{translate("login_here")}
.row
.col-md-8.col-md-offset-2.col-lg-6.col-lg-offset-3
diff --git a/services/web/app/views/user/sessions.pug b/services/web/app/views/user/sessions.pug
index ffd65a3548..744b804687 100644
--- a/services/web/app/views/user/sessions.pug
+++ b/services/web/app/views/user/sessions.pug
@@ -1,15 +1,15 @@
extends ../layout-marketing
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-lg-10.offset-lg-1.col-xl-8.offset-xl-2
.card.clear-user-sessions
.card-body
.page-header
- h1 #{translate("your_sessions")}
-
+ h1 #{translate("your_sessions")}
+
if currentSession.ip_address && currentSession.session_created
h3 #{translate("current_session")}
div
@@ -21,47 +21,43 @@ block content
tr
td #{currentSession.ip_address}
td #{moment(currentSession.session_created).utc().format('Do MMM YYYY, h:mm a')} UTC
-
+
h3 #{translate("other_sessions")}
div
p.small
| !{translate("clear_sessions_description")}
-
- form(
- data-ol-async-form
- action='/user/sessions/clear'
- method='POST'
- )
+
+ form(data-ol-async-form action='/user/sessions/clear' method='POST')
input(name='_csrf' type='hidden' value=csrfToken)
div(data-ol-not-sent)
if sessions.length == 0
p.text-center
| #{translate("no_other_sessions")}
-
+
if sessions.length > 0
table.table.table-striped
thead
tr
th #{translate("ip_address")}
th #{translate("session_created_at")}
- for session in sessions
+ each session in sessions
tr
td #{session.ip_address}
td #{moment(session.session_created).utc().format('Do MMM YYYY, h:mm a')} UTC
-
+
p.actions
.text-center
button.btn.btn-lg.btn-primary(
- type="submit"
+ type='submit'
data-ol-disable-inflight
)
- span(data-ol-inflight="idle") #{translate('clear_sessions')}
- span(hidden data-ol-inflight="pending") #{translate("processing")}…
-
+ span(data-ol-inflight='idle') #{translate('clear_sessions')}
+ span(hidden data-ol-inflight='pending') #{translate("processing")}…
+
div(hidden data-ol-sent)
p.text-center
| #{translate("no_other_sessions")}
-
+
p.text-success.text-center
| #{translate('clear_sessions_success')}
.page-separator
diff --git a/services/web/app/views/user/setPassword-bs5.pug b/services/web/app/views/user/setPassword-bs5.pug
index 83c3a531bb..5081d22409 100644
--- a/services/web/app/views/user/setPassword-bs5.pug
+++ b/services/web/app/views/user/setPassword-bs5.pug
@@ -7,28 +7,25 @@ block vars
block content
main#main-content
- a.auth-aux-logo(href="/")
- img(src=buildImgPath("ol-brand/overleaf-o-dark.svg") alt=settings.appName)
+ a.auth-aux-logo(href='/')
+ img(src=buildImgPath('ol-brand/overleaf-o-dark.svg') alt=settings.appName)
.auth-aux-container
form(
+ name='passwordResetForm'
data-ol-async-form
- name="passwordResetForm"
- action="/user/password/set"
- method="POST"
- data-ol-hide-on-error="token-expired"
+ action='/user/password/set'
+ method='POST'
+ data-ol-hide-on-error='token-expired'
)
- div(
- hidden
- data-ol-sent
- )
+ div(hidden data-ol-sent)
h1.h3.mb-3.mt-0 #{translate("password_updated")}
p.mb-4 #{translate("your_password_has_been_successfully_changed")}.
a.btn.btn-primary.w-100(href='/login') #{translate("log_in_now")}
div(data-ol-not-sent)
h1.h3.mb-3.mt-0 #{translate("reset_your_password")}
- p(data-ol-hide-on-error-message="token-expired") #{translate("create_a_new_password_for_your_account")}.
- +formMessagesNewStyle()
+ p(data-ol-hide-on-error-message='token-expired') #{translate("create_a_new_password_for_your_account")}.
+ +formMessagesNewStyle
+customFormMessageNewStyle('password-contains-email', 'danger')
| #{translate('invalid_password_contains_email')}.
@@ -41,18 +38,21 @@ block content
+customFormMessageNewStyle('token-expired', 'danger')
| #{translate('password_reset_token_expired')}
br
- a(href="/user/password/reset")
+ a(href='/user/password/reset')
| #{translate('request_new_password_reset_email')}
- input(type="hidden" name="_csrf" value=csrfToken)
- input(type="text" hidden name="email" autocomplete="username" value=email)
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='email' type='text' hidden autocomplete='username' value=email)
.form-group.mb-3
- label.form-label(for='passwordField', data-ol-hide-on-error-message="token-expired") #{translate("new_password")}
- input.form-control.auth-aux-new-password#passwordField(
- type='password'
+ label.form-label(
+ for='passwordField'
+ data-ol-hide-on-error-message='token-expired'
+ ) #{translate("new_password")}
+ input#passwordField.form-control.auth-aux-new-password(
name='password'
- autocomplete="new-password"
+ type='password'
+ autocomplete='new-password'
autofocus
required
minlength=settings.passwordStrengthOptions.length.min
@@ -68,12 +68,8 @@ block content
| !{translate('password_was_detected_on_a_public_list_of_known_compromised_passwords', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}])}.
| #{translate('use_a_different_password')}.
- input(
- type="hidden"
- name="passwordResetToken"
- value=passwordResetToken
- )
- div(data-ol-hide-on-error-message="token-expired")
+ input(name='passwordResetToken' type='hidden' value=passwordResetToken)
+ div(data-ol-hide-on-error-message='token-expired')
div #{translate('in_order_to_have_a_secure_account_make_sure_your_password')}
ul.mb-3.ps-4
li #{translate('is_longer_than_n_characters', {n: settings.passwordStrengthOptions.length.min})}
@@ -85,7 +81,7 @@ block content
data-ol-disabled-inflight
aria-label=translate('set_new_password')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('set_new_password')}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate('set_new_password')}…
diff --git a/services/web/app/views/user/setPassword.pug b/services/web/app/views/user/setPassword.pug
index 5da2b6b59a..653bc52045 100644
--- a/services/web/app/views/user/setPassword.pug
+++ b/services/web/app/views/user/setPassword.pug
@@ -4,28 +4,25 @@ block vars
- bootstrap5PageStatus = 'disabled'
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container-custom-sm.mx-auto
.card
form(
- data-ol-async-form,
- name="passwordResetForm",
- action="/user/password/set",
- method="POST",
- data-ol-hide-on-error="token-expired"
+ name='passwordResetForm'
+ data-ol-async-form
+ action='/user/password/set'
+ method='POST'
+ data-ol-hide-on-error='token-expired'
)
- div(
- hidden
- data-ol-sent
- )
+ div(hidden data-ol-sent)
h3.mt-0.mb-2 #{translate("password_updated")}
p.mb-4 #{translate("your_password_has_been_successfully_changed")}.
a(href='/login') #{translate("log_in_now")}
div(data-ol-not-sent)
h3.mt-0.mb-2 #{translate("reset_your_password")}
- p(data-ol-hide-on-error-message="token-expired") #{translate("create_a_new_password_for_your_account")}.
- +formMessages()
+ p(data-ol-hide-on-error-message='token-expired') #{translate("create_a_new_password_for_your_account")}.
+ +formMessages
+customFormMessage('password-contains-email', 'danger')
| #{translate('invalid_password_contains_email')}.
@@ -38,21 +35,30 @@ block content
+customFormMessage('token-expired', 'danger')
| #{translate('password_reset_token_expired')}
br
- a(href="/user/password/reset")
+ a(href='/user/password/reset')
| #{translate('request_new_password_reset_email')}
- input(type="hidden", name="_csrf", value=csrfToken)
- input(type="text" hidden name="email" autocomplete="username" value=email)
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(
+ name='email'
+ type='text'
+ hidden
+ autocomplete='username'
+ value=email
+ )
.form-group
- label(for='passwordField', data-ol-hide-on-error-message="token-expired") #{translate("new_password")}
- input.form-control#passwordField(
- type='password',
- name='password',
- placeholder=translate("enter_your_new_password"),
- autocomplete="new-password",
- autofocus,
- required,
+ label(
+ for='passwordField'
+ data-ol-hide-on-error-message='token-expired'
+ ) #{translate("new_password")}
+ input#passwordField.form-control(
+ name='password'
+ type='password'
+ placeholder=translate('enter_your_new_password')
+ autocomplete='new-password'
+ autofocus
+ required
minlength=settings.passwordStrengthOptions.length.min
)
@@ -66,12 +72,8 @@ block content
| !{translate('password_was_detected_on_a_public_list_of_known_compromised_passwords', {}, [{name: 'a', attrs: {href: 'https://haveibeenpwned.com/passwords', rel: 'noopener noreferrer', target: '_blank'}}])}.
| #{translate('use_a_different_password')}.
- input(
- type="hidden",
- name="passwordResetToken",
- value=passwordResetToken
- )
- div(data-ol-hide-on-error-message="token-expired")
+ input(name='passwordResetToken' type='hidden' value=passwordResetToken)
+ div(data-ol-hide-on-error-message='token-expired')
div #{translate('in_order_to_have_a_secure_account_make_sure_your_password')}
ul.mb-4.ps-4
li #{translate('is_longer_than_n_characters', {n: settings.passwordStrengthOptions.length.min})}
@@ -79,11 +81,11 @@ block content
li #{translate('is_not_used_on_any_other_website')}
.actions
button.btn.btn-primary.w-100(
- type='submit',
+ type='submit'
data-ol-disabled-inflight
aria-label=translate('set_new_password')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('set_new_password')}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate('set_new_password')}…
diff --git a/services/web/app/views/user/settings.pug b/services/web/app/views/user/settings.pug
index 4ac35bef71..dc63e27abe 100644
--- a/services/web/app/views/user/settings.pug
+++ b/services/web/app/views/user/settings.pug
@@ -2,38 +2,65 @@ extends ../layout-react
block entrypointVar
- entrypoint = 'pages/user/settings'
-
+
block vars
- isWebsiteRedesign = true
block append meta
- meta(name="ol-hasPassword" data-type="boolean" content=hasPassword)
- meta(name="ol-shouldAllowEditingDetails" data-type="boolean" content=shouldAllowEditingDetails)
- meta(name="ol-oauthProviders", data-type="json", content=oauthProviders)
- meta(name="ol-institutionLinked", data-type="json", content=institutionLinked)
- meta(name="ol-samlError", data-type="json", content=samlError)
- meta(name="ol-institutionEmailNonCanonical", content=institutionEmailNonCanonical)
+ meta(name='ol-hasPassword' data-type='boolean' content=hasPassword)
+ meta(
+ name='ol-shouldAllowEditingDetails'
+ data-type='boolean'
+ content=shouldAllowEditingDetails
+ )
+ meta(name='ol-oauthProviders' data-type='json' content=oauthProviders)
+ meta(name='ol-institutionLinked' data-type='json' content=institutionLinked)
+ meta(name='ol-samlError' data-type='json' content=samlError)
+ meta(
+ name='ol-institutionEmailNonCanonical'
+ content=institutionEmailNonCanonical
+ )
- meta(name="ol-reconfirmedViaSAML", content=reconfirmedViaSAML)
- meta(name="ol-reconfirmationRemoveEmail", content=reconfirmationRemoveEmail)
- meta(name="ol-samlBeta", content=samlBeta)
- meta(name="ol-ssoErrorMessage", content=ssoErrorMessage)
- meta(name="ol-thirdPartyIds", data-type="json", content=thirdPartyIds || {})
- meta(name="ol-passwordStrengthOptions", data-type="json", content=settings.passwordStrengthOptions || {})
- meta(name="ol-isExternalAuthenticationSystemUsed" data-type="boolean" content=externalAuthenticationSystemUsed())
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-labsExperiments" data-type="json" content=labsExperiments)
- meta(name="ol-dropbox" data-type="json" content=dropbox)
- meta(name="ol-github" data-type="json" content=github)
- meta(name="ol-projectSyncSuccessMessage", content=projectSyncSuccessMessage)
- meta(name="ol-personalAccessTokens", data-type="json" content=personalAccessTokens)
- meta(name="ol-emailAddressLimit", data-type="json", content=emailAddressLimit)
- meta(name="ol-currentManagedUserAdminEmail" data-type="string" content=currentManagedUserAdminEmail)
- meta(name="ol-gitBridgeEnabled" data-type="boolean" content=gitBridgeEnabled)
- meta(name="ol-isSaas" data-type="boolean" content=isSaas)
- meta(name="ol-memberOfSSOEnabledGroups" data-type="json" content=memberOfSSOEnabledGroups)
- meta(name="ol-capabilities" data-type="json" content=capabilities)
+ meta(name='ol-reconfirmedViaSAML' content=reconfirmedViaSAML)
+ meta(name='ol-reconfirmationRemoveEmail' content=reconfirmationRemoveEmail)
+ meta(name='ol-samlBeta' content=samlBeta)
+ meta(name='ol-ssoErrorMessage' content=ssoErrorMessage)
+ meta(name='ol-thirdPartyIds' data-type='json' content=thirdPartyIds || {})
+ meta(
+ name='ol-passwordStrengthOptions'
+ data-type='json'
+ content=settings.passwordStrengthOptions || {}
+ )
+ meta(
+ name='ol-isExternalAuthenticationSystemUsed'
+ data-type='boolean'
+ content=externalAuthenticationSystemUsed()
+ )
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-labsExperiments' data-type='json' content=labsExperiments)
+ meta(name='ol-dropbox' data-type='json' content=dropbox)
+ meta(name='ol-github' data-type='json' content=github)
+ meta(name='ol-projectSyncSuccessMessage' content=projectSyncSuccessMessage)
+ meta(
+ name='ol-personalAccessTokens'
+ data-type='json'
+ content=personalAccessTokens
+ )
+ meta(name='ol-emailAddressLimit' data-type='json' content=emailAddressLimit)
+ meta(
+ name='ol-currentManagedUserAdminEmail'
+ data-type='string'
+ content=currentManagedUserAdminEmail
+ )
+ meta(name='ol-gitBridgeEnabled' data-type='boolean' content=gitBridgeEnabled)
+ meta(name='ol-isSaas' data-type='boolean' content=isSaas)
+ meta(
+ name='ol-memberOfSSOEnabledGroups'
+ data-type='json'
+ content=memberOfSSOEnabledGroups
+ )
+ meta(name='ol-capabilities' data-type='json' content=capabilities)
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
#settings-page-root
diff --git a/services/web/app/views/user_membership/group-managers-react.pug b/services/web/app/views/user_membership/group-managers-react.pug
index d227a7a511..34414ddbf2 100644
--- a/services/web/app/views/user_membership/group-managers-react.pug
+++ b/services/web/app/views/user_membership/group-managers-react.pug
@@ -4,10 +4,10 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/group-managers'
block append meta
- meta(name="ol-user", data-type="json", content=user)
- meta(name="ol-users", data-type="json", content=users)
- meta(name="ol-groupId", data-type="string", content=groupId)
- meta(name="ol-groupName", data-type="string", content=name)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-users' data-type='json' content=users)
+ meta(name='ol-groupId' data-type='string' content=groupId)
+ meta(name='ol-groupName' data-type='string' content=name)
block content
- main.content.content-alt#subscription-manage-group-root
+ main#subscription-manage-group-root.content.content-alt
diff --git a/services/web/app/views/user_membership/group-members-react.pug b/services/web/app/views/user_membership/group-members-react.pug
index 05327c4b6d..4020ebdf58 100644
--- a/services/web/app/views/user_membership/group-members-react.pug
+++ b/services/web/app/views/user_membership/group-members-react.pug
@@ -2,18 +2,34 @@ extends ../layout-react
block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/group-members'
-
+
block append meta
- meta(name="ol-user", data-type="json", content=user)
- meta(name="ol-users", data-type="json", content=users)
- meta(name="ol-groupId", data-type="string", content=groupId)
- meta(name="ol-groupName", data-type="string", content=name)
- meta(name="ol-groupSize", data-type="json", content=groupSize)
- meta(name="ol-managedUsersActive", data-type="boolean", content=managedUsersActive)
- meta(name="ol-isUserGroupManager", data-type="boolean", content=isUserGroupManager)
- meta(name="ol-groupSSOActive", data-type="boolean", content=groupSSOActive)
- meta(name="ol-canUseFlexibleLicensing", data-type="boolean", content=canUseFlexibleLicensing)
- meta(name="ol-canUseAddSeatsFeature", data-type="boolean", content=canUseAddSeatsFeature)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-users' data-type='json' content=users)
+ meta(name='ol-groupId' data-type='string' content=groupId)
+ meta(name='ol-groupName' data-type='string' content=name)
+ meta(name='ol-groupSize' data-type='json' content=groupSize)
+ meta(
+ name='ol-managedUsersActive'
+ data-type='boolean'
+ content=managedUsersActive
+ )
+ meta(
+ name='ol-isUserGroupManager'
+ data-type='boolean'
+ content=isUserGroupManager
+ )
+ meta(name='ol-groupSSOActive' data-type='boolean' content=groupSSOActive)
+ meta(
+ name='ol-canUseFlexibleLicensing'
+ data-type='boolean'
+ content=canUseFlexibleLicensing
+ )
+ meta(
+ name='ol-canUseAddSeatsFeature'
+ data-type='boolean'
+ content=canUseAddSeatsFeature
+ )
block content
- main.content.content-alt#subscription-manage-group-root
+ main#subscription-manage-group-root.content.content-alt
diff --git a/services/web/app/views/user_membership/institution-managers-react.pug b/services/web/app/views/user_membership/institution-managers-react.pug
index ee62fcd430..9793058f6f 100644
--- a/services/web/app/views/user_membership/institution-managers-react.pug
+++ b/services/web/app/views/user_membership/institution-managers-react.pug
@@ -4,10 +4,10 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/institution-managers'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-users", data-type="json", content=users)
- meta(name="ol-groupId", data-type="string", content=groupId)
- meta(name="ol-groupName", data-type="string", content=name)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-users' data-type='json' content=users)
+ meta(name='ol-groupId' data-type='string' content=groupId)
+ meta(name='ol-groupName' data-type='string' content=name)
block content
- main.content.content-alt#subscription-manage-group-root
+ main#subscription-manage-group-root.content.content-alt
diff --git a/services/web/app/views/user_membership/new.pug b/services/web/app/views/user_membership/new.pug
index c59837b107..4e52ea160a 100644
--- a/services/web/app/views/user_membership/new.pug
+++ b/services/web/app/views/user_membership/new.pug
@@ -4,20 +4,13 @@ block vars
- bootstrap5PageStatus = 'disabled'
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
.row
.col-md-10.col-md-offset-1
h3 #{entityName} "#{entityId}" does not exists in v2
- form(
- data-ol-regular-form
- method='post',
- action=''
- )
- input(name="_csrf", type="hidden", value=csrfToken)
- button.btn.btn-primary(
- type="submit",
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") Create #{entityName} in v2
- span(hidden data-ol-inflight="pending") #{translate("creating")}…
+ form(data-ol-regular-form method='post' action='')
+ input(name='_csrf' type='hidden' value=csrfToken)
+ button.btn.btn-primary(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') Create #{entityName} in v2
+ span(hidden data-ol-inflight='pending') #{translate("creating")}…
diff --git a/services/web/app/views/user_membership/publisher-managers-react.pug b/services/web/app/views/user_membership/publisher-managers-react.pug
index a956e30c35..2f805079a7 100644
--- a/services/web/app/views/user_membership/publisher-managers-react.pug
+++ b/services/web/app/views/user_membership/publisher-managers-react.pug
@@ -4,10 +4,10 @@ block entrypointVar
- entrypoint = 'pages/user/subscription/group-management/publisher-managers'
block append meta
- meta(name="ol-user" data-type="json" content=user)
- meta(name="ol-users", data-type="json", content=users)
- meta(name="ol-groupId", data-type="string", content=groupId)
- meta(name="ol-groupName", data-type="string", content=name)
+ meta(name='ol-user' data-type='json' content=user)
+ meta(name='ol-users' data-type='json' content=users)
+ meta(name='ol-groupId' data-type='string' content=groupId)
+ meta(name='ol-groupName' data-type='string' content=name)
block content
- main.content.content-alt#subscription-manage-group-root
+ main#subscription-manage-group-root.content.content-alt
diff --git a/services/web/modules/launchpad/app/views/launchpad.pug b/services/web/modules/launchpad/app/views/launchpad.pug
index fdf0576c4a..ff917eeb74 100644
--- a/services/web/modules/launchpad/app/views/launchpad.pug
+++ b/services/web/modules/launchpad/app/views/launchpad.pug
@@ -2,39 +2,43 @@ extends ../../../../app/views/layout-marketing
mixin launchpad-check(section)
div(data-ol-launchpad-check=section)
- span(data-ol-inflight="pending")
+ span(data-ol-inflight='pending')
i.fa.fa-fw.fa-spinner.fa-spin
span #{translate('checking')}
-
- span(hidden data-ol-inflight="idle")
- div(data-ol-result="success")
+
+ span(hidden data-ol-inflight='idle')
+ div(data-ol-result='success')
i.fa.fa-check
span #{translate('ok')}
button.btn.btn-inline-link
span.text-danger #{translate('retry')}
- div(hidden data-ol-result="error")
+ div(hidden data-ol-result='error')
i.fa.fa-exclamation
span #{translate('error')}
button.btn.btn-inline-link
span.text-danger #{translate('retry')}
- div.alert.alert-danger
+ .alert.alert-danger
span(data-ol-error)
block entrypointVar
- entrypoint = 'modules/launchpad/pages/launchpad'
-
+
block vars
- metadata = metadata || {}
- bootstrap5PageStatus = 'disabled'
block append meta
- meta(name="ol-adminUserExists" data-type="boolean" content=adminUserExists)
- meta(name="ol-ideJsPath" content=buildJsPath('ide.js'))
+ meta(name='ol-adminUserExists' data-type='boolean' content=adminUserExists)
+ meta(name='ol-ideJsPath' content=buildJsPath('ide.js'))
block content
- script(type="text/javascript", nonce=scriptNonce, src=(wsUrl || '/socket.io') + '/socket.io.js')
+ script(
+ type='text/javascript'
+ nonce=scriptNonce
+ src=(wsUrl || '/socket.io') + '/socket.io.js'
+ )
- .content.content-alt#main-content
+ #main-content.content.content-alt
.container
.row
.col-md-8.col-md-offset-2
@@ -49,8 +53,6 @@ block content
.row
.col-md-8.col-md-offset-2
-
-
if !adminUserExists
.row(data-ol-not-sent)
@@ -62,37 +64,34 @@ block content
form(
data-ol-async-form
data-ol-register-admin
- action="/launchpad/register_admin"
- method="POST"
+ action='/launchpad/register_admin'
+ method='POST'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessages()
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessages
.form-group
label(for='email') #{translate("email")}
input.form-control(
- type='email',
- name='email',
- placeholder="email@example.com"
- autocomplete="username"
- required,
- autofocus="true"
+ name='email'
+ type='email'
+ placeholder='email@example.com'
+ autocomplete='username'
+ required
+ autofocus='true'
)
.form-group
label(for='password') #{translate("password")}
- input.form-control#passwordField(
- type='password',
- name='password',
- placeholder="********",
- autocomplete="new-password"
- required,
+ input#passwordField.form-control(
+ name='password'
+ type='password'
+ placeholder='********'
+ autocomplete='new-password'
+ required
)
.actions
- button.btn-primary.btn(
- type='submit'
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("register")}
- span(hidden data-ol-inflight="pending") #{translate("registering")}…
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("register")}
+ span(hidden data-ol-inflight='pending') #{translate("registering")}…
// Ldap Form
if authMethod === 'ldap'
@@ -103,28 +102,25 @@ block content
form(
data-ol-async-form
data-ol-register-admin
- action="/launchpad/register_ldap_admin"
- method="POST"
+ action='/launchpad/register_ldap_admin'
+ method='POST'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessages()
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessages
.form-group
label(for='email') #{translate("email")}
input.form-control(
- type='email',
- name='email',
- placeholder="email@example.com"
- autocomplete="username"
- required,
- autofocus="true"
+ name='email'
+ type='email'
+ placeholder='email@example.com'
+ autocomplete='username'
+ required
+ autofocus='true'
)
.actions
- button.btn-primary.btn(
- type='submit'
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("register")}
- span(hidden data-ol-inflight="pending") #{translate("registering")}…
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("register")}
+ span(hidden data-ol-inflight='pending') #{translate("registering")}…
// Saml Form
if authMethod === 'saml'
@@ -135,28 +131,25 @@ block content
form(
data-ol-async-form
data-ol-register-admin
- action="/launchpad/register_saml_admin"
- method="POST"
+ action='/launchpad/register_saml_admin'
+ method='POST'
)
- input(name='_csrf', type='hidden', value=csrfToken)
- +formMessages()
+ input(name='_csrf' type='hidden' value=csrfToken)
+ +formMessages
.form-group
label(for='email') #{translate("email")}
input.form-control(
- type='email',
- name='email',
- placeholder="email@example.com"
- autocomplete="username"
- required,
- autofocus="true"
+ name='email'
+ type='email'
+ placeholder='email@example.com'
+ autocomplete='username'
+ required
+ autofocus='true'
)
.actions
- button.btn-primary.btn(
- type='submit'
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("register")}
- span(hidden data-ol-inflight="pending") #{translate("registering")}…
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("register")}
+ span(hidden data-ol-inflight='pending') #{translate("registering")}…
br
@@ -164,7 +157,6 @@ block content
if adminUserExists
.row
.col-md-12.status-indicators
-
h2 #{translate('status_checks')}
@@ -185,42 +177,31 @@ block content
h3 #{translate('send_test_email')}
form.form(
data-ol-async-form
- action="/launchpad/send_test_email"
- method="POST"
+ action='/launchpad/send_test_email'
+ method='POST'
)
.form-group
- label(for="email") Email
- input.form-control(
- type="text"
- id="email"
- name="email"
- required
- )
- button.btn-primary.btn(
- type='submit'
- data-ol-disabled-inflight
- )
- span(data-ol-inflight="idle") #{translate("send")}
- span(hidden data-ol-inflight="pending") #{translate("sending")}…
+ label(for='email') Email
+ input.form-control(name='email' type='text' id='email' required)
+ button.btn-primary.btn(type='submit' data-ol-disabled-inflight)
+ span(data-ol-inflight='idle') #{translate("send")}
+ span(hidden data-ol-inflight='pending') #{translate("sending")}…
p
- +formMessages()
-
-
+ +formMessages
hr.thin
-
.row
.col-md-12
.text-center
br
p
- a(href="/admin").btn.btn-info
+ a.btn.btn-info(href='/admin')
| Go To Admin Panel
|
- a(href="/project").btn.btn-primary
+ a.btn.btn-primary(href='/project')
| Start Using #{settings.appName}
br
diff --git a/services/web/modules/user-activate/app/views/user/activate.pug b/services/web/modules/user-activate/app/views/user/activate.pug
index deebe0b08a..82671f90a7 100644
--- a/services/web/modules/user-activate/app/views/user/activate.pug
+++ b/services/web/modules/user-activate/app/views/user/activate.pug
@@ -6,14 +6,14 @@ block vars
include ../../../../../app/views/_mixins/material_symbol
block content
- main.content.content-alt#main-content
+ main#main-content.content.content-alt
.container
- div.col-lg-6.col-xl-4.m-auto
+ .col-lg-6.col-xl-4.m-auto
.notification-list
- .notification.notification-type-success(aria-live="off" role="alert")
+ .notification.notification-type-success(aria-live='off' role='alert')
.notification-content-and-cta
.notification-icon
- +material-symbol("check_circle")
+ +material-symbol('check_circle')
.notification-content
p
| #{translate("nearly_activated")}
@@ -21,12 +21,12 @@ block content
h1.h3 #{translate("please_set_a_password")}
form(
+ name='activationForm'
data-ol-async-form
- name="activationForm",
- action="/user/password/set",
- method="POST",
+ action='/user/password/set'
+ method='POST'
)
- +formMessages()
+ +formMessages
+customFormMessage('token-expired', 'danger')
| #{translate("activation_token_expired")}
@@ -34,43 +34,39 @@ block content
+customFormMessage('invalid-password', 'danger')
| #{translate('invalid_password')}
- input(name='_csrf', type='hidden', value=csrfToken)
- input(
- type="hidden",
- name="passwordResetToken",
- value=token
- )
+ input(name='_csrf' type='hidden' value=csrfToken)
+ input(name='passwordResetToken' type='hidden' value=token)
.form-group
label(for='emailField') #{translate("email")}
- input.form-control#emailField(
- aria-label="email",
- type='email',
- name='email',
- placeholder="email@example.com",
- autocomplete="username"
+ input#emailField.form-control(
+ name='email'
+ aria-label='email'
+ type='email'
+ placeholder='email@example.com'
+ autocomplete='username'
value=email
- required,
+ required
disabled
)
.form-group
label(for='passwordField') #{translate("password")}
- input.form-control#passwordField(
- type='password',
- name='password',
- placeholder="********",
- autocomplete="new-password",
- autofocus,
- required,
+ input#passwordField.form-control(
+ name='password'
+ type='password'
+ placeholder='********'
+ autocomplete='new-password'
+ autofocus
+ required
minlength=settings.passwordStrengthOptions.length.min
)
.actions
button.btn.btn-primary(
- type='submit',
+ type='submit'
data-ol-disabled-inflight
aria-label=translate('activate')
)
- span(data-ol-inflight="idle")
+ span(data-ol-inflight='idle')
| #{translate('activate')}
- span(hidden data-ol-inflight="pending")
+ span(hidden data-ol-inflight='pending')
| #{translate('activating')}…
diff --git a/services/web/modules/user-activate/app/views/user/register.pug b/services/web/modules/user-activate/app/views/user/register.pug
index 0f3e5f2f91..27e6f8215c 100644
--- a/services/web/modules/user-activate/app/views/user/register.pug
+++ b/services/web/modules/user-activate/app/views/user/register.pug
@@ -4,9 +4,9 @@ block entrypointVar
- entrypoint = 'modules/user-activate/pages/user-activate-page'
block append meta
- meta(name="ol-user" data-type="json" content=user)
+ meta(name='ol-user' data-type='json' content=user)
block content
- .content.content-alt#main-content
+ #main-content.content.content-alt
.container
#user-activate-register-container
diff --git a/services/web/package.json b/services/web/package.json
index 59825e0e68..bdc42673bb 100644
--- a/services/web/package.json
+++ b/services/web/package.json
@@ -28,6 +28,8 @@
"format:fix": "prettier --write $PWD/'**/*.{js,jsx,mjs,ts,tsx,json}'",
"format:styles": "prettier --list-different $PWD/'**/*.{css,less,scss}'",
"format:styles:fix": "prettier --write $PWD/'**/*.{css,less,scss}'",
+ "format:pug": "prettier --list-different $PWD/'**/*.pug'",
+ "format:pug:fix": "prettier --write $PWD/'**/*.pug'",
"lint": "eslint --max-warnings 0 --format unix --ext .js,.jsx,.mjs,.ts,.tsx .",
"lint:fix": "eslint --fix --ext .js,.jsx,.mjs,.ts,.tsx .",
"lint:styles": "stylelint '**/*.scss'",
@@ -209,6 +211,7 @@
"@pollyjs/adapter-node-http": "^6.0.6",
"@pollyjs/core": "^6.0.6",
"@pollyjs/persister-fs": "^6.0.6",
+ "@prettier/plugin-pug": "^3.4.0",
"@replit/codemirror-emacs": "overleaf/codemirror-emacs#4394c03858f27053f8768258e9493866e06e938e",
"@replit/codemirror-indentation-markers": "overleaf/codemirror-indentation-markers#78264032eb286bc47871569ae87bff5ca1c6c161",
"@replit/codemirror-vim": "overleaf/codemirror-vim#1bef138382d948018f3f9b8a4d7a70ab61774e4b",