diff --git a/services/web/app/views/contact-us-modal.jade b/services/web/app/views/contact-us-modal.jade index dade3a7730..32e096b7d5 100644 --- a/services/web/app/views/contact-us-modal.jade +++ b/services/web/app/views/contact-us-modal.jade @@ -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. \ No newline at end of file + p #{translate("request_sent_thank_you")} \ No newline at end of file diff --git a/services/web/app/views/wiki/page.jade b/services/web/app/views/wiki/page.jade index 054697cee9..6a6bea2202 100644 --- a/services/web/app/views/wiki/page.jade +++ b/services/web/app/views/wiki/page.jade @@ -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} \ No newline at end of file + | !{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")} + diff --git a/services/web/public/coffee/analytics/AbTestingManager.coffee b/services/web/public/coffee/analytics/AbTestingManager.coffee index 53524c8d5d..950f4f89f8 100644 --- a/services/web/public/coffee/analytics/AbTestingManager.coffee +++ b/services/web/public/coffee/analytics/AbTestingManager.coffee @@ -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) diff --git a/services/web/public/coffee/main.coffee b/services/web/public/coffee/main.coffee index 40c6bd753d..d85d89cfe8 100644 --- a/services/web/public/coffee/main.coffee +++ b/services/web/public/coffee/main.coffee @@ -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" diff --git a/services/web/public/coffee/main/learn.coffee b/services/web/public/coffee/main/learn.coffee new file mode 100644 index 0000000000..57053bd4fa --- /dev/null +++ b/services/web/public/coffee/main/learn.coffee @@ -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(//) + 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() diff --git a/services/web/public/coffee/main/templates.coffee b/services/web/public/coffee/main/templates.coffee new file mode 100644 index 0000000000..3d05d4ea0f --- /dev/null +++ b/services/web/public/coffee/main/templates.coffee @@ -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(//) + 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 \ No newline at end of file diff --git a/services/web/public/stylesheets/app/wiki.less b/services/web/public/stylesheets/app/wiki.less index cd4022dd89..210230989c 100644 --- a/services/web/public/stylesheets/app/wiki.less +++ b/services/web/public/stylesheets/app/wiki.less @@ -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); + } + } + } \ No newline at end of file