diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index 40509a98..de2fa2e5 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -152,7 +152,7 @@ urls = { "history/us": "/history/userstory" "history/issue": "/history/issue" "history/task": "/history/task" - "history/wiki": "/history/wiki/%s" + "history/wiki": "/history/wiki" # Attachments "attachments/epic": "/epics/attachments" diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 8f4d998d..aefaf6bb 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -213,7 +213,7 @@ WikiSummaryDirective = ($log, $template, $compile, $translate, avatarService) -> module.directive("tgWikiSummary", ["$log", "$tgTemplate", "$compile", "$translate", "tgAvatarService", WikiSummaryDirective]) WikiWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService, -$qqueue, $repo, $analytics, wikiHistoryService) -> +$qqueue, $repo, $analytics, activityService) -> link = ($scope, $el, $attrs) -> $scope.editableDescription = false @@ -223,7 +223,7 @@ $qqueue, $repo, $analytics, wikiHistoryService) -> $analytics.trackEvent("wikipage", "create", "create wiki page", 1) $scope.$emit("wikipage:add") - wikiHistoryService.loadHistoryEntries() + activityService.fetchEntries(true) $confirm.notify("success") onError = -> @@ -290,5 +290,5 @@ module.directive("tgWikiWysiwyg", [ "$rootScope", "$tgConfirm", "tgAttachmentsFullService", - "$tgQqueue", "$tgRepo", "$tgAnalytics", "tgWikiHistoryService" + "$tgQqueue", "$tgRepo", "$tgAnalytics", "tgActivityService" WikiWysiwyg]) diff --git a/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee b/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee index 09e369ab..b40858e2 100644 --- a/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee +++ b/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee @@ -23,11 +23,12 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) $scope.saveComment = (description, cb) -> $scope.content = '' - $scope.vm.type.comment = description + $scope.type.comment = description transform = $modelTransform.save (item) -> return transform.then -> - $rootscope.$broadcast("object:updated") + if $scope.onAddComment + $scope.onAddComment() transform.finally(cb) types = { @@ -38,11 +39,11 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) } uploadFile = (file, cb) -> - return attachmentsFullService.addAttachment($scope.vm.projectId, $scope.vm.type.id, types[$scope.vm.type._name], file, true, true).then (result) -> + return attachmentsFullService.addAttachment($scope.vm.projectId, $scope.type.id, types[$scope.type._name], file, true, true).then (result) -> cb(result.getIn(['file', 'name']), result.getIn(['file', 'url'])) $scope.onChange = (markdown) -> - $scope.vm.type.comment = markdown + $scope.type.comment = markdown $scope.uploadFiles = (files, cb) -> for file in files @@ -50,13 +51,16 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) $scope.content = '' - $scope.$watch "vm.type", (value) -> + $scope.$watch "type", (value) -> return if not value $scope.storageKey = "comment-" + value.project + "-" + value.id + "-" + value._name return { - scope: true, + scope: { + type: '=', + onAddComment: '&' + }, link: link, template: """
diff --git a/app/modules/history/activity/activity.service.coffee b/app/modules/history/activity/activity.service.coffee new file mode 100644 index 00000000..ac335540 --- /dev/null +++ b/app/modules/history/activity/activity.service.coffee @@ -0,0 +1,72 @@ +### +# Copyright (C) 2014-2018 Taiga Agile LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# File: history/activity/activity.service.coffee +### + +taiga = @.taiga + +class ActivityService + @.$inject = [ + 'tgResources', + 'tgXhrErrorService' + ] + + constructor: (@rs, @xhrError) -> + @._contentType = null + @._objectId = null + @.clear() + + clear: () -> + @.page = 1 + @.loadingEntries = false + @.disablePagination = false + @.entries = Immutable.List() + @.count = null + + fetchEntries: (reset = false) -> + if reset + @.page = 1 + @.loadingEntries = true + @.disablePagination = true + + return @rs.history.getHistory('activity', @._contentType, @._objectId, @.page) + .then (result) => + if reset + @.clear() + @.entries = result.list + else + @.entries = @.entries.concat(result.list) + + @.loadingEntries = false + @.disablePagination = !result.headers('x-pagination-next') + @.count = result.headers('x-pagination-count') + + return @.entries + .catch (xhr) => + @xhrError.response(@.entries) + + nextPage: (historyType = 'comment') -> + @.page++ + @.fetchEntries() + + init: (contentType, objectId) -> + @._contentType = contentType + @._objectId = objectId + @.clear() + + +angular.module('taigaHistory').service('tgActivityService', ActivityService) diff --git a/app/modules/history/activity/activity.service.spec.coffee b/app/modules/history/activity/activity.service.spec.coffee new file mode 100644 index 00000000..0cbfa63e --- /dev/null +++ b/app/modules/history/activity/activity.service.spec.coffee @@ -0,0 +1,96 @@ +### +# Copyright (C) 2014-2018 Taiga Agile LLC +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +# File: history/activity/activity.service.spec.coffee +### + + +describe "tgActivityService", -> + $provide = null + activityService = null + mocks = {} + + _mockTgResources = () -> + mocks.tgResources = { + history: { + getHistory: sinon.stub() + } + } + $provide.value("tgResources", mocks.tgResources) + + _mockXhrErrorService = () -> + mocks.xhrErrorService = { + response: sinon.stub() + } + + $provide.value "tgXhrErrorService", mocks.xhrErrorService + + _mocks = -> + module (_$provide_) -> + $provide = _$provide_ + + _mockTgResources() + _mockXhrErrorService() + + return null + + _inject = -> + inject (_tgActivityService_) -> + activityService = _tgActivityService_ + + _setup = -> + _mocks() + _inject() + + beforeEach -> + module "taigaHistory" + + _setup() + + fixtures = { + contentType: 'foo', + objId: 43, + page: 1, + response: { + headers: sinon.stub() + list: Immutable.List([ + {id: 1, name: 'history entry 1'}, + {id: 2, name: 'history entry 2'}, + {id: 3, name: 'history entry 3'}, + ]) + } + } + + it "populate history entries", (done) -> + f = fixtures + mocks.tgResources.history.getHistory.withArgs('activity', f.contentType, f.objId, f.page) + .promise().resolve(f.response) + + activityService.init(f.contentType, f.objId) + expect(activityService._objectId).to.be.equal(f.objId) + + expect(activityService.entries.size).to.be.equal(0) + activityService.fetchEntries().then () -> + expect(activityService.entries.size).to.be.equal(3) + done() + + it "reset history entries if objectId change", () -> + f = fixtures + activityService.entries = f.response.list + expect(activityService.entries.size).to.be.equal(3) + + activityService.init(f.contentType, f.objId + 1) + expect(activityService.entries.size).to.be.equal(0) diff --git a/app/modules/history/comments/comments.jade b/app/modules/history/comments/comments.jade index 09a27fcd..24d6e790 100644 --- a/app/modules/history/comments/comments.jade +++ b/app/modules/history/comments/comments.jade @@ -18,6 +18,6 @@ section.comments tg-comment-wysiwyg( tg-check-permission="{{::vm.canAddCommentPermission}}" - on-update="updateComment(text)" + on-add-comment="vm.onAddComment()" type="vm.type" ) diff --git a/app/modules/history/history.controller.coffee b/app/modules/history/history.controller.coffee index 368c413e..bff997ba 100644 --- a/app/modules/history/history.controller.coffee +++ b/app/modules/history/history.controller.coffee @@ -25,30 +25,42 @@ class HistorySectionController "$tgRepo", "$tgStorage", "tgProjectService", + "tgActivityService" ] - constructor: (@rs, @repo, @storage, @projectService) -> + constructor: (@rs, @repo, @storage, @projectService, @activityService) -> @.editing = null @.deleting = null @.editMode = {} @.viewComments = true + @.reverse = @storage.get("orderComments") - @._loadHistory() + + taiga.defineImmutableProperty @, 'disabledActivityPagination', () => + return @activityService.disablePagination + taiga.defineImmutableProperty @, 'loadingActivity', () => + return @activityService.loading _loadHistory: () -> - @rs.history.get(@.name, @.id).then (history) => - @._getComments(history) - @._getActivities(history) + @._loadComments() + @._loadActivity() - _getComments: (comments) -> - @.comments = _.filter(comments, (item) -> item.comment != "") - if @.reverse - @.comments - _.reverse(@.comments) - @.commentsNum = @.comments.length + _loadActivity: () -> + @activityService.init(@.name, @.id) + @activityService.fetchEntries().then (response) => + @.activitiesNum = @activityService.count + @.activities = response.toJS() - _getActivities: (activities) -> - @.activities = _.filter(activities, (item) -> Object.keys(item.values_diff).length > 0) - @.activitiesNum = @.activities.length + _loadComments: () -> + @rs.history.get(@.name, @.id).then (comments) => + @.comments = _.filter(comments, (item) -> item.comment != "") + if @.reverse + @.comments - _.reverse(@.comments) + @.commentsNum = @.comments.length + + nextActivityPage: () -> + @activityService.nextPage().then (response) => + @.activities = response.toJS() showHistorySection: () -> return @.showCommentTab() or @.showActivityTab() @@ -71,7 +83,7 @@ class HistorySectionController activityId = commentId @.deleting = commentId return @rs.history.deleteComment(type, objectId, activityId).then => - @._loadHistory() + @._loadComments() @.deleting = null editComment: (commentId, comment) -> @@ -80,7 +92,7 @@ class HistorySectionController activityId = commentId @.editing = commentId return @rs.history.editComment(type, objectId, activityId, comment).then => - @._loadHistory() + @._loadComments() @.toggleEditMode(commentId) @.editing = null @@ -90,17 +102,17 @@ class HistorySectionController activityId = commentId @.editing = commentId return @rs.history.undeleteComment(type, objectId, activityId).then => - @._loadHistory() + @._loadComments() @.editing = null - addComment: (cb) -> - return @repo.save(@.type).then => - @._loadHistory() - cb() + addComment: () -> + @.editMode = {} + @.editing = null + @._loadComments() onOrderComments: () -> @.reverse = !@.reverse @storage.set("orderComments", @.reverse) - @._loadHistory() + @._loadComments() module.controller("HistorySection", HistorySectionController) diff --git a/app/modules/history/history.controller.spec.coffee b/app/modules/history/history.controller.spec.coffee index d8f6cdd9..46a99520 100644 --- a/app/modules/history/history.controller.spec.coffee +++ b/app/modules/history/history.controller.spec.coffee @@ -54,6 +54,14 @@ describe "HistorySection", -> } provide.value "tgProjectService", mocks.tgProjectService + _mockTgActivityService = () -> + mocks.tgActivityService = { + init: sinon.stub() + fetchEntries: sinon.stub() + count: null + } + provide.value "tgActivityService", mocks.tgActivityService + _mocks = () -> module ($provide) -> provide = $provide @@ -61,6 +69,7 @@ describe "HistorySection", -> _mockTgRepo() _mocktgStorage() _mockTgProjectService() + _mockTgActivityService() return null beforeEach -> @@ -70,61 +79,57 @@ describe "HistorySection", -> inject ($controller) -> controller = $controller - promise = mocks.tgResources.history.get.promise().resolve() + mocks.tgResources.history.get.promise().resolve() + mocks.tgActivityService.fetchEntries.promise().resolve() - it "load historic", (done) -> + it "load historic", () -> historyCtrl = controller "HistorySection" - historyCtrl._getComments = sinon.stub() - historyCtrl._getActivities = sinon.stub() + historyCtrl._loadComments = sinon.stub() + historyCtrl._loadActivity = sinon.stub() - name = "name" - id = 4 - - promise = mocks.tgResources.history.get.withArgs(name, id).promise().resolve() - historyCtrl._loadHistory().then (data) -> - expect(historyCtrl._getComments).have.been.calledWith(data) - expect(historyCtrl._getActivities).have.been.calledWith(data) - done() + historyCtrl._loadHistory() + expect(historyCtrl._loadComments).have.been.called + expect(historyCtrl._loadActivity).have.been.called it "get Comments older first", () -> historyCtrl = controller "HistorySection" - - comments = ['comment3', 'comment2', 'comment1'] + historyCtrl.name = 'foo' + historyCtrl.id = 3 historyCtrl.reverse = false - historyCtrl._getComments(comments) - expect(historyCtrl.comments).to.be.eql(['comment3', 'comment2', 'comment1']) - expect(historyCtrl.commentsNum).to.be.equal(3) + comments = ['comment3', 'comment2', 'comment1'] + mocks.tgResources.history.get.withArgs('foo', 3).promise().resolve(comments) + + historyCtrl._loadComments().then () -> + expect(historyCtrl.comments).to.be.eql(['comment3', 'comment2', 'comment1']) + expect(historyCtrl.commentsNum).to.be.equal(3) it "get Comments newer first", () -> historyCtrl = controller "HistorySection" - - comments = ['comment3', 'comment2', 'comment1'] + historyCtrl.name = 'foo' + historyCtrl.id = 3 historyCtrl.reverse = true - historyCtrl._getComments(comments) - expect(historyCtrl.comments).to.be.eql(['comment1', 'comment2', 'comment3']) - expect(historyCtrl.commentsNum).to.be.equal(3) + comments = ['comment3', 'comment2', 'comment1'] + mocks.tgResources.history.get.withArgs('foo', 3).promise().resolve(comments) + + historyCtrl._loadComments().then () -> + expect(historyCtrl.comments).to.be.eql(['comment1', 'comment2', 'comment3']) + expect(historyCtrl.commentsNum).to.be.equal(3) it "get activities", () -> historyCtrl = controller "HistorySection" - activities = { - 'activity1': { - 'values_diff': {"k1": [0, 1]} - }, - 'activity2': { - 'values_diff': {"k2": [0, 1]} - }, - 'activity3': { - 'values_diff': {"k3": [0, 1]} - }, - } - historyCtrl._getActivities(activities) + activities = Immutable.List([ + {id: 1, name: 'history entry 1'}, + {id: 2, name: 'history entry 2'}, + {id: 3, name: 'history entry 3'}, + ]) + mocks.tgActivityService.fetchEntries.withArgs().promise().resolve(activities) - historyCtrl.activities = activities - expect(historyCtrl.activitiesNum).to.be.equal(3) + historyCtrl._loadActivity().then () -> + expect(historyCtrl.activities.length).to.be.equal(3) it "on active history tab", () -> historyCtrl = controller "HistorySection" @@ -140,7 +145,7 @@ describe "HistorySection", -> it "delete comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadHistory = sinon.stub() + historyCtrl._loadComments = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -149,7 +154,8 @@ describe "HistorySection", -> objectId = historyCtrl.id commentId = 7 - deleteCommentPromise = mocks.tgResources.history.deleteComment.withArgs(type, objectId, commentId).promise() + deleteCommentPromise = mocks.tgResources.history.deleteComment + .withArgs(type, objectId, commentId).promise() ctrlPromise = historyCtrl.deleteComment(commentId) expect(historyCtrl.deleting).to.be.equal(7) @@ -157,12 +163,12 @@ describe "HistorySection", -> deleteCommentPromise.resolve() ctrlPromise.then () -> - expect(historyCtrl._loadHistory).have.been.called + expect(historyCtrl._loadComments).have.been.called expect(historyCtrl.deleting).to.be.null it "edit comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadHistory = sinon.stub() + historyCtrl._loadComments = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -173,16 +179,17 @@ describe "HistorySection", -> objectId = historyCtrl.id commentId = activityId - promise = mocks.tgResources.history.editComment.withArgs(type, objectId, activityId, comment).promise().resolve() + promise = mocks.tgResources.history.editComment + .withArgs(type, objectId, activityId, comment).promise().resolve() historyCtrl.editing = 7 historyCtrl.editComment(commentId, comment).then () -> - expect(historyCtrl._loadHistory).has.been.called + expect(historyCtrl._loadComments).has.been.called expect(historyCtrl.editing).to.be.null it "restore comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadHistory = sinon.stub() + historyCtrl._loadComments = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -196,12 +203,12 @@ describe "HistorySection", -> historyCtrl.editing = 7 historyCtrl.restoreDeletedComment(commentId).then () -> - expect(historyCtrl._loadHistory).has.been.called + expect(historyCtrl._loadComments).has.been.called expect(historyCtrl.editing).to.be.null it "add comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadHistory = sinon.stub() + historyCtrl._loadComments = sinon.stub() historyCtrl.type = "type" type = historyCtrl.type @@ -210,18 +217,17 @@ describe "HistorySection", -> promise = mocks.tgRepo.save.withArgs(type).promise().resolve() - historyCtrl.addComment(cb).then () -> - expect(historyCtrl._loadHistory).has.been.called - expect(cb).to.have.been.called + historyCtrl.addComment() + expect(historyCtrl._loadComments).has.been.called it "order comments", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadHistory = sinon.stub() + historyCtrl._loadComments = sinon.stub() historyCtrl.reverse = false historyCtrl.onOrderComments() expect(historyCtrl.reverse).to.be.true expect(mocks.tgStorage.set).has.been.calledWith("orderComments", historyCtrl.reverse) - expect(historyCtrl._loadHistory).has.been.called + expect(historyCtrl._loadComments).has.been.called diff --git a/app/modules/history/history.directive.coffee b/app/modules/history/history.directive.coffee index 617f8956..efaf4df3 100644 --- a/app/modules/history/history.directive.coffee +++ b/app/modules/history/history.directive.coffee @@ -19,9 +19,14 @@ module = angular.module('taigaHistory') +bindOnce = @.taiga.bindOnce + HistorySectionDirective = () -> link = (scope, el, attr, ctrl) -> - scope.$on "object:updated", -> ctrl._loadHistory(scope.type, scope.id) + scope.$on "object:updated", -> ctrl._loadActivity() + + scope.$watch 'vm.id', (value) -> + ctrl._loadHistory() return { link: link, diff --git a/app/modules/history/history.jade b/app/modules/history/history.jade index 12ef2b08..aad57410 100644 --- a/app/modules/history/history.jade +++ b/app/modules/history/history.jade @@ -30,7 +30,10 @@ section.history( deleting="vm.deleting" project-id="vm.projectId" ) - tg-history( + div( ng-if="!vm.viewComments" - activities="vm.activities" + infinite-scroll="vm.nextActivityPage()" + infinite-scroll-disabled="vm.disabledActivityPagination" + infinite-scroll-immediate-check="false" ) + tg-history(activities="vm.activities") diff --git a/app/modules/resources/wiki-resource.service.coffee b/app/modules/resources/history-resource.service.coffee similarity index 65% rename from app/modules/resources/wiki-resource.service.coffee rename to app/modules/resources/history-resource.service.coffee index 42406567..89ffc829 100644 --- a/app/modules/resources/wiki-resource.service.coffee +++ b/app/modules/resources/history-resource.service.coffee @@ -14,29 +14,25 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -# File: resources/wiki-resource.service.coffee +# File: resources/history-resource.service.coffee ### Resource = (urlsService, http) -> service = {} - service.getWikiHistory = (wikiId) -> - url = urlsService.resolve("history/wiki", wikiId) - - httpOptions = { - headers: { - "x-disable-pagination": "1" - } - } - - return http.get(url, null, httpOptions) + service.getHistory = (historyType, contentType, objectId, page) -> + url = urlsService.resolve("history/#{contentType}", ) + return http.get("#{url}/#{objectId}", {page: page, type: historyType}) .then (result) -> - return Immutable.fromJS(result.data) + return { + list: Immutable.fromJS(result.data) + headers: result.headers + } return () -> - return {"wikiHistory": service} + return {"history": service} Resource.$inject = ["$tgUrls", "$tgHttp"] module = angular.module("taigaResources2") -module.factory("tgWikiHistory", Resource) +module.factory("tgHistory", Resource) diff --git a/app/modules/resources/resources.coffee b/app/modules/resources/resources.coffee index c68f9a67..70c36bda 100644 --- a/app/modules/resources/resources.coffee +++ b/app/modules/resources/resources.coffee @@ -27,7 +27,7 @@ services = [ "tgExternalAppsResource", "tgAttachmentsResource", "tgStatsResource", - "tgWikiHistory", + "tgHistory", "tgEpicsResource", "tgTrelloImportResource", "tgJiraImportResource", diff --git a/app/modules/wiki/history/wiki-history.controller.coffee b/app/modules/wiki/history/wiki-history.controller.coffee index 61b0c843..d1e75552 100644 --- a/app/modules/wiki/history/wiki-history.controller.coffee +++ b/app/modules/wiki/history/wiki-history.controller.coffee @@ -23,17 +23,25 @@ module = angular.module("taigaWikiHistory") class WikiHistoryController @.$inject = [ - "tgWikiHistoryService" + "tgActivityService" ] - constructor: (@wikiHistoryService) -> - taiga.defineImmutableProperty @, 'historyEntries', () => return @wikiHistoryService.historyEntries + constructor: (@activityService) -> + taiga.defineImmutableProperty @, 'historyEntries', () => + return @activityService.entries + taiga.defineImmutableProperty @, 'disablePagination', () => + return @activityService.disablePagination @.toggle = false - initializeHistoryEntries: (wikiId) -> + initializeHistory: (wikiId) -> if wikiId - @wikiHistoryService.setWikiId(wikiId) + @activityService.init('wiki', wikiId) + @.loadHistory() - @wikiHistoryService.loadHistoryEntries() + loadHistory: ()-> + @activityService.fetchEntries() + + nextPage: () -> + @activityService.nextPage() module.controller("WikiHistoryCtrl", WikiHistoryController) diff --git a/app/modules/wiki/history/wiki-history.controller.spec.coffee b/app/modules/wiki/history/wiki-history.controller.spec.coffee index 2eaf171e..069df315 100644 --- a/app/modules/wiki/history/wiki-history.controller.spec.coffee +++ b/app/modules/wiki/history/wiki-history.controller.spec.coffee @@ -22,18 +22,18 @@ describe "WikiHistorySection", -> controller = null mocks = {} - _mockTgWikiHistoryService = () -> - mocks.tgWikiHistoryService = { - setWikiId: sinon.stub(), - loadHistoryEntries: sinon.stub() + _mockTgActivityService = () -> + mocks.tgActivityService = { + init: sinon.stub(), + fetchEntries: sinon.stub() } - provide.value "tgWikiHistoryService", mocks.tgWikiHistoryService + provide.value "tgActivityService", mocks.tgActivityService _mocks = () -> module ($provide) -> provide = $provide - _mockTgWikiHistoryService() + _mockTgActivityService() return null beforeEach -> @@ -44,19 +44,19 @@ describe "WikiHistorySection", -> inject ($controller) -> controller = $controller - it "initialize histori entries with id", -> + it "initialize history entries with id", -> wikiId = 42 historyCtrl = controller "WikiHistoryCtrl" - historyCtrl.initializeHistoryEntries(wikiId) + historyCtrl.initializeHistory(wikiId) - expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledOnce - expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledWith(wikiId) - expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce + expect(mocks.tgActivityService.init).to.be.calledOnce + expect(mocks.tgActivityService.init).to.be.calledWith('wiki', wikiId) + expect(mocks.tgActivityService.fetchEntries).to.be.calledOnce it "initialize history entries without id", -> historyCtrl = controller "WikiHistoryCtrl" - historyCtrl.initializeHistoryEntries() + historyCtrl.initializeHistory() - expect(mocks.tgWikiHistoryService.setWikiId).to.not.be.calledOnce - expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce + expect(mocks.tgActivityService.init).to.not.be.calledOnce + expect(mocks.tgActivityService.fetchEntries).to.be.calledOnce diff --git a/app/modules/wiki/history/wiki-history.directive.coffee b/app/modules/wiki/history/wiki-history.directive.coffee index 39243b16..d8fe0615 100644 --- a/app/modules/wiki/history/wiki-history.directive.coffee +++ b/app/modules/wiki/history/wiki-history.directive.coffee @@ -25,7 +25,7 @@ module = angular.module('taigaWikiHistory') WikiHistoryDirective = () -> link = (scope, el, attrs, ctrl) -> bindOnce scope, 'vm.wikiId', (value) -> - ctrl.initializeHistoryEntries(value) + ctrl.initializeHistory(value) return { scope: {}, diff --git a/app/modules/wiki/history/wiki-history.jade b/app/modules/wiki/history/wiki-history.jade index b093fbe6..7535d47c 100644 --- a/app/modules/wiki/history/wiki-history.jade +++ b/app/modules/wiki/history/wiki-history.jade @@ -6,8 +6,13 @@ nav.history-tabs(ng-if="vm.historyEntries.count()>0") title="{{ACTIVITY.TITLE}}" translate="ACTIVITY.TITLE" ) - -section.wiki-history(ng-if="vm.historyEntries.count()>0 && vm.toggle") +p {{ disablePagination }} +section.wiki-history( + ng-if="vm.historyEntries.count()>0 && vm.toggle" + infinite-scroll="vm.nextPage()" + infinite-scroll-immediate-check="false" + infinite-scroll-disabled="vm.disablePagination" +) tg-wiki-history-entry.wiki-history-entry( tg-repeat="historyEntry in vm.historyEntries" history-entry="historyEntry" diff --git a/app/modules/wiki/history/wiki-history.service.coffee b/app/modules/wiki/history/wiki-history.service.coffee deleted file mode 100644 index 2acc177d..00000000 --- a/app/modules/wiki/history/wiki-history.service.coffee +++ /dev/null @@ -1,51 +0,0 @@ -### -# Copyright (C) 2014-2018 Taiga Agile LLC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# File: wiki/history/wiki-history.service.coffee -### - -taiga = @.taiga - -module = angular.module('taigaWikiHistory') - -class WikiHistoryService extends taiga.Service - @.$inject = [ - "tgResources" - "tgXhrErrorService" - ] - - constructor: (@rs, @xhrError) -> - @._wikiId = null - @._historyEntries = Immutable.List() - - taiga.defineImmutableProperty @, "wikiId", () => return @._wikiId - taiga.defineImmutableProperty @, "historyEntries", () => return @._historyEntries - - setWikiId: (wikiId) -> - @._wikiId = wikiId - @._historyEntries = Immutable.List() - - loadHistoryEntries: () -> - return if not @._wikiId - - return @rs.wikiHistory.getWikiHistory(@._wikiId) - .then (historyEntries) => - if historyEntries.size - @._historyEntries = historyEntries.reverse() - .catch (xhr) => - @xhrError.response(xhr) - _ -module.service("tgWikiHistoryService", WikiHistoryService) diff --git a/app/modules/wiki/history/wiki-history.service.spec.coffee b/app/modules/wiki/history/wiki-history.service.spec.coffee deleted file mode 100644 index be03aaac..00000000 --- a/app/modules/wiki/history/wiki-history.service.spec.coffee +++ /dev/null @@ -1,92 +0,0 @@ -### -# Copyright (C) 2014-2018 Taiga Agile LLC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -# File: wiki/history/wiki-history.service.spec.coffee -### - - -describe "tgWikiHistoryService", -> - $provide = null - wikiHistoryService = null - mocks = {} - - _mockTgResources = () -> - mocks.tgResources = { - wikiHistory: { - getWikiHistory: sinon.stub() - } - } - $provide.value("tgResources", mocks.tgResources) - - _mockXhrErrorService = () -> - mocks.xhrErrorService = { - response: sinon.stub() - } - - $provide.value "tgXhrErrorService", mocks.xhrErrorService - - _mocks = -> - module (_$provide_) -> - $provide = _$provide_ - - _mockTgResources() - _mockXhrErrorService() - - return null - - _inject = -> - inject (_tgWikiHistoryService_) -> - wikiHistoryService = _tgWikiHistoryService_ - - _setup = -> - _mocks() - _inject() - - beforeEach -> - module "taigaWikiHistory" - - _setup() - - it "populate history entries", (done) -> - wikiId = 42 - historyEntries = Immutable.List([ - {id: 1, name: 'history entrie 1'}, - {id: 2, name: 'history entrie 2'}, - {id: 3, name: 'history entrie 3'}, - ]) - - mocks.tgResources.wikiHistory.getWikiHistory.withArgs(wikiId).promise().resolve(historyEntries) - - wikiHistoryService.setWikiId(wikiId) - expect(wikiHistoryService.wikiId).to.be.equal(wikiId) - - expect(wikiHistoryService.historyEntries.size).to.be.equal(0) - wikiHistoryService.loadHistoryEntries().then () -> - expect(wikiHistoryService.historyEntries.size).to.be.equal(3) - done() - - it "reset history entries if wikiId change", () -> - wikiId = 42 - - wikiHistoryService._historyEntries = Immutable.List([ - {id: 1, name: 'history entrie 1'}, - {id: 2, name: 'history entrie 2'}, - {id: 3, name: 'history entrie 3'}, - ]) - - expect(wikiHistoryService.historyEntries.size).to.be.equal(3) - wikiHistoryService.setWikiId(wikiId) - expect(wikiHistoryService.historyEntries.size).to.be.equal(0)