mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge branch 'templatessearch'
This commit is contained in:
commit
e9478e0843
7 changed files with 243 additions and 17 deletions
|
@ -5,26 +5,26 @@ script(type='text/ng-template', id='supportModalTemplate')
|
|||
data-dismiss="modal"
|
||||
ng-click="close()"
|
||||
) ×
|
||||
h3 Contact Us
|
||||
h3 #{translate("contact_us")}
|
||||
.modal-body.contact-us-modal
|
||||
span(ng-show="sent == false")
|
||||
label
|
||||
| Subject
|
||||
| #{translate("subject")}
|
||||
.form-group
|
||||
input.field.text.medium.span8.form-control(ng-model="form.subject", maxlength='255', tabindex='1', onkeyup='')
|
||||
label.desc
|
||||
| Email
|
||||
| #{translate("email")}
|
||||
.form-group
|
||||
input.field.text.medium.span8.form-control(ng-model="form.email", ng-init="form.email = '#{getUserEmail()}'", type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
|
||||
label#title12.desc
|
||||
| Project URL (optional)
|
||||
| #{translate("project_url")} (#{translate("optional")})
|
||||
.form-group
|
||||
input.field.text.medium.span8.form-control(ng-model="form.project_url", tabindex='3', onkeyup='')
|
||||
label.desc
|
||||
| Message
|
||||
| #{translate("suggestion")}
|
||||
.form-group
|
||||
textarea.field.text.medium.span8.form-control(ng-model="form.message",type='text', value='', maxlength='255', tabindex='4', onkeyup='')
|
||||
.form-group.text-center
|
||||
input.btn-success.btn.btn-lg(type='submit', ng-disabled="sending", ng-click="contactUs()" value='Get in Touch')
|
||||
input.btn-success.btn.btn-lg(type='submit', ng-disabled="sending", ng-click="contactUs()" value='#{translate("contact_us")}')
|
||||
span(ng-show="sent")
|
||||
p Request Sent, Thank you.
|
||||
p #{translate("request_sent_thank_you")}
|
|
@ -1,14 +1,68 @@
|
|||
extends ../layout
|
||||
|
||||
block content
|
||||
.content.content-alt(ng-non-bindable)
|
||||
.content.content-alt(ng-cloak)
|
||||
.container.wiki
|
||||
.row.template-page-header
|
||||
.col-md-8(ng-cloak)
|
||||
|
||||
.row
|
||||
.col-xs-3.contents
|
||||
.col-xs-3.contents(ng-non-bindable)
|
||||
| !{contents.content}
|
||||
|
||||
.col-xs-9.page
|
||||
.card
|
||||
- if(typeof(settings.algolia) != "undefined" && typeof(settings.algolia.indexes) != "undefined" && typeof(settings.algolia.indexes.wiki) != "undefined")
|
||||
span(ng-controller="SearchWikiController")
|
||||
.row
|
||||
form.project-search.form-horizontal.col-md-9(role="form")
|
||||
.form-group.has-feedback.has-feedback-left.col-md-12
|
||||
input.form-control.col-md-12(type='text', ng-model='searchQueryText', ng-keyup='search()', placeholder="Search help library....")
|
||||
i.fa.fa-search.form-control-feedback-left
|
||||
i.fa.fa-times.form-control-feedback(
|
||||
ng-click="clearSearchText()",
|
||||
style="cursor: pointer;",
|
||||
ng-show="searchQueryText.length > 0"
|
||||
)
|
||||
.col-md-3.text-right
|
||||
a.btn.btn-primary(ng-click="showMissingTemplateModal()") #{translate("suggest_new_doc")}
|
||||
|
||||
.row
|
||||
.col-md-12(ng-cloak)
|
||||
a(ng-href='{{hit.url}}',ng-repeat='hit in hits').search-result.card.card-thin
|
||||
span(ng-bind-html='hit.name')
|
||||
div.search-result-content(ng-show="hit.content != ''", ng-bind-html='hit.content')
|
||||
|
||||
.card.row-spaced(ng-non-bindable)
|
||||
.page-header
|
||||
h1 #{title}
|
||||
|
||||
| !{page.content}
|
||||
| !{page.content}
|
||||
|
||||
|
||||
|
||||
|
||||
script(type="text/ng-template", id="missingWikiPageModal")
|
||||
.modal-header
|
||||
button.close(
|
||||
type="button"
|
||||
data-dismiss="modal"
|
||||
ng-click="close()"
|
||||
) ×
|
||||
h3 #{translate("suggest_new_doc")}
|
||||
.modal-body.contact-us-modal
|
||||
span(ng-show="sent == false")
|
||||
label.desc
|
||||
| #{translate("email")} (#{translate("optional")})
|
||||
.form-group
|
||||
input.field.text.medium.span8.form-control(ng-model="form.email", ng-init="form.email = '#{getUserEmail()}'", type='email', spellcheck='false', value='', maxlength='255', tabindex='2')
|
||||
label.desc
|
||||
| #{translate("suggestion")}
|
||||
.form-group
|
||||
textarea.field.text.medium.span8.form-control(ng-model="form.message",type='text', value='', maxlength='255', tabindex='4', onkeyup='')
|
||||
span(ng-show="sent")
|
||||
p #{translate("request_sent_thank_you")}
|
||||
.modal-footer
|
||||
button.btn.btn-default(ng-click="close()")
|
||||
span #{translate("dismiss")}
|
||||
button.btn-success.btn(type='submit', ng-disabled="sending", ng-click="contactUs()") #{translate("contact_us")}
|
||||
|
||||
|
|
|
@ -22,24 +22,20 @@ define [
|
|||
|
||||
_buildCookieKey = (testName, bucket)->
|
||||
key = "sl_abt_#{testName}_#{bucket}"
|
||||
#console.log key
|
||||
return key
|
||||
|
||||
|
||||
_getTestCookie = (testName, bucket)->
|
||||
cookieKey = _buildCookieKey(testName, bucket)
|
||||
cookie = ipCookie(cookieKey)
|
||||
#console.log cookieKey, cookie
|
||||
return cookie
|
||||
|
||||
_persistCookieStep = (testName, bucket, newStep)->
|
||||
cookieKey = _buildCookieKey(testName, bucket)
|
||||
ipCookie(cookieKey, {step:newStep}, {expires:100, path:"/"})
|
||||
#console.log("persisting", cookieKey, {step:newStep})
|
||||
ga('send', 'event', 'ab_tests', "#{testName}:#{bucket}", "step-#{newStep}")
|
||||
|
||||
_checkIfStepIsNext = (cookieStep, newStep)->
|
||||
#console.log cookieStep, newStep, "checking if step is next"
|
||||
if !cookieStep? and newStep != 0
|
||||
return false
|
||||
else if newStep == 0
|
||||
|
@ -68,8 +64,6 @@ define [
|
|||
bucketIndex = parseInt(hash.toString().slice(0,2), 16) % (buckets?.length or 2)
|
||||
return buckets[bucketIndex]
|
||||
|
||||
|
||||
|
||||
App.controller "AbTestController", ($scope, abTestManager)->
|
||||
testKeys = _.keys(window.ab)
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ define [
|
|||
"main/register-users"
|
||||
"main/subscription/group-subscription-invite-controller"
|
||||
"main/contact-us"
|
||||
"main/learn"
|
||||
"analytics/AbTestingManager"
|
||||
"directives/asyncForm"
|
||||
"directives/stopPropagation"
|
||||
|
|
92
services/web/public/coffee/main/learn.coffee
Normal file
92
services/web/public/coffee/main/learn.coffee
Normal file
|
@ -0,0 +1,92 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
|
||||
App.factory "algoliawiki", ->
|
||||
if window.sharelatex?.algolia? and window.sharelatex.algolia?.indexes?.wiki?
|
||||
client = new AlgoliaSearch(window.sharelatex.algolia?.app_id, window.sharelatex.algolia?.api_key)
|
||||
index = client.initIndex(window.sharelatex.algolia?.indexes?.wiki)
|
||||
return index
|
||||
|
||||
App.controller "SearchWikiController", ($scope, algoliawiki, _, $modal) ->
|
||||
algolia = algoliawiki
|
||||
$scope.hits = []
|
||||
|
||||
$scope.clearSearchText = ->
|
||||
$scope.searchQueryText = ""
|
||||
updateHits []
|
||||
|
||||
$scope.safeApply = (fn)->
|
||||
phase = $scope.$root.$$phase
|
||||
if(phase == '$apply' || phase == '$digest')
|
||||
$scope.$eval(fn)
|
||||
else
|
||||
$scope.$apply(fn)
|
||||
|
||||
buildHitViewModel = (hit)->
|
||||
page_underscored = hit.pageName.replace(/\s/g,'_')
|
||||
section_underscored = hit.sectionName.replace(/\s/g,'_')
|
||||
content = hit._highlightResult.content.value
|
||||
# Replace many new lines
|
||||
content = content.replace(/\n\n+/g, "\n\n")
|
||||
lines = content.split("\n")
|
||||
# Only show the lines that have a highlighted match
|
||||
matching_lines = []
|
||||
for line in lines
|
||||
if !line.match(/^\[edit\]/)
|
||||
content += line + "\n"
|
||||
if line.match(/<em>/)
|
||||
matching_lines.push line
|
||||
content = matching_lines.join("\n...\n")
|
||||
result =
|
||||
name : hit._highlightResult.pageName.value + " - " + hit._highlightResult.sectionName.value
|
||||
url :"/learn/#{page_underscored}##{section_underscored}"
|
||||
content: content
|
||||
return result
|
||||
|
||||
updateHits = (hits)->
|
||||
$scope.safeApply ->
|
||||
$scope.hits = hits
|
||||
|
||||
$scope.search = ->
|
||||
query = $scope.searchQueryText
|
||||
if !query? or query.length == 0
|
||||
updateHits []
|
||||
return
|
||||
|
||||
algolia.search query, (err, response)->
|
||||
if response.hits.length == 0
|
||||
updateHits []
|
||||
else
|
||||
hits = _.map response.hits, buildHitViewModel
|
||||
updateHits hits
|
||||
|
||||
$scope.showMissingTemplateModal = () ->
|
||||
modalInstance = $modal.open(
|
||||
templateUrl: "missingWikiPageModal"
|
||||
controller: "MissingWikiPageController"
|
||||
)
|
||||
|
||||
|
||||
App.controller 'MissingWikiPageController', ($scope, $modalInstance) ->
|
||||
$scope.form = {}
|
||||
$scope.sent = false
|
||||
$scope.sending = false
|
||||
$scope.contactUs = ->
|
||||
if !$scope.form.message?
|
||||
console.log "message not set"
|
||||
return
|
||||
$scope.sending = true
|
||||
ticketNumber = Math.floor((1 + Math.random()) * 0x10000).toString(32)
|
||||
params =
|
||||
email: $scope.form.email or "support@sharelatex.com"
|
||||
message: $scope.form.message or ""
|
||||
subject: "new wiki page sujection - [#{ticketNumber}]"
|
||||
labels: "support wiki"
|
||||
|
||||
Groove.createTicket params, (err, json)->
|
||||
$scope.sent = true
|
||||
$scope.$apply()
|
||||
|
||||
$scope.close = () ->
|
||||
$modalInstance.close()
|
62
services/web/public/coffee/main/templates.coffee
Normal file
62
services/web/public/coffee/main/templates.coffee
Normal file
|
@ -0,0 +1,62 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
|
||||
App.factory "algoliawiki", ->
|
||||
if window.sharelatex?.algolia? and window.sharelatex.algolia?.indexes?.wiki?
|
||||
client = new AlgoliaSearch(window.sharelatex.algolia?.app_id, window.sharelatex.algolia?.api_key)
|
||||
index = client.initIndex(window.sharelatex.algolia?.indexes?.wiki)
|
||||
return index
|
||||
|
||||
App.controller "SearchWikiController", ($scope, algoliawiki, _) ->
|
||||
algolia = algoliawiki
|
||||
$scope.hits = []
|
||||
|
||||
$scope.clearSearchText = ->
|
||||
$scope.searchQueryText = ""
|
||||
updateHits []
|
||||
|
||||
$scope.safeApply = (fn)->
|
||||
phase = $scope.$root.$$phase
|
||||
if(phase == '$apply' || phase == '$digest')
|
||||
$scope.$eval(fn)
|
||||
else
|
||||
$scope.$apply(fn)
|
||||
|
||||
buildHitViewModel = (hit)->
|
||||
page_underscored = hit.pageName.replace(/\s/g,'_')
|
||||
section_underscored = hit.sectionName.replace(/\s/g,'_')
|
||||
content = hit._highlightResult.content.value
|
||||
# Replace many new lines
|
||||
content = content.replace(/\n\n+/g, "\n\n")
|
||||
lines = content.split("\n")
|
||||
# Only show the lines that have a highlighted match
|
||||
matching_lines = []
|
||||
for line in lines
|
||||
if !line.match(/^\[edit\]/)
|
||||
content += line + "\n"
|
||||
if line.match(/<em>/)
|
||||
matching_lines.push line
|
||||
content = matching_lines.join("\n...\n")
|
||||
result =
|
||||
name : hit._highlightResult.pageName.value + " - " + hit._highlightResult.sectionName.value
|
||||
url :"/learn/#{page_underscored}##{section_underscored}"
|
||||
content: content
|
||||
return result
|
||||
|
||||
updateHits = (hits)->
|
||||
$scope.safeApply ->
|
||||
$scope.hits = hits
|
||||
|
||||
$scope.search = ->
|
||||
query = $scope.searchQueryText
|
||||
if !query? or query.length == 0
|
||||
updateHits []
|
||||
return
|
||||
|
||||
algolia.search query, (err, response)->
|
||||
if response.hits.length == 0
|
||||
updateHits []
|
||||
else
|
||||
hits = _.map response.hits, buildHitViewModel
|
||||
updateHits hits
|
|
@ -104,4 +104,27 @@
|
|||
|
||||
/*]]>*/
|
||||
|
||||
a.search-result {
|
||||
display: block;
|
||||
margin-top: @line-height-computed / 2;
|
||||
.search-result-content {
|
||||
margin-top: @line-height-computed / 4;
|
||||
white-space: pre-wrap;
|
||||
font-size: 0.8em;
|
||||
color: @gray-dark;
|
||||
em {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover, &:active, &:focus {
|
||||
text-decoration: none;
|
||||
.search-result-content {
|
||||
color: @gray-darker;
|
||||
|
||||
}
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.35);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue