From 5125aa0089ebd0896d8d3b73f0c362c1b438c139 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Jan 2016 13:37:11 +0000 Subject: [PATCH 1/4] Make templates a premium feature --- .../Project/ProjectEditorHandler.coffee | 8 ++- services/web/app/coffee/models/User.coffee | 2 + .../project/editor/publish-template.jade | 66 ++++++++++++++----- services/web/config/settings.defaults.coffee | 2 + 4 files changed, 62 insertions(+), 16 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee index 338c660c0c..f12a7d548e 100644 --- a/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee +++ b/services/web/app/coffee/Features/Project/ProjectEditorHandler.coffee @@ -26,6 +26,8 @@ module.exports = ProjectEditorHandler = dropbox:false compileTimeout: 60 compileGroup:"standard" + templates: false + references: false if project.owner_ref.features? if project.owner_ref.features.collaborators? @@ -37,7 +39,11 @@ module.exports = ProjectEditorHandler = if project.owner_ref.features.compileTimeout? result.features.compileTimeout = project.owner_ref.features.compileTimeout if project.owner_ref.features.compileGroup? - result.features.compileGroup = project.owner_ref.features.compileGroup + result.features.compileGroup = project.owner_ref.features.compileGroup + if project.owner_ref.features.templates? + result.features.templates = project.owner_ref.features.templates + if project.owner_ref.features.references? + result.features.references = project.owner_ref.features.references result.owner = @buildUserModelView project.owner_ref, "owner" diff --git a/services/web/app/coffee/models/User.coffee b/services/web/app/coffee/models/User.coffee index af83318b49..8fca181d0e 100644 --- a/services/web/app/coffee/models/User.coffee +++ b/services/web/app/coffee/models/User.coffee @@ -34,6 +34,8 @@ UserSchema = new Schema github: { type:Boolean, default: Settings.defaultFeatures.github } compileTimeout: { type:Number, default: Settings.defaultFeatures.compileTimeout } compileGroup: { type:String, default: Settings.defaultFeatures.compileGroup } + templates: { type:Boolean, default: Settings.defaultFeatures.templates } + references: { type:Boolean, default: Settings.defaultFeatures.references } } featureSwitches : { pdfng: { type: Boolean } diff --git a/services/web/app/views/project/editor/publish-template.jade b/services/web/app/views/project/editor/publish-template.jade index 7fd2c1a0f4..d1ca335bcd 100644 --- a/services/web/app/views/project/editor/publish-template.jade +++ b/services/web/app/views/project/editor/publish-template.jade @@ -7,25 +7,61 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") ) × h3 #{translate("publish_as_template")} .modal-body.modal-body-share - span(ng-hide="problemTalkingToTemplateApi") - form() - label(for='Description') #{translate("template_description")} - .form-group - textarea.form-control( - rows=5, - name='Description', - ng-model="templateDetails.description", - value="" - ) - div(ng-show="templateDetails.exists").text-center.templateDetails - | #{translate("project_last_published_at")} - strong {{templateDetails.publishedDate}}. - a(ng-href="{{templateDetails.canonicalUrl}}") #{translate("view_in_template_gallery")}. + span(ng-if="project.features.templates") + span(ng-hide="problemTalkingToTemplateApi") + form() + label(for='Description') #{translate("template_description")} + .form-group + textarea.form-control( + rows=5, + name='Description', + ng-model="templateDetails.description", + value="" + ) + div(ng-show="templateDetails.exists").text-center.templateDetails + | #{translate("project_last_published_at")} + strong {{templateDetails.publishedDate}}. + a(ng-href="{{templateDetails.canonicalUrl}}") #{translate("view_in_template_gallery")}. - span(ng-show="problemTalkingToTemplateApi") #{translate("problem_talking_to_publishing_service")}. + span(ng-show="problemTalkingToTemplateApi") #{translate("problem_talking_to_publishing_service")}. + div(ng-hide="project.features.templates") + p #{translate("upgrade_to_get_feature", {feature:"templates"})} + ul.list-unstyled + li + i.fa.fa-check   + | #{translate("unlimited_projects")} + + li + i.fa.fa-check   + | #{translate("collabs_per_proj", {collabcount:'Multiple'})} + + li + i.fa.fa-check   + | #{translate("full_doc_history")} + + li + i.fa.fa-check   + | #{translate("sync_to_dropbox")} + li + i.fa.fa-check   + | #{translate("sync_to_github")} + + li + i.fa.fa-check   + |#{translate("compile_larger_projects")} + + p(ng-controller="FreeTrialModalController").text-center + a.btn.btn-success( + href + ng-class="buttonClass" + ng-click="startFreeTrial('templates')" + ) #{translate("start_free_trial")} + + p.small(ng-show="startedFreeTrial") + | #{translate("refresh_page_after_starting_free_trial")} .modal-footer(ng-hide="problemTalkingToTemplateApi") button.btn.btn-default( diff --git a/services/web/config/settings.defaults.coffee b/services/web/config/settings.defaults.coffee index 9f47f33a9f..cdfe451c1a 100644 --- a/services/web/config/settings.defaults.coffee +++ b/services/web/config/settings.defaults.coffee @@ -143,6 +143,8 @@ module.exports = versioning: true compileTimeout: 60 compileGroup: "standard" + references: true + templates: true plans: plans = [{ planCode: "personal" From ed5872702ac2b072b083194b10667ffe1b2ffc37 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Jan 2016 14:17:01 +0000 Subject: [PATCH 2/4] Pass image to wordcount end point in CLSI --- .../app/coffee/Features/Compile/ClsiManager.coffee | 5 ++++- .../UnitTests/coffee/Compile/ClsiManagerTests.coffee | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Compile/ClsiManager.coffee b/services/web/app/coffee/Features/Compile/ClsiManager.coffee index fd65454054..83eb72fcf7 100755 --- a/services/web/app/coffee/Features/Compile/ClsiManager.coffee +++ b/services/web/app/coffee/Features/Compile/ClsiManager.coffee @@ -111,8 +111,11 @@ module.exports = ClsiManager = ClsiManager._buildRequest project_id, options, (error, req) -> compilerUrl = ClsiManager._getCompilerUrl(options?.compileGroup) filename = file || req?.compile?.rootResourcePath + wordcount_url = "#{compilerUrl}/project/#{project_id}/wordcount?file=#{encodeURIComponent(filename)}" + if req.compile.options.imageName? + wordcount_url += "&image=#{encodeURIComponent(req.compile.options.imageName)}" request.get { - url: "#{compilerUrl}/project/#{project_id}/wordcount?file=#{filename}" + url: wordcount_url }, (error, response, body) -> return callback(error) if error? if 200 <= response.statusCode < 300 diff --git a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee index e47f72daca..00e02af13e 100644 --- a/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee +++ b/services/web/test/UnitTests/coffee/Compile/ClsiManagerTests.coffee @@ -266,7 +266,7 @@ describe "ClsiManager", -> describe "wordCount", -> beforeEach -> @request.get = sinon.stub().callsArgWith(1, null, {statusCode: 200}, @body = { mock: "foo" }) - @ClsiManager._buildRequest = sinon.stub().callsArgWith(2, null, { compile: { rootResourcePath: "rootfile.text" } }) + @ClsiManager._buildRequest = sinon.stub().callsArgWith(2, null, @req = { compile: { rootResourcePath: "rootfile.text", options: {} } }) @ClsiManager._getCompilerUrl = sinon.stub().returns "compiler.url" describe "with root file", -> @@ -289,3 +289,13 @@ describe "ClsiManager", -> @request.get .calledWith({ url: "compiler.url/project/#{@project_id}/wordcount?file=main.tex" }) .should.equal true + + describe "with image", -> + beforeEach -> + @req.compile.options.imageName = @image = "example.com/mock/image" + @ClsiManager.wordCount @project_id, "main.tex", {}, @callback + + it "should call wordCount with file and image", -> + @request.get + .calledWith({ url: "compiler.url/project/#{@project_id}/wordcount?file=main.tex&image=#{encodeURIComponent(@image)}" }) + .should.equal true From 38876a9d4c044546089ad57e620f667950cf3b29 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Jan 2016 16:10:50 +0000 Subject: [PATCH 3/4] Don't show publish buttons when showing free trial for templates --- .../project/editor/publish-template.jade | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/services/web/app/views/project/editor/publish-template.jade b/services/web/app/views/project/editor/publish-template.jade index d1ca335bcd..c89aeebe6d 100644 --- a/services/web/app/views/project/editor/publish-template.jade +++ b/services/web/app/views/project/editor/publish-template.jade @@ -6,8 +6,8 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") ng-click="cancel()" ) × h3 #{translate("publish_as_template")} - .modal-body.modal-body-share - span(ng-if="project.features.templates") + div(ng-if="project.features.templates") + .modal-body.modal-body-share span(ng-hide="problemTalkingToTemplateApi") form() label(for='Description') #{translate("template_description")} @@ -24,8 +24,32 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") a(ng-href="{{templateDetails.canonicalUrl}}") #{translate("view_in_template_gallery")}. span(ng-show="problemTalkingToTemplateApi") #{translate("problem_talking_to_publishing_service")}. + + .modal-footer(ng-hide="problemTalkingToTemplateApi") + button.btn.btn-default( + ng-click="cancel()", + ng-disabled="state.publishInflight || state.unpublishInflight" + ) + span #{translate("cancel")} - div(ng-hide="project.features.templates") + button.btn.btn-info( + ng-click="unpublishTemplate()", + ng-disabled="state.publishInflight || state.unpublishInflight" + ng-show="templateDetails.exists" + ) + span(ng-show="!state.unpublishInflight") #{translate("unpublish")} + span(ng-show="state.unpublishInflight") #{translate("unpublishing")}... + + button.btn.btn-primary( + ng-click="publishTemplate()", + ng-disabled="state.publishInflight || state.unpublishInflight" + ) + span(ng-show="!state.publishInflight && !templateDetails.exists") #{translate("publish")} + span(ng-show="!state.publishInflight && templateDetails.exists") #{translate("republish")} + span(ng-show="state.publishInflight") #{translate("publishing")}... + + div(ng-hide="project.features.templates") + .modal-body.modal-body-share p #{translate("upgrade_to_get_feature", {feature:"templates"})} ul.list-unstyled @@ -52,36 +76,14 @@ script(type="text/ng-template", id="publishProjectAsTemplateModalTemplate") li i.fa.fa-check   |#{translate("compile_larger_projects")} - - p(ng-controller="FreeTrialModalController").text-center + + .modal-footer(ng-controller="FreeTrialModalController") + .text-center a.btn.btn-success( href ng-class="buttonClass" ng-click="startFreeTrial('templates')" ) #{translate("start_free_trial")} - p.small(ng-show="startedFreeTrial") - | #{translate("refresh_page_after_starting_free_trial")} - - .modal-footer(ng-hide="problemTalkingToTemplateApi") - button.btn.btn-default( - ng-click="cancel()", - ng-disabled="state.publishInflight || state.unpublishInflight" - ) - span #{translate("cancel")} - - button.btn.btn-info( - ng-click="unpublishTemplate()", - ng-disabled="state.publishInflight || state.unpublishInflight" - ng-show="templateDetails.exists" - ) - span(ng-show="!state.unpublishInflight") #{translate("unpublish")} - span(ng-show="state.unpublishInflight") #{translate("unpublishing")}... - - button.btn.btn-primary( - ng-click="publishTemplate()", - ng-disabled="state.publishInflight || state.unpublishInflight" - ) - span(ng-show="!state.publishInflight && !templateDetails.exists") #{translate("publish")} - span(ng-show="!state.publishInflight && templateDetails.exists") #{translate("republish")} - span(ng-show="state.publishInflight") #{translate("publishing")}... \ No newline at end of file + .row-spaced-small.small(ng-show="startedFreeTrial") + | #{translate("refresh_page_after_starting_free_trial")} From bcb9e1180b9a2f386a5401c8280da6ab8595b03a Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 20 Jan 2016 11:56:08 +0000 Subject: [PATCH 4/4] Add jobs page --- .../web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee b/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee index f1079cc5b7..f1f55814c7 100644 --- a/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee +++ b/services/web/app/coffee/Features/StaticPages/StaticPagesRouter.coffee @@ -13,6 +13,7 @@ module.exports = webRouter.get '/privacy_policy', HomeController.externalPage("privacy", "Privacy Policy") webRouter.get '/planned_maintenance', HomeController.externalPage("planned_maintenance", "Planned Maintenance") webRouter.get '/style', HomeController.externalPage("style_guide", "Style Guide") + webRouter.get '/jobs', HomeController.externalPage("jobs", "Jobs") webRouter.get '/dropbox', HomeController.externalPage("dropbox", "Dropbox and ShareLaTeX")