From f6bbf7fe3f03b9ba7738b2b57e9602ab893fe3fb Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 25 Oct 2017 09:13:17 +0100 Subject: [PATCH 01/45] wip --- .../Features/Project/OlProjectGetter.coffee | 18 ++++++++++++++++++ .../Features/Project/ProjectController.coffee | 6 ++++++ 2 files changed, 24 insertions(+) create mode 100644 services/web/app/coffee/Features/Project/OlProjectGetter.coffee diff --git a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee new file mode 100644 index 0000000000..06eb1be0be --- /dev/null +++ b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee @@ -0,0 +1,18 @@ +request = require 'request' +settings = require 'settings-sharelatex' +Errors = require '../Errors/Errors' + +makeRequest = (opts, callback) -> + if settings.apis?.olProjects?.url? + urlPath = opts.url + opts.url = "#{settings.apis.olProjects.url}#{urlPath}" + request opts, callback + else + callback(new Errors.ServiceNotConfiguredError('OL Projects service not configured')) + +module.exports = OlProjectGetter = + findAllUsersProjects: (userId, callback = (error, projects) ->) -> + opts = + method: 'GET' + url: '/api/v0/current_user' + json: true \ No newline at end of file diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index ff20664c43..a586dddb94 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -1,5 +1,6 @@ async = require("async") logger = require("logger-sharelatex") +Settings = require('settings-sharelatex') projectDeleter = require("./ProjectDeleter") projectDuplicator = require("./ProjectDuplicator") projectCreationHandler = require("./ProjectCreationHandler") @@ -148,6 +149,11 @@ module.exports = ProjectController = NotificationsHandler.getUserNotifications user_id, cb projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb + olProjects: (cb) -> + console.log('OOOOOOOOOOOOOOOOOOOOOOO') + if Settings.brandPrefix == "ol-" + OlProjectGetter.findAllUsersProjects user_id, cb + cb() hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> From fa0559f8d76a0273f7a15927dd3029c37ebf94c3 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 09:42:12 +0000 Subject: [PATCH 02/45] Fetch OL projects using OAuth --- .../coffee/Features/Project/OlProjectGetter.coffee | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee index 06eb1be0be..3f47c0dac4 100644 --- a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee +++ b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee @@ -1,6 +1,8 @@ request = require 'request' settings = require 'settings-sharelatex' +logger = require 'logger-sharelatex' Errors = require '../Errors/Errors' +oAuthRequest = require '../../../../modules/overleaf-integration-web-module/app/coffee/oauth/OAuthRequest' makeRequest = (opts, callback) -> if settings.apis?.olProjects?.url? @@ -12,7 +14,11 @@ makeRequest = (opts, callback) -> module.exports = OlProjectGetter = findAllUsersProjects: (userId, callback = (error, projects) ->) -> - opts = + oAuthRequest userId, { + url: "#{settings.overleaf.host}/api/v1/sharelatex/docs" method: 'GET' - url: '/api/v0/current_user' - json: true \ No newline at end of file + json: true + }, (error, docs) -> + return callback(error) if error? + logger.log {userId, docs}, "got projects from OL" + callback(null, docs) \ No newline at end of file From 8c66342a0419a9577544e1e68d724ef08e4318a3 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 09:42:44 +0000 Subject: [PATCH 03/45] Pull in OL projects and process for view --- .../Features/Project/ProjectController.coffee | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index a586dddb94..c8126b10bd 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -18,6 +18,7 @@ fs = require "fs" InactiveProjectManager = require("../InactiveData/InactiveProjectManager") ProjectUpdateHandler = require("./ProjectUpdateHandler") ProjectGetter = require("./ProjectGetter") +OlProjectGetter = require("./OlProjectGetter") PrivilegeLevels = require("../Authorization/PrivilegeLevels") AuthenticationController = require("../Authentication/AuthenticationController") PackageVersions = require("../../infrastructure/PackageVersions") @@ -150,10 +151,10 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb olProjects: (cb) -> - console.log('OOOOOOOOOOOOOOOOOOOOOOO') if Settings.brandPrefix == "ol-" OlProjectGetter.findAllUsersProjects user_id, cb - cb() + else + cb() hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> @@ -167,7 +168,7 @@ module.exports = ProjectController = notifications = require("underscore").map results.notifications, (notification)-> notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts) return notification - projects = ProjectController._buildProjectList results.projects + projects = ProjectController._buildProjectList results.projects, results.olProjects.projects user = results.user ProjectController._injectProjectOwners projects, (error, projects) -> return next(error) if error? @@ -396,7 +397,7 @@ module.exports = ProjectController = showLinkSharingOnboarding: showLinkSharingOnboarding timer.done() - _buildProjectList: (allProjects)-> + _buildProjectList: (allProjects, olProjects = [])-> {owned, readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly} = allProjects projects = [] for project in owned @@ -406,6 +407,8 @@ module.exports = ProjectController = projects.push ProjectController._buildProjectViewModel(project, "readWrite", Sources.INVITE) for project in readOnly projects.push ProjectController._buildProjectViewModel(project, "readOnly", Sources.INVITE) + for project in olProjects + projects.push ProjectController._buildOlProjectViwModel(project) # Token-access # Only add these projects if they're not already present, this gives us cascading access # from 'owner' => 'token-read-only' @@ -433,6 +436,18 @@ module.exports = ProjectController = } return model + _buildOlProjectViewModel: (project) -> + { + id: project.id + name: project.title + lastUpdated: project.updated_at +# publicAccessLevel: +# accessLevel: + archived: project.archived +# owner_ref: + isOLProject: true + } + _injectProjectOwners: (projects, callback = (error, projects) ->) -> users = {} for project in projects From d072fabb25618d693b2dcaac02167dec62e15701 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 11:26:54 +0000 Subject: [PATCH 04/45] Fix non-beta throwing error because it's expecting OL projects --- .../web/app/coffee/Features/Project/ProjectController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index c8126b10bd..fca884f371 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -168,7 +168,7 @@ module.exports = ProjectController = notifications = require("underscore").map results.notifications, (notification)-> notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts) return notification - projects = ProjectController._buildProjectList results.projects, results.olProjects.projects + projects = ProjectController._buildProjectList results.projects, results.olProjects?.projects user = results.user ProjectController._injectProjectOwners projects, (error, projects) -> return next(error) if error? From 532a26c68f5175e79dad496da14ca690ee12aecc Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 11:27:24 +0000 Subject: [PATCH 05/45] Extract out project list item to template and add OL-specific template --- services/web/app/views/project/list/item.pug | 40 +++++++++++++++ .../web/app/views/project/list/ol-item.pug | 11 ++++ .../app/views/project/list/project-list.pug | 50 ++++--------------- 3 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 services/web/app/views/project/list/item.pug create mode 100644 services/web/app/views/project/list/ol-item.pug diff --git a/services/web/app/views/project/list/item.pug b/services/web/app/views/project/list/item.pug new file mode 100644 index 0000000000..f246ad34d4 --- /dev/null +++ b/services/web/app/views/project/list/item.pug @@ -0,0 +1,40 @@ +.col-xs-6 + input.select-item( + select-individual, + type="checkbox", + ng-model="project.selected" + stop-propagation="click" + aria-label=translate('select_project') + " '{{ project.name }}'" + ) + span + a.projectName( + ng-href="{{projectLink(project)}}" + stop-propagation="click" + ) {{project.name}} + span( + ng-controller="TagListController" + ) + .tag-label( + ng-repeat='tag in project.tags' + stop-propagation="click" + ) + a.label.label-default.tag-label-name( + href, + ng-click="selectTag(tag)" + ) {{tag.name}} + a.label.label-default.tag-label-remove( + href + ng-click="removeProjectFromTag(project, tag)" + ) × + +.col-xs-2 + span.owner {{ownerName()}} + span(ng-if="isLinkSharingProject(project)") + |   + i.fa.fa-link.small( + tooltip=translate("link_sharing") + tooltip-placement="right" + tooltip-append-to-body="true" + ) +.col-xs-4 + span.last-modified {{project.lastUpdated | formatDate}} \ No newline at end of file diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug new file mode 100644 index 0000000000..be76749706 --- /dev/null +++ b/services/web/app/views/project/list/ol-item.pug @@ -0,0 +1,11 @@ +.col-xs-6 + span + a.projectName( + href="/project/{{project.id}}" + stop-propagation="click" + ) {{project.name}} + +.col-xs-2 + span.owner +.col-xs-4 + span.last-modified \ No newline at end of file diff --git a/services/web/app/views/project/list/project-list.pug b/services/web/app/views/project/list/project-list.pug index aba8ed08be..66103ea3fa 100644 --- a/services/web/app/views/project/list/project-list.pug +++ b/services/web/app/views/project/list/project-list.pug @@ -142,47 +142,15 @@ ng-repeat="project in visibleProjects | orderBy:predicate:reverse", ng-controller="ProjectListItemController" ) - .row(select-row) - .col-xs-6 - input.select-item( - select-individual, - type="checkbox", - ng-model="project.selected" - stop-propagation="click" - aria-label=translate('select_project') + " '{{ project.name }}'" - ) - span - a.projectName( - ng-href="{{projectLink(project)}}" - stop-propagation="click" - ) {{project.name}} - span( - ng-controller="TagListController" - ) - .tag-label( - ng-repeat='tag in project.tags' - stop-propagation="click" - ) - a.label.label-default.tag-label-name( - href, - ng-click="selectTag(tag)" - ) {{tag.name}} - a.label.label-default.tag-label-remove( - href - ng-click="removeProjectFromTag(project, tag)" - ) × - - .col-xs-2 - span.owner {{ownerName()}} - span(ng-if="isLinkSharingProject(project)") - |   - i.fa.fa-link.small( - tooltip=translate("link_sharing") - tooltip-placement="right" - tooltip-append-to-body="true" - ) - .col-xs-4 - span.last-modified {{project.lastUpdated | formatDate}} + .row( + ng-if="!project.isOLProject" + select-row + ) + include ./item + .row( + ng-if="project.isOLProject" + ) + include ./ol-item li( ng-if="visibleProjects.length == 0", ng-cloak From fe90ef047f456c72b33542f18fbdbbc9e1611766 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 11:39:39 +0000 Subject: [PATCH 06/45] Temp OL label --- services/web/app/views/project/list/ol-item.pug | 5 ++--- services/web/public/stylesheets/app/project-list.less | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index be76749706..a43d681b1f 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -1,11 +1,10 @@ -.col-xs-6 +.col-xs-8 + span.label.label-default.ol-label OL span a.projectName( href="/project/{{project.id}}" stop-propagation="click" ) {{project.name}} -.col-xs-2 - span.owner .col-xs-4 span.last-modified \ No newline at end of file diff --git a/services/web/public/stylesheets/app/project-list.less b/services/web/public/stylesheets/app/project-list.less index 1568915296..cde6596303 100644 --- a/services/web/public/stylesheets/app/project-list.less +++ b/services/web/public/stylesheets/app/project-list.less @@ -366,6 +366,12 @@ ul.project-list { border-top-left-radius: 0; border-bottom-left-radius: 0; } + + .ol-label { + margin-right: 9px; + margin-left: 5px; + padding: 2px 3px 1px; + } } i.tablesort { padding-left: 8px; From 9eff01fcc536589177b8f268e08cc6e2766ad236 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 11:52:07 +0000 Subject: [PATCH 07/45] Explcitly depend on moment --- services/web/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/package.json b/services/web/package.json index e831d929e1..b4dd29395d 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -40,6 +40,7 @@ "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", "mimelib": "0.2.14", "mocha": "1.17.1", + "moment": "^2.18.1", "mongojs": "2.4.0", "mongoose": "4.11.4", "multer": "^0.1.8", From fc6da2e2e4a2166ad8cbfce3c3d916af8b2891bc Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 12:27:09 +0000 Subject: [PATCH 08/45] Parse & display OL project last updated --- .../web/app/coffee/Features/Project/ProjectController.coffee | 3 ++- services/web/app/views/project/list/ol-item.pug | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index fca884f371..67d6a8014a 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -1,4 +1,5 @@ async = require("async") +moment = require('moment') logger = require("logger-sharelatex") Settings = require('settings-sharelatex') projectDeleter = require("./ProjectDeleter") @@ -440,7 +441,7 @@ module.exports = ProjectController = { id: project.id name: project.title - lastUpdated: project.updated_at + lastUpdated: moment.unix(project.updated_at) # publicAccessLevel: # accessLevel: archived: project.archived diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index a43d681b1f..c0bf873ce7 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -7,4 +7,4 @@ ) {{project.name}} .col-xs-4 - span.last-modified \ No newline at end of file + span.last-modified {{project.lastUpdated | formatDate}} \ No newline at end of file From 3c8dd6c42185b678eb678cad23407e340bdafad5 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 12:27:19 +0000 Subject: [PATCH 09/45] Link to OL project --- services/web/app/views/project/list/ol-item.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index c0bf873ce7..39741af6aa 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -2,7 +2,7 @@ span.label.label-default.ol-label OL span a.projectName( - href="/project/{{project.id}}" + href=settings.overleaf.host + "/{{project.id}}" stop-propagation="click" ) {{project.name}} From 20c756ec9a09c2524072a0a4f030cce6c69c4b77 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 14:28:35 +0000 Subject: [PATCH 10/45] Switch to v1 wording --- services/web/app/views/project/list/ol-item.pug | 2 +- services/web/public/stylesheets/app/project-list.less | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index 39741af6aa..a5f21e7387 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -1,5 +1,5 @@ .col-xs-8 - span.label.label-default.ol-label OL + span.label.label-default.ol-label V1 span a.projectName( href=settings.overleaf.host + "/{{project.id}}" diff --git a/services/web/public/stylesheets/app/project-list.less b/services/web/public/stylesheets/app/project-list.less index cde6596303..88442147f2 100644 --- a/services/web/public/stylesheets/app/project-list.less +++ b/services/web/public/stylesheets/app/project-list.less @@ -368,7 +368,7 @@ ul.project-list { } .ol-label { - margin-right: 9px; + margin-right: 11px; margin-left: 5px; padding: 2px 3px 1px; } From dfe17d63ba89c7f4ea786d18f1a2375934eab2c2 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 14:29:20 +0000 Subject: [PATCH 11/45] Projects removed also treated as archived --- .../web/app/coffee/Features/Project/ProjectController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 67d6a8014a..78c84f5681 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -444,7 +444,7 @@ module.exports = ProjectController = lastUpdated: moment.unix(project.updated_at) # publicAccessLevel: # accessLevel: - archived: project.archived + archived: project.removed || project.archived # owner_ref: isOLProject: true } From 3f422dc48c93af9fad1733da8417c643e7493904 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 15:07:59 +0000 Subject: [PATCH 12/45] Clean up OL view model --- .../web/app/coffee/Features/Project/ProjectController.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 78c84f5681..9b281617c8 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -442,10 +442,8 @@ module.exports = ProjectController = id: project.id name: project.title lastUpdated: moment.unix(project.updated_at) -# publicAccessLevel: -# accessLevel: + accessLevel: "readOnly", archived: project.removed || project.archived -# owner_ref: isOLProject: true } From 37c7a95fde550827b960745d890c1e4caad518ff Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 15:30:14 +0000 Subject: [PATCH 13/45] Hide V1 projects from shared filter --- .../web/public/coffee/main/project-list/project-list.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/web/public/coffee/main/project-list/project-list.coffee b/services/web/public/coffee/main/project-list/project-list.coffee index 8c39df060f..63e669308c 100644 --- a/services/web/public/coffee/main/project-list/project-list.coffee +++ b/services/web/public/coffee/main/project-list/project-list.coffee @@ -116,6 +116,10 @@ define [ if $scope.filter == "shared" and project.accessLevel == "owner" visible = false + # Hide projects from V1 if we only want to see shared projects + if $scope.filter == "shared" and project.isOLProject + visible = false + # Hide projects we don't own if we only want to see owned projects if $scope.filter == "owned" and project.accessLevel != "owner" visible = false From 7910f2109fd30887a345c69bfbab2138c1f759f0 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 15:32:54 +0000 Subject: [PATCH 14/45] Switch to V1 wording --- .../web/app/coffee/Features/Project/ProjectController.coffee | 3 ++- services/web/app/views/project/list/ol-item.pug | 2 +- services/web/app/views/project/list/project-list.pug | 4 ++-- .../web/public/coffee/main/project-list/project-list.coffee | 2 +- services/web/public/stylesheets/app/project-list.less | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 9b281617c8..ac28dcdf4c 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -434,6 +434,7 @@ module.exports = ProjectController = archived: !!project.archived owner_ref: project.owner_ref tokens: project.tokens + isV1Project: false } return model @@ -444,7 +445,7 @@ module.exports = ProjectController = lastUpdated: moment.unix(project.updated_at) accessLevel: "readOnly", archived: project.removed || project.archived - isOLProject: true + isV1Project: true } _injectProjectOwners: (projects, callback = (error, projects) ->) -> diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index a5f21e7387..49a6dd01f2 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -1,5 +1,5 @@ .col-xs-8 - span.label.label-default.ol-label V1 + span.label.label-default.v1-label V1 span a.projectName( href=settings.overleaf.host + "/{{project.id}}" diff --git a/services/web/app/views/project/list/project-list.pug b/services/web/app/views/project/list/project-list.pug index 66103ea3fa..260cc387f0 100644 --- a/services/web/app/views/project/list/project-list.pug +++ b/services/web/app/views/project/list/project-list.pug @@ -143,12 +143,12 @@ ng-controller="ProjectListItemController" ) .row( - ng-if="!project.isOLProject" + ng-if="!project.isV1Project" select-row ) include ./item .row( - ng-if="project.isOLProject" + ng-if="project.isV1Project" ) include ./ol-item li( diff --git a/services/web/public/coffee/main/project-list/project-list.coffee b/services/web/public/coffee/main/project-list/project-list.coffee index 63e669308c..335f46c62d 100644 --- a/services/web/public/coffee/main/project-list/project-list.coffee +++ b/services/web/public/coffee/main/project-list/project-list.coffee @@ -117,7 +117,7 @@ define [ visible = false # Hide projects from V1 if we only want to see shared projects - if $scope.filter == "shared" and project.isOLProject + if $scope.filter == "shared" and project.isV1Project visible = false # Hide projects we don't own if we only want to see owned projects diff --git a/services/web/public/stylesheets/app/project-list.less b/services/web/public/stylesheets/app/project-list.less index 88442147f2..d3745854c3 100644 --- a/services/web/public/stylesheets/app/project-list.less +++ b/services/web/public/stylesheets/app/project-list.less @@ -367,7 +367,7 @@ ul.project-list { border-bottom-left-radius: 0; } - .ol-label { + .v1-label { margin-right: 11px; margin-left: 5px; padding: 2px 3px 1px; From 5ee52408e57b10d2f0899f0287f1952fe9b6abef Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 16:16:25 +0000 Subject: [PATCH 15/45] Inject v1 flag into view model --- .../web/app/coffee/Features/Project/ProjectController.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index ac28dcdf4c..e441ce6ca1 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -144,6 +144,7 @@ module.exports = ProjectController = timer = new metrics.Timer("project-list") user_id = AuthenticationController.getLoggedInUserId(req) currentUser = AuthenticationController.getSessionUser(req) + isV1 = Settings.brandPrefix == "ol-" async.parallel { tags: (cb)-> TagsHandler.getAllTags user_id, cb @@ -152,7 +153,7 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb olProjects: (cb) -> - if Settings.brandPrefix == "ol-" + if isV1 OlProjectGetter.findAllUsersProjects user_id, cb else cb() @@ -181,6 +182,7 @@ module.exports = ProjectController = notifications: notifications or [] user: user hasSubscription: results.hasSubscription[0] + isV1: isV1 } if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key? From c1b3cc3a69ad8537ad5f929267e573c0a72b9468 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Mon, 30 Oct 2017 16:16:39 +0000 Subject: [PATCH 16/45] Add v1 filter --- services/web/app/views/project/list/side-bar.pug | 3 +++ .../web/public/coffee/main/project-list/project-list.coffee | 3 +++ 2 files changed, 6 insertions(+) diff --git a/services/web/app/views/project/list/side-bar.pug b/services/web/app/views/project/list/side-bar.pug index fe053f0019..33be0f5378 100644 --- a/services/web/app/views/project/list/side-bar.pug +++ b/services/web/app/views/project/list/side-bar.pug @@ -45,6 +45,9 @@ a(href) #{translate("shared_with_you")} li(ng-class="{active: (filter == 'archived')}", ng-click="filterProjects('archived')") a(href) #{translate("deleted_projects")} + if isV1 + li(ng-class="{active: (filter == 'v1')}", ng-click="filterProjects('v1')") + a(href) #{translate("v1_projects")} li.separator h2 #{translate("folders")} li.tag( diff --git a/services/web/public/coffee/main/project-list/project-list.coffee b/services/web/public/coffee/main/project-list/project-list.coffee index 335f46c62d..1d81504c74 100644 --- a/services/web/public/coffee/main/project-list/project-list.coffee +++ b/services/web/public/coffee/main/project-list/project-list.coffee @@ -133,6 +133,9 @@ define [ if project.archived visible = false + if $scope.filter == "v1" and !project.isV1Project + visible = false + if visible $scope.visibleProjects.push project else From 020e8ab8c488661a0c24bce87b9df42d7875aa98 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 31 Oct 2017 09:38:55 +0000 Subject: [PATCH 17/45] Change wording to v1 --- .../web/app/coffee/Features/Project/ProjectController.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index e441ce6ca1..f8c0676938 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -152,7 +152,7 @@ module.exports = ProjectController = NotificationsHandler.getUserNotifications user_id, cb projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb - olProjects: (cb) -> + v1Projects: (cb) -> if isV1 OlProjectGetter.findAllUsersProjects user_id, cb else @@ -170,7 +170,7 @@ module.exports = ProjectController = notifications = require("underscore").map results.notifications, (notification)-> notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts) return notification - projects = ProjectController._buildProjectList results.projects, results.olProjects?.projects + projects = ProjectController._buildProjectList results.projects, results.v1Projects?.projects user = results.user ProjectController._injectProjectOwners projects, (error, projects) -> return next(error) if error? From ec64d1fab9dd744afb0dba6c9ccd6c398d12e53a Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 31 Oct 2017 12:37:18 +0000 Subject: [PATCH 18/45] Combine tags with v1 tags --- .../web/app/coffee/Features/Project/ProjectController.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index f8c0676938..2aeddd1ab6 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -166,7 +166,8 @@ module.exports = ProjectController = logger.err err:err, "error getting data for project list page" return next(err) logger.log results:results, user_id:user_id, "rendering project list" - tags = results.tags[0] + v1Tags = results.v1Projects?.tags or [] + tags = results.tags[0].concat(v1Tags) notifications = require("underscore").map results.notifications, (notification)-> notification.html = req.i18n.translate(notification.templateKey, notification.messageOpts) return notification From 35883b6b27b57f5851118acf2fcf8e593dc93e59 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 31 Oct 2017 14:09:54 +0000 Subject: [PATCH 19/45] Extract V1 badge styles to file --- services/web/app/views/project/list/ol-item.pug | 2 +- services/web/public/stylesheets/_style_includes.less | 1 + services/web/public/stylesheets/app/project-list.less | 7 +++---- services/web/public/stylesheets/app/v1-badge.less | 9 +++++++++ 4 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 services/web/public/stylesheets/app/v1-badge.less diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/ol-item.pug index 49a6dd01f2..67648b9c7b 100644 --- a/services/web/app/views/project/list/ol-item.pug +++ b/services/web/app/views/project/list/ol-item.pug @@ -1,5 +1,5 @@ .col-xs-8 - span.label.label-default.v1-label V1 + span.v1-badge span a.projectName( href=settings.overleaf.host + "/{{project.id}}" diff --git a/services/web/public/stylesheets/_style_includes.less b/services/web/public/stylesheets/_style_includes.less index a5c7589ef0..54539a4cb4 100644 --- a/services/web/public/stylesheets/_style_includes.less +++ b/services/web/public/stylesheets/_style_includes.less @@ -78,6 +78,7 @@ @import "app/invite.less"; @import "app/review-features-page.less"; @import "app/error-pages.less"; +@import "app/v1-badge.less"; @import "../js/libs/pdfListView/TextLayer.css"; @import "../js/libs/pdfListView/AnnotationsLayer.css"; diff --git a/services/web/public/stylesheets/app/project-list.less b/services/web/public/stylesheets/app/project-list.less index d3745854c3..1ca170ff89 100644 --- a/services/web/public/stylesheets/app/project-list.less +++ b/services/web/public/stylesheets/app/project-list.less @@ -367,10 +367,9 @@ ul.project-list { border-bottom-left-radius: 0; } - .v1-label { - margin-right: 11px; - margin-left: 5px; - padding: 2px 3px 1px; + .v1-badge { + margin-right: 9px; + margin-left: 7px; } } i.tablesort { diff --git a/services/web/public/stylesheets/app/v1-badge.less b/services/web/public/stylesheets/app/v1-badge.less new file mode 100644 index 0000000000..0c64ee9e6b --- /dev/null +++ b/services/web/public/stylesheets/app/v1-badge.less @@ -0,0 +1,9 @@ +.v1-badge { + &:extend(.label); + &:extend(.label-default); + padding: 2px 3px 1px; + margin: 0 4px; + &:before { + content: "V1"; + } +} \ No newline at end of file From d43863d438fc87f9dd83197d0ec13879de2f7fa1 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 31 Oct 2017 14:10:40 +0000 Subject: [PATCH 20/45] Add V1 badge to tags from V1 --- services/web/app/views/project/list/side-bar.pug | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/app/views/project/list/side-bar.pug b/services/web/app/views/project/list/side-bar.pug index 33be0f5378..4888cfdc70 100644 --- a/services/web/app/views/project/list/side-bar.pug +++ b/services/web/app/views/project/list/side-bar.pug @@ -65,6 +65,7 @@ ) span.name {{tag.name}} span.subdued ({{tag.project_ids.length}}) + span.v1-badge(ng-if="tag.isV1", ng-cloak) span.dropdown.tag-menu(dropdown) a.dropdown-toggle( href="#", From bb8f80c1e4a2a5a2830eee45428f2e3277336915 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 31 Oct 2017 14:28:42 +0000 Subject: [PATCH 21/45] Tweak v1 badge styles --- services/web/public/stylesheets/app/v1-badge.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/web/public/stylesheets/app/v1-badge.less b/services/web/public/stylesheets/app/v1-badge.less index 0c64ee9e6b..c2ca96ec73 100644 --- a/services/web/public/stylesheets/app/v1-badge.less +++ b/services/web/public/stylesheets/app/v1-badge.less @@ -1,8 +1,9 @@ .v1-badge { &:extend(.label); &:extend(.label-default); + vertical-align: 11%; padding: 2px 3px 1px; - margin: 0 4px; + margin: 0 6px; &:before { content: "V1"; } From 87352610225949792dd400d5f0fefd1694886c94 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 1 Nov 2017 14:01:06 +0000 Subject: [PATCH 22/45] Extract V1 projects fetch to integration module OlProjectGetter now just detects if integration module is loaded and proxies to integration module. If module not loaded, it just bails --- .../Features/Project/OlProjectGetter.coffee | 36 +++++++++---------- .../Features/Project/ProjectController.coffee | 5 +-- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee index 3f47c0dac4..ab3187a636 100644 --- a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee +++ b/services/web/app/coffee/Features/Project/OlProjectGetter.coffee @@ -1,24 +1,22 @@ -request = require 'request' -settings = require 'settings-sharelatex' +fs = require 'fs' +path = require 'path' logger = require 'logger-sharelatex' -Errors = require '../Errors/Errors' -oAuthRequest = require '../../../../modules/overleaf-integration-web-module/app/coffee/oauth/OAuthRequest' -makeRequest = (opts, callback) -> - if settings.apis?.olProjects?.url? - urlPath = opts.url - opts.url = "#{settings.apis.olProjects.url}#{urlPath}" - request opts, callback - else - callback(new Errors.ServiceNotConfiguredError('OL Projects service not configured')) +INTEGRATION_MODULE_PATH = path.resolve(__dirname, '../../../../modules/overleaf-integration-web-module') module.exports = OlProjectGetter = + integrationModuleExists: (callback = (error, stats) ->) -> + fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> + if error? or !stats.isDirectory() + return callback(false) + return callback(true) + findAllUsersProjects: (userId, callback = (error, projects) ->) -> - oAuthRequest userId, { - url: "#{settings.overleaf.host}/api/v1/sharelatex/docs" - method: 'GET' - json: true - }, (error, docs) -> - return callback(error) if error? - logger.log {userId, docs}, "got projects from OL" - callback(null, docs) \ No newline at end of file + OlProjectGetter.integrationModuleExists (exists) -> + if exists + logger.log {exists}, "integration module does exist, loading V1 projects" + V1ProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) + V1ProjectListGetter.findAllUsersProjects(userId, callback) + else + logger.log {exists}, "integration modules doesn't exists, not loading V1 projects" + return callback() diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 2aeddd1ab6..e067d7f9e7 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -153,10 +153,7 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb v1Projects: (cb) -> - if isV1 - OlProjectGetter.findAllUsersProjects user_id, cb - else - cb() + OlProjectGetter.findAllUsersProjects user_id, cb hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> From 8df31590a9087b875bfd9d28b4dd9591fe546fcd Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 1 Nov 2017 14:10:12 +0000 Subject: [PATCH 23/45] Switch V1 naming instead of OL --- .../coffee/Features/Project/ProjectController.coffee | 12 ++++++------ ...OlProjectGetter.coffee => V1ProjectGetter.coffee} | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) rename services/web/app/coffee/Features/Project/{OlProjectGetter.coffee => V1ProjectGetter.coffee} (90%) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index e067d7f9e7..3b2099f923 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -19,7 +19,7 @@ fs = require "fs" InactiveProjectManager = require("../InactiveData/InactiveProjectManager") ProjectUpdateHandler = require("./ProjectUpdateHandler") ProjectGetter = require("./ProjectGetter") -OlProjectGetter = require("./OlProjectGetter") +V1ProjectGetter = require("./V1ProjectGetter") PrivilegeLevels = require("../Authorization/PrivilegeLevels") AuthenticationController = require("../Authentication/AuthenticationController") PackageVersions = require("../../infrastructure/PackageVersions") @@ -153,7 +153,7 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb v1Projects: (cb) -> - OlProjectGetter.findAllUsersProjects user_id, cb + V1ProjectGetter.findAllUsersProjects user_id, cb hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> @@ -398,7 +398,7 @@ module.exports = ProjectController = showLinkSharingOnboarding: showLinkSharingOnboarding timer.done() - _buildProjectList: (allProjects, olProjects = [])-> + _buildProjectList: (allProjects, v1Projects = [])-> {owned, readAndWrite, readOnly, tokenReadAndWrite, tokenReadOnly} = allProjects projects = [] for project in owned @@ -408,8 +408,8 @@ module.exports = ProjectController = projects.push ProjectController._buildProjectViewModel(project, "readWrite", Sources.INVITE) for project in readOnly projects.push ProjectController._buildProjectViewModel(project, "readOnly", Sources.INVITE) - for project in olProjects - projects.push ProjectController._buildOlProjectViwModel(project) + for project in v1Projects + projects.push ProjectController._buildV1ProjectViewModel(project) # Token-access # Only add these projects if they're not already present, this gives us cascading access # from 'owner' => 'token-read-only' @@ -438,7 +438,7 @@ module.exports = ProjectController = } return model - _buildOlProjectViewModel: (project) -> + _buildV1ProjectViewModel: (project) -> { id: project.id name: project.title diff --git a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee similarity index 90% rename from services/web/app/coffee/Features/Project/OlProjectGetter.coffee rename to services/web/app/coffee/Features/Project/V1ProjectGetter.coffee index ab3187a636..ca957e2804 100644 --- a/services/web/app/coffee/Features/Project/OlProjectGetter.coffee +++ b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee @@ -4,7 +4,7 @@ logger = require 'logger-sharelatex' INTEGRATION_MODULE_PATH = path.resolve(__dirname, '../../../../modules/overleaf-integration-web-module') -module.exports = OlProjectGetter = +module.exports = V1ProjectGetter = integrationModuleExists: (callback = (error, stats) ->) -> fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> if error? or !stats.isDirectory() @@ -12,7 +12,7 @@ module.exports = OlProjectGetter = return callback(true) findAllUsersProjects: (userId, callback = (error, projects) ->) -> - OlProjectGetter.integrationModuleExists (exists) -> + V1ProjectGetter.integrationModuleExists (exists) -> if exists logger.log {exists}, "integration module does exist, loading V1 projects" V1ProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) From 072448280838f04bfbabd3f5cde0663628bda040 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 1 Nov 2017 14:12:44 +0000 Subject: [PATCH 24/45] Don't use brand prefix setting to mark v1 --- .../web/app/coffee/Features/Project/ProjectController.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 3b2099f923..944ac04a2e 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -144,7 +144,6 @@ module.exports = ProjectController = timer = new metrics.Timer("project-list") user_id = AuthenticationController.getLoggedInUserId(req) currentUser = AuthenticationController.getSessionUser(req) - isV1 = Settings.brandPrefix == "ol-" async.parallel { tags: (cb)-> TagsHandler.getAllTags user_id, cb @@ -180,7 +179,7 @@ module.exports = ProjectController = notifications: notifications or [] user: user hasSubscription: results.hasSubscription[0] - isV1: isV1 + isV1: results.v1Projects? } if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key? From 9bf74f29bdee44c8fe880197d28bd8c60153df98 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 1 Nov 2017 14:13:50 +0000 Subject: [PATCH 25/45] Improve naming --- .../web/app/coffee/Features/Project/ProjectController.coffee | 2 +- services/web/app/views/project/list/side-bar.pug | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 944ac04a2e..5b5668ec31 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -179,7 +179,7 @@ module.exports = ProjectController = notifications: notifications or [] user: user hasSubscription: results.hasSubscription[0] - isV1: results.v1Projects? + isShowingV1Projects: results.v1Projects? } if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key? diff --git a/services/web/app/views/project/list/side-bar.pug b/services/web/app/views/project/list/side-bar.pug index 4888cfdc70..69bfecd50a 100644 --- a/services/web/app/views/project/list/side-bar.pug +++ b/services/web/app/views/project/list/side-bar.pug @@ -45,7 +45,7 @@ a(href) #{translate("shared_with_you")} li(ng-class="{active: (filter == 'archived')}", ng-click="filterProjects('archived')") a(href) #{translate("deleted_projects")} - if isV1 + if isShowingV1Projects li(ng-class="{active: (filter == 'v1')}", ng-click="filterProjects('v1')") a(href) #{translate("v1_projects")} li.separator @@ -65,7 +65,7 @@ ) span.name {{tag.name}} span.subdued ({{tag.project_ids.length}}) - span.v1-badge(ng-if="tag.isV1", ng-cloak) + span.v1-badge(ng-if="tag.isShowingV1Projects", ng-cloak) span.dropdown.tag-menu(dropdown) a.dropdown-toggle( href="#", From fff6873e1072c4bfd0d3cb0afa5642ed96d6ae6b Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 10:18:01 +0000 Subject: [PATCH 26/45] Add tests for getting V1 projects --- .../Project/ProjectControllerTests.coffee | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 498090f790..7cd43f0174 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -54,6 +54,8 @@ describe "ProjectController", -> @ProjectGetter = findAllUsersProjects: sinon.stub() getProject: sinon.stub() + @V1ProjectGetter = + findAllUsersProjects: sinon.stub() @AuthenticationController = getLoggedInUser: sinon.stub().callsArgWith(1, null, @user) getLoggedInUserId: sinon.stub().returns(@user._id) @@ -89,6 +91,7 @@ describe "ProjectController", -> "./ProjectUpdateHandler":@ProjectUpdateHandler "../ReferencesSearch/ReferencesSearchHandler": @ReferencesSearchHandler "./ProjectGetter": @ProjectGetter + './V1ProjectGetter': @V1ProjectGetter '../Authentication/AuthenticationController': @AuthenticationController "../Analytics/AnalyticsManager": @AnalyticsManager "../TokenAccess/TokenAccessHandler": @TokenAccessHandler @@ -263,6 +266,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) + @V1ProjectGetter.findAllUsersProjects.callsArg(1) # Without integration module cb returns without args it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> @@ -278,7 +282,7 @@ describe "ProjectController", -> it "should send the projects", (done)-> @res.render = (pageName, opts)=> - opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length + @tokenReadAndWrite.length + @tokenReadOnly.length) + opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length) done() @ProjectController.projectListPage @req, @res @@ -295,6 +299,36 @@ describe "ProjectController", -> done() @ProjectController.projectListPage @req, @res + describe 'with overleaf-integration-web-module', -> + beforeEach -> + @V1Response = + projects: [ + { id: '123mockV1Id', title: 'mock title', updated_at: 1509616411, removed: false, archived: false } + { id: '456mockV1Id', title: 'mock title 2', updated_at: 1509616411, removed: true, archived: false } + ], + tags: [ + { name: 'mock tag', project_ids: ['123mockV1Id'] } + ] + @V1ProjectGetter.findAllUsersProjects.callsArgWith(1, null, @V1Response) + + it 'should include V1 projects', (done) -> + @res.render = (pageName, opts) => + opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length + @V1Response.projects.length) + done() + @ProjectController.projectListPage @req, @res + + it 'should include V1 tags', (done) -> + @res.render = (pageName, opts) => + opts.tags.length.should.equal (@tags.length + @V1Response.tags.length) + done() + @ProjectController.projectListPage @req, @res + + it 'should have isShowingV1Projects flag', (done) -> + @res.render = (pageName, opts) => + opts.isShowingV1Projects.should.equal true + done() + @ProjectController.projectListPage @req, @res + describe "projectListPage with duplicate projects", -> beforeEach -> From 24166af90e54c73b9e70b7948847cef6315a4a96 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 11:59:05 +0000 Subject: [PATCH 27/45] Add tests for V1ProjectGetter --- .../Project/V1ProjectGetterTests.coffee | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee diff --git a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee new file mode 100644 index 0000000000..e2851eecdb --- /dev/null +++ b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee @@ -0,0 +1,47 @@ +sinon = require('sinon') +should = require('chai').should() +SandboxedModule = require('sandboxed-module') + +modulePath = '../../../../app/js/Features/Project/V1ProjectGetter.js' + +describe 'V1ProjectGetter', -> + beforeEach -> + @fs = + stat: sinon.stub() + @path = + resolve: sinon.stub().returns('path/to/integration/module') + join: sinon.stub().returns('path/to/file/in/integration/module') + @IntegrationProjectListGetter = + findAllUsersProjects: sinon.stub() + @V1ProjectGetter = SandboxedModule.require modulePath, requires: + 'fs': @fs + 'path': @path + 'logger-sharelatex': log: -> + 'path/to/file/in/integration/module': @IntegrationProjectListGetter + @userId = 123 + @callback = sinon.stub() + + describe 'without overleaf-integration-web-module', -> + beforeEach -> + # Mock not finding integration module + @fs.stat.yields({ code: 'mock-ENOENT-error' }) + # Call method + @V1ProjectGetter.findAllUsersProjects @userId, @callback + + it 'should call the callback with no arguments', -> + @callback.calledWith().should.equal true + + describe 'with overleaf-integration-web-module', -> + beforeEach -> + # Mock finding integration module + @fs.stat.yields(null, isDirectory: sinon.stub().returns(true)) + # Mock integration module response + @IntegrationProjectListGetter.findAllUsersProjects.yields(null, @response = { + projects: [{ id: '123mockV1Id', title: 'mock title' }] + tags: [{ name: 'mock tag', project_ids: ['123mockV1Id'] }] + }) + # Call method + @V1ProjectGetter.findAllUsersProjects @userId, @callback + + it 'should call the callback with all the projects and tags', -> + @callback.calledWith(null, @response).should.equal true From 9a96f070d56bbb862e9199a8c8346e3583f6656b Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 12:09:47 +0000 Subject: [PATCH 28/45] Add assertions for correctly mapping V1 properties --- .../UnitTests/coffee/Project/ProjectControllerTests.coffee | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 7cd43f0174..2392c4476b 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -314,6 +314,13 @@ describe "ProjectController", -> it 'should include V1 projects', (done) -> @res.render = (pageName, opts) => opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length + @V1Response.projects.length) + opts.projects.forEach (p) -> + # Check properties correctly mapped from V1 + expect(p).to.have.property 'id' + expect(p).to.have.property 'name' + expect(p).to.have.property 'lastUpdated' + expect(p).to.have.property 'accessLevel' + expect(p).to.have.property 'archived' done() @ProjectController.projectListPage @req, @res From 56634bdb49873550fa3e4f2c9b5e6d7bc25022f7 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 12:16:11 +0000 Subject: [PATCH 29/45] Add assertions for tag properties --- .../UnitTests/coffee/Project/ProjectControllerTests.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 2392c4476b..b53d36cd6f 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -327,6 +327,9 @@ describe "ProjectController", -> it 'should include V1 tags', (done) -> @res.render = (pageName, opts) => opts.tags.length.should.equal (@tags.length + @V1Response.tags.length) + opts.tags.forEach (t) -> + expect(t).to.have.property 'name' + expect(t).to.have.property 'project_ids' done() @ProjectController.projectListPage @req, @res From 08fd092f7c72d17c7a7a88560253666d5e0d183e Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 12:24:26 +0000 Subject: [PATCH 30/45] Rename v1 list item template for consistency --- services/web/app/views/project/list/project-list.pug | 2 +- .../web/app/views/project/list/{ol-item.pug => v1-item.pug} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename services/web/app/views/project/list/{ol-item.pug => v1-item.pug} (100%) diff --git a/services/web/app/views/project/list/project-list.pug b/services/web/app/views/project/list/project-list.pug index 260cc387f0..806e2d97e8 100644 --- a/services/web/app/views/project/list/project-list.pug +++ b/services/web/app/views/project/list/project-list.pug @@ -150,7 +150,7 @@ .row( ng-if="project.isV1Project" ) - include ./ol-item + include ./v1-item li( ng-if="visibleProjects.length == 0", ng-cloak diff --git a/services/web/app/views/project/list/ol-item.pug b/services/web/app/views/project/list/v1-item.pug similarity index 100% rename from services/web/app/views/project/list/ol-item.pug rename to services/web/app/views/project/list/v1-item.pug From 4b25525e9d5341d4fd47e151d727d4e7fe0dcd25 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 12:24:42 +0000 Subject: [PATCH 31/45] Add aria labels to V1 badges --- services/web/app/views/project/list/side-bar.pug | 6 +++++- services/web/app/views/project/list/v1-item.pug | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/services/web/app/views/project/list/side-bar.pug b/services/web/app/views/project/list/side-bar.pug index 69bfecd50a..1cb41d6119 100644 --- a/services/web/app/views/project/list/side-bar.pug +++ b/services/web/app/views/project/list/side-bar.pug @@ -65,7 +65,11 @@ ) span.name {{tag.name}} span.subdued ({{tag.project_ids.length}}) - span.v1-badge(ng-if="tag.isShowingV1Projects", ng-cloak) + span.v1-badge( + ng-if="tag.isShowingV1Projects", + ng-cloak, + aria-label=translate("v1_badge") + ) span.dropdown.tag-menu(dropdown) a.dropdown-toggle( href="#", diff --git a/services/web/app/views/project/list/v1-item.pug b/services/web/app/views/project/list/v1-item.pug index 67648b9c7b..5631788aeb 100644 --- a/services/web/app/views/project/list/v1-item.pug +++ b/services/web/app/views/project/list/v1-item.pug @@ -1,5 +1,5 @@ .col-xs-8 - span.v1-badge + span.v1-badge(aria-label=translate("v1_badge")) span a.projectName( href=settings.overleaf.host + "/{{project.id}}" From 4b2e22c257b7866f9d2ee588122951e3390050fc Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 2 Nov 2017 12:34:28 +0000 Subject: [PATCH 32/45] Remove duplicate dependency --- .../web/app/coffee/Features/Project/ProjectController.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 5b5668ec31..30d403b189 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -1,7 +1,6 @@ async = require("async") moment = require('moment') logger = require("logger-sharelatex") -Settings = require('settings-sharelatex') projectDeleter = require("./ProjectDeleter") projectDuplicator = require("./ProjectDuplicator") projectCreationHandler = require("./ProjectCreationHandler") From 3bc48a7a05bfa0cc57d45bd2ba086d56089a1031 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 09:30:58 +0000 Subject: [PATCH 33/45] Switch to date builtin instead of moment --- .../web/app/coffee/Features/Project/ProjectController.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 30d403b189..877a0ae634 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -1,5 +1,4 @@ async = require("async") -moment = require('moment') logger = require("logger-sharelatex") projectDeleter = require("./ProjectDeleter") projectDuplicator = require("./ProjectDuplicator") @@ -440,7 +439,7 @@ module.exports = ProjectController = { id: project.id name: project.title - lastUpdated: moment.unix(project.updated_at) + lastUpdated: new Date(project.updated_at * 1000) # Convert from epoch accessLevel: "readOnly", archived: project.removed || project.archived isV1Project: true From e32406a4c4eb011121da736afbfb9b29858b6d6b Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 10:16:03 +0000 Subject: [PATCH 34/45] Dynamically monkey patch impl to check integration once instead of each request --- .../Features/Project/V1ProjectGetter.coffee | 29 +++++++++---------- .../Project/V1ProjectGetterTests.coffee | 27 ++++++++++------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee index ca957e2804..26efa45312 100644 --- a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee +++ b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee @@ -4,19 +4,18 @@ logger = require 'logger-sharelatex' INTEGRATION_MODULE_PATH = path.resolve(__dirname, '../../../../modules/overleaf-integration-web-module') -module.exports = V1ProjectGetter = - integrationModuleExists: (callback = (error, stats) ->) -> - fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> - if error? or !stats.isDirectory() - return callback(false) - return callback(true) - +V1ProjectGetter = + # Default implementation is a no-op findAllUsersProjects: (userId, callback = (error, projects) ->) -> - V1ProjectGetter.integrationModuleExists (exists) -> - if exists - logger.log {exists}, "integration module does exist, loading V1 projects" - V1ProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) - V1ProjectListGetter.findAllUsersProjects(userId, callback) - else - logger.log {exists}, "integration modules doesn't exists, not loading V1 projects" - return callback() + logger.log {}, "integration modules doesn't exist, not loading V1 projects" + return callback() + +fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> + return if error? or !stats.isDirectory() + logger.log {isDirectory: stats.isDirectory}, "integration module does exist, loading V1 projects" + # Monkey patch impl to actually fetch projects + V1ProjectGetter.findAllUsersProjects = (userId, callback = (error, projects) ->) -> + IntegrationProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) + IntegrationProjectListGetter.findAllUsersProjects(userId, callback) + +module.exports = V1ProjectGetter \ No newline at end of file diff --git a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee index e2851eecdb..a7d2e9f326 100644 --- a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee @@ -6,25 +6,24 @@ modulePath = '../../../../app/js/Features/Project/V1ProjectGetter.js' describe 'V1ProjectGetter', -> beforeEach -> - @fs = - stat: sinon.stub() @path = resolve: sinon.stub().returns('path/to/integration/module') join: sinon.stub().returns('path/to/file/in/integration/module') @IntegrationProjectListGetter = findAllUsersProjects: sinon.stub() - @V1ProjectGetter = SandboxedModule.require modulePath, requires: - 'fs': @fs - 'path': @path - 'logger-sharelatex': log: -> - 'path/to/file/in/integration/module': @IntegrationProjectListGetter @userId = 123 @callback = sinon.stub() describe 'without overleaf-integration-web-module', -> beforeEach -> - # Mock not finding integration module - @fs.stat.yields({ code: 'mock-ENOENT-error' }) + @fs = + stat: sinon.stub().yields({code: 'mock-ENOENT-error'}) + @V1ProjectGetter = SandboxedModule.require modulePath, requires: + # Mock not finding integration module + 'fs': @fs + 'path': @path + 'logger-sharelatex': log: -> + 'path/to/file/in/integration/module': @IntegrationProjectListGetter # Call method @V1ProjectGetter.findAllUsersProjects @userId, @callback @@ -33,8 +32,14 @@ describe 'V1ProjectGetter', -> describe 'with overleaf-integration-web-module', -> beforeEach -> - # Mock finding integration module - @fs.stat.yields(null, isDirectory: sinon.stub().returns(true)) + @fs = + stat: sinon.stub().yields(null, isDirectory: sinon.stub().returns(true)) + @V1ProjectGetter = SandboxedModule.require modulePath, requires: + # Mock finding integration module + 'fs': @fs + 'path': @path + 'logger-sharelatex': log: -> + 'path/to/file/in/integration/module': @IntegrationProjectListGetter # Mock integration module response @IntegrationProjectListGetter.findAllUsersProjects.yields(null, @response = { projects: [{ id: '123mockV1Id', title: 'mock title' }] From 6822a0d838b65b79904abd678d2aea75e2862091 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 10:17:55 +0000 Subject: [PATCH 35/45] Add assertions for integration module call --- .../test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee index a7d2e9f326..c97574550b 100644 --- a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee @@ -29,6 +29,7 @@ describe 'V1ProjectGetter', -> it 'should call the callback with no arguments', -> @callback.calledWith().should.equal true + @IntegrationProjectListGetter.findAllUsersProjects.called.should.equal false describe 'with overleaf-integration-web-module', -> beforeEach -> @@ -50,3 +51,4 @@ describe 'V1ProjectGetter', -> it 'should call the callback with all the projects and tags', -> @callback.calledWith(null, @response).should.equal true + @IntegrationProjectListGetter.findAllUsersProjects.called.should.equal true From c629f27db9e012b64f38fd638873a32d20aa5279 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 10:20:48 +0000 Subject: [PATCH 36/45] Remove unneeded moment dep --- services/web/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/services/web/package.json b/services/web/package.json index b4dd29395d..e831d929e1 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -40,7 +40,6 @@ "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", "mimelib": "0.2.14", "mocha": "1.17.1", - "moment": "^2.18.1", "mongojs": "2.4.0", "mongoose": "4.11.4", "multer": "^0.1.8", From d5cfd34bb72445fedede938fd9ae9964e01bb87d Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 10:23:29 +0000 Subject: [PATCH 37/45] Log something useful --- services/web/app/coffee/Features/Project/V1ProjectGetter.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee index 26efa45312..b304429b2f 100644 --- a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee +++ b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee @@ -12,7 +12,7 @@ V1ProjectGetter = fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> return if error? or !stats.isDirectory() - logger.log {isDirectory: stats.isDirectory}, "integration module does exist, loading V1 projects" + logger.log {isDirectory: stats.isDirectory()}, "integration module does exist, loading V1 projects" # Monkey patch impl to actually fetch projects V1ProjectGetter.findAllUsersProjects = (userId, callback = (error, projects) ->) -> IntegrationProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) From d9c19ccdc4a28d8e095bac1c85fd0b3f9df39192 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Fri, 3 Nov 2017 10:30:48 +0000 Subject: [PATCH 38/45] Fix V1 tags not showing badge correctly --- services/web/app/views/project/list/side-bar.pug | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/app/views/project/list/side-bar.pug b/services/web/app/views/project/list/side-bar.pug index 1cb41d6119..9fceb4cc86 100644 --- a/services/web/app/views/project/list/side-bar.pug +++ b/services/web/app/views/project/list/side-bar.pug @@ -66,7 +66,7 @@ span.name {{tag.name}} span.subdued ({{tag.project_ids.length}}) span.v1-badge( - ng-if="tag.isShowingV1Projects", + ng-if="tag.isV1", ng-cloak, aria-label=translate("v1_badge") ) From 47942816ae186be574ce186c3de4ba03ea25e908 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 14 Nov 2017 11:38:06 +0000 Subject: [PATCH 39/45] Include token based --- .../coffee/Project/ProjectControllerTests.coffee | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index b53d36cd6f..14b7fa3c99 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -282,7 +282,7 @@ describe "ProjectController", -> it "should send the projects", (done)-> @res.render = (pageName, opts)=> - opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length) + opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length + @tokenReadAndWrite.length + @tokenReadOnly.length) done() @ProjectController.projectListPage @req, @res @@ -313,7 +313,14 @@ describe "ProjectController", -> it 'should include V1 projects', (done) -> @res.render = (pageName, opts) => - opts.projects.length.should.equal (@projects.length + @collabertions.length + @readOnly.length + @V1Response.projects.length) + opts.projects.length.should.equal ( + @projects.length + + @collabertions.length + + @readOnly.length + + @tokenReadAndWrite.length + + @tokenReadOnly.length + + @V1Response.projects.length + ) opts.projects.forEach (p) -> # Check properties correctly mapped from V1 expect(p).to.have.property 'id' From 3eaf6c5d8e9991d56481076cd87bb23928af4985 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Tue, 14 Nov 2017 11:38:46 +0000 Subject: [PATCH 40/45] Stub V1 project getter --- .../test/UnitTests/coffee/Project/ProjectControllerTests.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 14b7fa3c99..2111abc085 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -389,6 +389,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) + @V1ProjectGetter.findAllUsersProjects.callsArg(1) # Without integration module cb returns without args it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> From 621977c47c7fc860a263cb17e9c19bf178b42c6b Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 15 Nov 2017 15:54:47 +0000 Subject: [PATCH 41/45] Replace call to V1ProjectGetter with Module hook --- .../Features/Project/ProjectController.coffee | 5 +++-- .../coffee/Project/ProjectControllerTests.coffee | 15 ++++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index 877a0ae634..be3236747a 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -17,7 +17,6 @@ fs = require "fs" InactiveProjectManager = require("../InactiveData/InactiveProjectManager") ProjectUpdateHandler = require("./ProjectUpdateHandler") ProjectGetter = require("./ProjectGetter") -V1ProjectGetter = require("./V1ProjectGetter") PrivilegeLevels = require("../Authorization/PrivilegeLevels") AuthenticationController = require("../Authentication/AuthenticationController") PackageVersions = require("../../infrastructure/PackageVersions") @@ -25,6 +24,7 @@ AnalyticsManager = require "../Analytics/AnalyticsManager" Sources = require "../Authorization/Sources" TokenAccessHandler = require '../TokenAccess/TokenAccessHandler' CollaboratorsHandler = require '../Collaborators/CollaboratorsHandler' +Modules = require '../../infrastructure/Modules' crypto = require 'crypto' module.exports = ProjectController = @@ -150,7 +150,8 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb v1Projects: (cb) -> - V1ProjectGetter.findAllUsersProjects user_id, cb + Modules.hooks.fire "findAllUsersProjects", user_id, (error, projects = []) -> + cb error, projects[0] # hooks.fire returns an array of results, only need first hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 2111abc085..4236ffa37f 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -54,8 +54,6 @@ describe "ProjectController", -> @ProjectGetter = findAllUsersProjects: sinon.stub() getProject: sinon.stub() - @V1ProjectGetter = - findAllUsersProjects: sinon.stub() @AuthenticationController = getLoggedInUser: sinon.stub().callsArgWith(1, null, @user) getLoggedInUserId: sinon.stub().returns(@user._id) @@ -68,6 +66,9 @@ describe "ProjectController", -> protectTokens: sinon.stub() @CollaboratorsHandler = userIsTokenMember: sinon.stub().callsArgWith(2, null, false) + @Modules = + hooks: + fire: sinon.stub() @ProjectController = SandboxedModule.require modulePath, requires: "settings-sharelatex":@settings "logger-sharelatex": @@ -91,11 +92,11 @@ describe "ProjectController", -> "./ProjectUpdateHandler":@ProjectUpdateHandler "../ReferencesSearch/ReferencesSearchHandler": @ReferencesSearchHandler "./ProjectGetter": @ProjectGetter - './V1ProjectGetter': @V1ProjectGetter '../Authentication/AuthenticationController': @AuthenticationController "../Analytics/AnalyticsManager": @AnalyticsManager "../TokenAccess/TokenAccessHandler": @TokenAccessHandler "../Collaborators/CollaboratorsHandler": @CollaboratorsHandler + "../../infrastructure/Modules": @Modules @projectName = "£12321jkj9ujkljds" @req = @@ -266,7 +267,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) - @V1ProjectGetter.findAllUsersProjects.callsArg(1) # Without integration module cb returns without args + @Modules.hooks.fire.yields(undefined) # Without integration module hook, cb returns undefined it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> @@ -299,7 +300,7 @@ describe "ProjectController", -> done() @ProjectController.projectListPage @req, @res - describe 'with overleaf-integration-web-module', -> + describe 'with overleaf-integration-web-module hook', -> beforeEach -> @V1Response = projects: [ @@ -309,7 +310,7 @@ describe "ProjectController", -> tags: [ { name: 'mock tag', project_ids: ['123mockV1Id'] } ] - @V1ProjectGetter.findAllUsersProjects.callsArgWith(1, null, @V1Response) + @Modules.hooks.fire.withArgs('findAllUsersProjects', @user._id).yields(null, [@V1Response]) # Need to wrap response in array, as multiple hooks could fire it 'should include V1 projects', (done) -> @res.render = (pageName, opts) => @@ -389,7 +390,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) - @V1ProjectGetter.findAllUsersProjects.callsArg(1) # Without integration module cb returns without args + @Modules.hooks.fire.withArgs('findAllUsersProjects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> From 119be26989b6c188fa4982798dd627511ce33dff Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 15 Nov 2017 15:59:13 +0000 Subject: [PATCH 42/45] Remove unnecessary project getter Had bad assumption about whether ol-integration module would be available in filesystem, now replaced with Module hook --- .../Features/Project/V1ProjectGetter.coffee | 21 -------- .../Project/V1ProjectGetterTests.coffee | 54 ------------------- 2 files changed, 75 deletions(-) delete mode 100644 services/web/app/coffee/Features/Project/V1ProjectGetter.coffee delete mode 100644 services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee diff --git a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee b/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee deleted file mode 100644 index b304429b2f..0000000000 --- a/services/web/app/coffee/Features/Project/V1ProjectGetter.coffee +++ /dev/null @@ -1,21 +0,0 @@ -fs = require 'fs' -path = require 'path' -logger = require 'logger-sharelatex' - -INTEGRATION_MODULE_PATH = path.resolve(__dirname, '../../../../modules/overleaf-integration-web-module') - -V1ProjectGetter = - # Default implementation is a no-op - findAllUsersProjects: (userId, callback = (error, projects) ->) -> - logger.log {}, "integration modules doesn't exist, not loading V1 projects" - return callback() - -fs.stat INTEGRATION_MODULE_PATH, (error, stats) -> - return if error? or !stats.isDirectory() - logger.log {isDirectory: stats.isDirectory()}, "integration module does exist, loading V1 projects" - # Monkey patch impl to actually fetch projects - V1ProjectGetter.findAllUsersProjects = (userId, callback = (error, projects) ->) -> - IntegrationProjectListGetter = require(path.join(INTEGRATION_MODULE_PATH, 'app/coffee/ProjectList/ProjectListGetter')) - IntegrationProjectListGetter.findAllUsersProjects(userId, callback) - -module.exports = V1ProjectGetter \ No newline at end of file diff --git a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee b/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee deleted file mode 100644 index c97574550b..0000000000 --- a/services/web/test/UnitTests/coffee/Project/V1ProjectGetterTests.coffee +++ /dev/null @@ -1,54 +0,0 @@ -sinon = require('sinon') -should = require('chai').should() -SandboxedModule = require('sandboxed-module') - -modulePath = '../../../../app/js/Features/Project/V1ProjectGetter.js' - -describe 'V1ProjectGetter', -> - beforeEach -> - @path = - resolve: sinon.stub().returns('path/to/integration/module') - join: sinon.stub().returns('path/to/file/in/integration/module') - @IntegrationProjectListGetter = - findAllUsersProjects: sinon.stub() - @userId = 123 - @callback = sinon.stub() - - describe 'without overleaf-integration-web-module', -> - beforeEach -> - @fs = - stat: sinon.stub().yields({code: 'mock-ENOENT-error'}) - @V1ProjectGetter = SandboxedModule.require modulePath, requires: - # Mock not finding integration module - 'fs': @fs - 'path': @path - 'logger-sharelatex': log: -> - 'path/to/file/in/integration/module': @IntegrationProjectListGetter - # Call method - @V1ProjectGetter.findAllUsersProjects @userId, @callback - - it 'should call the callback with no arguments', -> - @callback.calledWith().should.equal true - @IntegrationProjectListGetter.findAllUsersProjects.called.should.equal false - - describe 'with overleaf-integration-web-module', -> - beforeEach -> - @fs = - stat: sinon.stub().yields(null, isDirectory: sinon.stub().returns(true)) - @V1ProjectGetter = SandboxedModule.require modulePath, requires: - # Mock finding integration module - 'fs': @fs - 'path': @path - 'logger-sharelatex': log: -> - 'path/to/file/in/integration/module': @IntegrationProjectListGetter - # Mock integration module response - @IntegrationProjectListGetter.findAllUsersProjects.yields(null, @response = { - projects: [{ id: '123mockV1Id', title: 'mock title' }] - tags: [{ name: 'mock tag', project_ids: ['123mockV1Id'] }] - }) - # Call method - @V1ProjectGetter.findAllUsersProjects @userId, @callback - - it 'should call the callback with all the projects and tags', -> - @callback.calledWith(null, @response).should.equal true - @IntegrationProjectListGetter.findAllUsersProjects.called.should.equal true From 24ceaffd3a2f4efae435c84cea5c242c0516a27b Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 15 Nov 2017 16:28:41 +0000 Subject: [PATCH 43/45] Rename hook for clarity --- .../app/coffee/Features/Project/ProjectController.coffee | 2 +- .../UnitTests/coffee/Project/ProjectControllerTests.coffee | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index be3236747a..a4d8ab0274 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -150,7 +150,7 @@ module.exports = ProjectController = projects: (cb)-> ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb v1Projects: (cb) -> - Modules.hooks.fire "findAllUsersProjects", user_id, (error, projects = []) -> + Modules.hooks.fire "findAllV1Projects", user_id, (error, projects = []) -> cb error, projects[0] # hooks.fire returns an array of results, only need first hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb diff --git a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee index 4236ffa37f..35176acd4b 100644 --- a/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee +++ b/services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee @@ -267,7 +267,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) - @Modules.hooks.fire.yields(undefined) # Without integration module hook, cb returns undefined + @Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> @@ -310,7 +310,7 @@ describe "ProjectController", -> tags: [ { name: 'mock tag', project_ids: ['123mockV1Id'] } ] - @Modules.hooks.fire.withArgs('findAllUsersProjects', @user._id).yields(null, [@V1Response]) # Need to wrap response in array, as multiple hooks could fire + @Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(null, [@V1Response]) # Need to wrap response in array, as multiple hooks could fire it 'should include V1 projects', (done) -> @res.render = (pageName, opts) => @@ -390,7 +390,7 @@ describe "ProjectController", -> @TagsHandler.getAllTags.callsArgWith(1, null, @tags, {}) @NotificationsHandler.getUserNotifications = sinon.stub().callsArgWith(1, null, @notifications, {}) @ProjectGetter.findAllUsersProjects.callsArgWith(2, null, @allProjects) - @Modules.hooks.fire.withArgs('findAllUsersProjects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined + @Modules.hooks.fire.withArgs('findAllV1Projects', @user._id).yields(undefined) # Without integration module hook, cb returns undefined it "should render the project/list page", (done)-> @res.render = (pageName, opts)=> From f3583b17021daeb65f19e197932c351b3edd8cc0 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Wed, 15 Nov 2017 17:19:37 +0000 Subject: [PATCH 44/45] Show warning message if V1 connection fails --- .../web/app/coffee/Features/Project/ProjectController.coffee | 5 ++++- services/web/app/views/project/list/project-list.pug | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/services/web/app/coffee/Features/Project/ProjectController.coffee b/services/web/app/coffee/Features/Project/ProjectController.coffee index a4d8ab0274..bbff14d2a1 100644 --- a/services/web/app/coffee/Features/Project/ProjectController.coffee +++ b/services/web/app/coffee/Features/Project/ProjectController.coffee @@ -151,7 +151,9 @@ module.exports = ProjectController = ProjectGetter.findAllUsersProjects user_id, 'name lastUpdated publicAccesLevel archived owner_ref tokens', cb v1Projects: (cb) -> Modules.hooks.fire "findAllV1Projects", user_id, (error, projects = []) -> - cb error, projects[0] # hooks.fire returns an array of results, only need first + if error? and error.message == 'No V1 connection' + return cb(null, projects: [], tags: [], noConnection: true) + return cb(error, projects[0]) # hooks.fire returns an array of results, only need first hasSubscription: (cb)-> LimitationsManager.userHasSubscriptionOrIsGroupMember currentUser, cb user: (cb) -> @@ -179,6 +181,7 @@ module.exports = ProjectController = user: user hasSubscription: results.hasSubscription[0] isShowingV1Projects: results.v1Projects? + noV1Connection: results.v1Projects?.noConnection } if Settings?.algolia?.app_id? and Settings?.algolia?.read_only_api_key? diff --git a/services/web/app/views/project/list/project-list.pug b/services/web/app/views/project/list/project-list.pug index 806e2d97e8..0db4f49400 100644 --- a/services/web/app/views/project/list/project-list.pug +++ b/services/web/app/views/project/list/project-list.pug @@ -114,6 +114,10 @@ ) #{translate("delete_forever")} .row.row-spaced + if noV1Connection + .col-xs-12 + .alert.alert-warning No V1 Connection + .col-xs-12 .card.card-thin.project-list-card ul.list-unstyled.project-list.structured-list( From a63e40f03f658514706878b8ff10947dcdacb827 Mon Sep 17 00:00:00 2001 From: Alasdair Smith Date: Thu, 16 Nov 2017 17:11:39 +0000 Subject: [PATCH 45/45] Adjust vertical padding on V1 badge --- services/web/public/stylesheets/app/v1-badge.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/stylesheets/app/v1-badge.less b/services/web/public/stylesheets/app/v1-badge.less index c2ca96ec73..ced9d04c81 100644 --- a/services/web/public/stylesheets/app/v1-badge.less +++ b/services/web/public/stylesheets/app/v1-badge.less @@ -2,7 +2,7 @@ &:extend(.label); &:extend(.label-default); vertical-align: 11%; - padding: 2px 3px 1px; + padding: 1px 3px; margin: 0 6px; &:before { content: "V1";