mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-07 20:31:06 -05:00
Merge pull request #4956 from overleaf/jpa-jk-contact-form-de-ng
[web] de-ng contact form GitOrigin-RevId: 8a92b37163555d6466e4b8c565f1ef490f73d49a
This commit is contained in:
parent
267b7fc17d
commit
7919017118
6 changed files with 135 additions and 5 deletions
|
@ -121,7 +121,7 @@ html(
|
|||
if (typeof(suppressFooter) == "undefined")
|
||||
include layout/footer-marketing
|
||||
|
||||
!= moduleIncludes("contactModal", locals)
|
||||
!= moduleIncludes("contactModal-marketing", locals)
|
||||
|
||||
block foot-scripts
|
||||
each file in entrypointScripts(entrypoint)
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import _ from 'lodash'
|
||||
import AlgoliaSearch from 'algoliasearch'
|
||||
import getMeta from '../../utils/meta'
|
||||
|
||||
let wikiIdx
|
||||
export async function searchWiki(...args) {
|
||||
if (!wikiIdx) {
|
||||
const algoliaConfig = getMeta('ol-algolia')
|
||||
const wikiIndex = _.get(algoliaConfig, 'indexes.wiki')
|
||||
if (wikiIndex) {
|
||||
const client = AlgoliaSearch(algoliaConfig.appId, algoliaConfig.apiKey)
|
||||
wikiIdx = client.initIndex(wikiIndex)
|
||||
}
|
||||
}
|
||||
if (!wikiIdx) {
|
||||
return { hits: [], nbHits: 0, nbPages: 0 }
|
||||
}
|
||||
return wikiIdx.search(...args)
|
||||
}
|
12
services/web/frontend/js/features/contact-form/index.js
Normal file
12
services/web/frontend/js/features/contact-form/index.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { setupSearch } from './search'
|
||||
|
||||
document
|
||||
.querySelectorAll('[data-ol-contact-form-with-search]')
|
||||
.forEach(setupSearch)
|
||||
|
||||
document.querySelectorAll('a[ng-click="contactUsModal()"]').forEach(el => {
|
||||
el.addEventListener('click', function (e) {
|
||||
e.preventDefault()
|
||||
$('[data-ol-contact-form-modal]').modal()
|
||||
})
|
||||
})
|
86
services/web/frontend/js/features/contact-form/search.js
Normal file
86
services/web/frontend/js/features/contact-form/search.js
Normal file
|
@ -0,0 +1,86 @@
|
|||
import _ from 'lodash'
|
||||
import { searchWiki } from '../algolia-search/search-wiki'
|
||||
import { sendMB } from '../../infrastructure/event-tracking'
|
||||
|
||||
function formatHit(hit) {
|
||||
const pageUnderscored = hit.pageName.replace(/\s/g, '_')
|
||||
const pageSlug = encodeURIComponent(pageUnderscored)
|
||||
const pagePath = hit.kb ? 'how-to' : 'latex'
|
||||
|
||||
let pageAnchor = ''
|
||||
let pageName = hit._highlightResult.pageName.value
|
||||
if (hit.sectionName) {
|
||||
pageAnchor = `#${hit.sectionName.replace(/\s/g, '_')}`
|
||||
pageName += ' - ' + hit.sectionName
|
||||
}
|
||||
|
||||
const url = `/learn/${pagePath}/${pageSlug}${pageAnchor}`
|
||||
return { url, pageName }
|
||||
}
|
||||
|
||||
export function setupSearch(formEl) {
|
||||
const inputEl = formEl.querySelector('[name="subject"]')
|
||||
const resultsEl = formEl.querySelector('[data-ol-search-results]')
|
||||
const wrapperEl = formEl.querySelector('[data-ol-search-results-wrapper]')
|
||||
|
||||
let lastValue = ''
|
||||
function hideResults() {
|
||||
wrapperEl.setAttribute('hidden', '')
|
||||
}
|
||||
function showResults() {
|
||||
wrapperEl.removeAttribute('hidden')
|
||||
}
|
||||
|
||||
async function handleChange() {
|
||||
const value = inputEl.value
|
||||
if (value === lastValue) return
|
||||
lastValue = value
|
||||
if (value.length < 3) {
|
||||
hideResults()
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const { hits, nbHits } = await searchWiki(value, {
|
||||
hitsPerPage: 3,
|
||||
typoTolerance: 'strict',
|
||||
})
|
||||
resultsEl.innerText = ''
|
||||
|
||||
for (const hit of hits) {
|
||||
const { url, pageName } = formatHit(hit)
|
||||
const liEl = document.createElement('li')
|
||||
|
||||
const linkEl = document.createElement('a')
|
||||
linkEl.className = 'contact-suggestion-list-item'
|
||||
linkEl.href = url
|
||||
linkEl.target = '_blank'
|
||||
liEl.append(linkEl)
|
||||
|
||||
const contentEl = document.createElement('span')
|
||||
contentEl.innerHTML = pageName
|
||||
linkEl.append(contentEl)
|
||||
|
||||
const iconEl = document.createElement('i')
|
||||
iconEl.className = 'fa fa-angle-right'
|
||||
iconEl.setAttribute('aria-hidden', 'true')
|
||||
linkEl.append(contentEl)
|
||||
|
||||
resultsEl.append(liEl)
|
||||
}
|
||||
if (nbHits > 0) {
|
||||
showResults()
|
||||
sendMB('contact-form-suggestions-shown')
|
||||
} else {
|
||||
hideResults()
|
||||
}
|
||||
} catch (e) {
|
||||
hideResults()
|
||||
}
|
||||
}
|
||||
|
||||
inputEl.addEventListener('input', _.debounce(handleChange, 350))
|
||||
|
||||
// display initial results
|
||||
handleChange()
|
||||
}
|
|
@ -26,6 +26,7 @@ function formSubmitHelper(formEl) {
|
|||
const captchaResponse = await validateCaptcha(formEl)
|
||||
|
||||
const data = await sendFormRequest(formEl, captchaResponse)
|
||||
formEl.dispatchEvent(new Event('sent'))
|
||||
|
||||
// Handle redirects. From poking around, this still appears to be the
|
||||
// "correct" way of handling redirects with fetch
|
||||
|
@ -110,16 +111,27 @@ function formInflightHelper(el) {
|
|||
disabledEl.disabled = false
|
||||
toggleDisplay(showWhenInflightEl, showWhenNotInflightEl)
|
||||
})
|
||||
}
|
||||
|
||||
function toggleDisplay(hideEl, showEl) {
|
||||
hideEl.setAttribute('hidden', '')
|
||||
showEl.removeAttribute('hidden')
|
||||
}
|
||||
function formSentHelper(el) {
|
||||
const showWhenPending = el.querySelector('[data-ol-not-sent]')
|
||||
const showWhenDone = el.querySelector('[data-ol-sent]')
|
||||
if (!showWhenDone) return
|
||||
|
||||
el.addEventListener('sent', () => {
|
||||
toggleDisplay(showWhenPending, showWhenDone)
|
||||
})
|
||||
}
|
||||
|
||||
function toggleDisplay(hideEl, showEl) {
|
||||
hideEl.setAttribute('hidden', '')
|
||||
showEl.removeAttribute('hidden')
|
||||
}
|
||||
|
||||
export function hydrateForm(el) {
|
||||
formSubmitHelper(el)
|
||||
formInflightHelper(el)
|
||||
formSentHelper(el)
|
||||
}
|
||||
|
||||
document.querySelectorAll(`[data-ol-form]`).forEach(form => hydrateForm(form))
|
||||
|
|
|
@ -2,5 +2,6 @@ import './utils/webpack-public-path'
|
|||
import 'jquery'
|
||||
import 'bootstrap'
|
||||
import './features/form-helpers/hydrate-form'
|
||||
import './features/contact-form'
|
||||
|
||||
$('[data-ol-lang-selector-tooltip]').tooltip({ trigger: 'hover' })
|
||||
|
|
Loading…
Reference in a new issue