diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index 344c68a1..6ea2affd 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -148,7 +148,7 @@ urls = { "history/us": "/history/userstory" "history/issue": "/history/issue" "history/task": "/history/task" - "history/wiki": "/history/wiki" + "history/wiki": "/history/wiki/%s" # Attachments "attachments/epic": "/epics/attachments" diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index aefaf6bb..8f4d998d 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, activityService) -> +$qqueue, $repo, $analytics, wikiHistoryService) -> link = ($scope, $el, $attrs) -> $scope.editableDescription = false @@ -223,7 +223,7 @@ $qqueue, $repo, $analytics, activityService) -> $analytics.trackEvent("wikipage", "create", "create wiki page", 1) $scope.$emit("wikipage:add") - activityService.fetchEntries(true) + wikiHistoryService.loadHistoryEntries() $confirm.notify("success") onError = -> @@ -290,5 +290,5 @@ module.directive("tgWikiWysiwyg", [ "$rootScope", "$tgConfirm", "tgAttachmentsFullService", - "$tgQqueue", "$tgRepo", "$tgAnalytics", "tgActivityService" + "$tgQqueue", "$tgRepo", "$tgAnalytics", "tgWikiHistoryService" WikiWysiwyg]) diff --git a/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee b/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee index b40858e2..09e369ab 100644 --- a/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee +++ b/app/modules/components/wysiwyg/comment-wysiwyg.directive.coffee @@ -23,12 +23,11 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) $scope.saveComment = (description, cb) -> $scope.content = '' - $scope.type.comment = description + $scope.vm.type.comment = description transform = $modelTransform.save (item) -> return transform.then -> - if $scope.onAddComment - $scope.onAddComment() + $rootscope.$broadcast("object:updated") transform.finally(cb) types = { @@ -39,11 +38,11 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) } uploadFile = (file, cb) -> - return attachmentsFullService.addAttachment($scope.vm.projectId, $scope.type.id, types[$scope.type._name], file, true, true).then (result) -> + return attachmentsFullService.addAttachment($scope.vm.projectId, $scope.vm.type.id, types[$scope.vm.type._name], file, true, true).then (result) -> cb(result.getIn(['file', 'name']), result.getIn(['file', 'url'])) $scope.onChange = (markdown) -> - $scope.type.comment = markdown + $scope.vm.type.comment = markdown $scope.uploadFiles = (files, cb) -> for file in files @@ -51,16 +50,13 @@ CommentWysiwyg = ($modelTransform, $rootscope, $confirm, attachmentsFullService) $scope.content = '' - $scope.$watch "type", (value) -> + $scope.$watch "vm.type", (value) -> return if not value $scope.storageKey = "comment-" + value.project + "-" + value.id + "-" + value._name return { - scope: { - type: '=', - onAddComment: '&' - }, + scope: true, link: link, template: """
diff --git a/app/modules/history/activity/activity.service.coffee b/app/modules/history/activity/activity.service.coffee deleted file mode 100644 index ac335540..00000000 --- a/app/modules/history/activity/activity.service.coffee +++ /dev/null @@ -1,72 +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: 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 deleted file mode 100644 index 0cbfa63e..00000000 --- a/app/modules/history/activity/activity.service.spec.coffee +++ /dev/null @@ -1,96 +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: 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 24d6e790..09a27fcd 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-add-comment="vm.onAddComment()" + on-update="updateComment(text)" type="vm.type" ) diff --git a/app/modules/history/history.controller.coffee b/app/modules/history/history.controller.coffee index bff997ba..368c413e 100644 --- a/app/modules/history/history.controller.coffee +++ b/app/modules/history/history.controller.coffee @@ -25,42 +25,30 @@ class HistorySectionController "$tgRepo", "$tgStorage", "tgProjectService", - "tgActivityService" ] - constructor: (@rs, @repo, @storage, @projectService, @activityService) -> + constructor: (@rs, @repo, @storage, @projectService) -> @.editing = null @.deleting = null @.editMode = {} @.viewComments = true - @.reverse = @storage.get("orderComments") - - taiga.defineImmutableProperty @, 'disabledActivityPagination', () => - return @activityService.disablePagination - taiga.defineImmutableProperty @, 'loadingActivity', () => - return @activityService.loading + @._loadHistory() _loadHistory: () -> - @._loadComments() - @._loadActivity() + @rs.history.get(@.name, @.id).then (history) => + @._getComments(history) + @._getActivities(history) - _loadActivity: () -> - @activityService.init(@.name, @.id) - @activityService.fetchEntries().then (response) => - @.activitiesNum = @activityService.count - @.activities = response.toJS() + _getComments: (comments) -> + @.comments = _.filter(comments, (item) -> item.comment != "") + if @.reverse + @.comments - _.reverse(@.comments) + @.commentsNum = @.comments.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() + _getActivities: (activities) -> + @.activities = _.filter(activities, (item) -> Object.keys(item.values_diff).length > 0) + @.activitiesNum = @.activities.length showHistorySection: () -> return @.showCommentTab() or @.showActivityTab() @@ -83,7 +71,7 @@ class HistorySectionController activityId = commentId @.deleting = commentId return @rs.history.deleteComment(type, objectId, activityId).then => - @._loadComments() + @._loadHistory() @.deleting = null editComment: (commentId, comment) -> @@ -92,7 +80,7 @@ class HistorySectionController activityId = commentId @.editing = commentId return @rs.history.editComment(type, objectId, activityId, comment).then => - @._loadComments() + @._loadHistory() @.toggleEditMode(commentId) @.editing = null @@ -102,17 +90,17 @@ class HistorySectionController activityId = commentId @.editing = commentId return @rs.history.undeleteComment(type, objectId, activityId).then => - @._loadComments() + @._loadHistory() @.editing = null - addComment: () -> - @.editMode = {} - @.editing = null - @._loadComments() + addComment: (cb) -> + return @repo.save(@.type).then => + @._loadHistory() + cb() onOrderComments: () -> @.reverse = !@.reverse @storage.set("orderComments", @.reverse) - @._loadComments() + @._loadHistory() module.controller("HistorySection", HistorySectionController) diff --git a/app/modules/history/history.controller.spec.coffee b/app/modules/history/history.controller.spec.coffee index 46a99520..d8f6cdd9 100644 --- a/app/modules/history/history.controller.spec.coffee +++ b/app/modules/history/history.controller.spec.coffee @@ -54,14 +54,6 @@ 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 @@ -69,7 +61,6 @@ describe "HistorySection", -> _mockTgRepo() _mocktgStorage() _mockTgProjectService() - _mockTgActivityService() return null beforeEach -> @@ -79,57 +70,61 @@ describe "HistorySection", -> inject ($controller) -> controller = $controller - mocks.tgResources.history.get.promise().resolve() - mocks.tgActivityService.fetchEntries.promise().resolve() + promise = mocks.tgResources.history.get.promise().resolve() - it "load historic", () -> + it "load historic", (done) -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() - historyCtrl._loadActivity = sinon.stub() + historyCtrl._getComments = sinon.stub() + historyCtrl._getActivities = sinon.stub() - historyCtrl._loadHistory() - expect(historyCtrl._loadComments).have.been.called - expect(historyCtrl._loadActivity).have.been.called + 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() it "get Comments older first", () -> historyCtrl = controller "HistorySection" - historyCtrl.name = 'foo' - historyCtrl.id = 3 - historyCtrl.reverse = false comments = ['comment3', 'comment2', 'comment1'] - mocks.tgResources.history.get.withArgs('foo', 3).promise().resolve(comments) + historyCtrl.reverse = false - historyCtrl._loadComments().then () -> - expect(historyCtrl.comments).to.be.eql(['comment3', 'comment2', 'comment1']) - expect(historyCtrl.commentsNum).to.be.equal(3) + historyCtrl._getComments(comments) + expect(historyCtrl.comments).to.be.eql(['comment3', 'comment2', 'comment1']) + expect(historyCtrl.commentsNum).to.be.equal(3) it "get Comments newer first", () -> historyCtrl = controller "HistorySection" - historyCtrl.name = 'foo' - historyCtrl.id = 3 - historyCtrl.reverse = true comments = ['comment3', 'comment2', 'comment1'] - mocks.tgResources.history.get.withArgs('foo', 3).promise().resolve(comments) + historyCtrl.reverse = true - historyCtrl._loadComments().then () -> - expect(historyCtrl.comments).to.be.eql(['comment1', 'comment2', 'comment3']) - expect(historyCtrl.commentsNum).to.be.equal(3) + historyCtrl._getComments(comments) + 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]} + }, + } - 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._getActivities(activities) - historyCtrl._loadActivity().then () -> - expect(historyCtrl.activities.length).to.be.equal(3) + historyCtrl.activities = activities + expect(historyCtrl.activitiesNum).to.be.equal(3) it "on active history tab", () -> historyCtrl = controller "HistorySection" @@ -145,7 +140,7 @@ describe "HistorySection", -> it "delete comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() + historyCtrl._loadHistory = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -154,8 +149,7 @@ 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) @@ -163,12 +157,12 @@ describe "HistorySection", -> deleteCommentPromise.resolve() ctrlPromise.then () -> - expect(historyCtrl._loadComments).have.been.called + expect(historyCtrl._loadHistory).have.been.called expect(historyCtrl.deleting).to.be.null it "edit comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() + historyCtrl._loadHistory = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -179,17 +173,16 @@ 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._loadComments).has.been.called + expect(historyCtrl._loadHistory).has.been.called expect(historyCtrl.editing).to.be.null it "restore comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() + historyCtrl._loadHistory = sinon.stub() historyCtrl.name = "type" historyCtrl.id = 1 @@ -203,12 +196,12 @@ describe "HistorySection", -> historyCtrl.editing = 7 historyCtrl.restoreDeletedComment(commentId).then () -> - expect(historyCtrl._loadComments).has.been.called + expect(historyCtrl._loadHistory).has.been.called expect(historyCtrl.editing).to.be.null it "add comment", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() + historyCtrl._loadHistory = sinon.stub() historyCtrl.type = "type" type = historyCtrl.type @@ -217,17 +210,18 @@ describe "HistorySection", -> promise = mocks.tgRepo.save.withArgs(type).promise().resolve() - historyCtrl.addComment() - expect(historyCtrl._loadComments).has.been.called + historyCtrl.addComment(cb).then () -> + expect(historyCtrl._loadHistory).has.been.called + expect(cb).to.have.been.called it "order comments", () -> historyCtrl = controller "HistorySection" - historyCtrl._loadComments = sinon.stub() + historyCtrl._loadHistory = 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._loadComments).has.been.called + expect(historyCtrl._loadHistory).has.been.called diff --git a/app/modules/history/history.directive.coffee b/app/modules/history/history.directive.coffee index efaf4df3..617f8956 100644 --- a/app/modules/history/history.directive.coffee +++ b/app/modules/history/history.directive.coffee @@ -19,14 +19,9 @@ module = angular.module('taigaHistory') -bindOnce = @.taiga.bindOnce - HistorySectionDirective = () -> link = (scope, el, attr, ctrl) -> - scope.$on "object:updated", -> ctrl._loadActivity() - - scope.$watch 'vm.id', (value) -> - ctrl._loadHistory() + scope.$on "object:updated", -> ctrl._loadHistory(scope.type, scope.id) return { link: link, diff --git a/app/modules/history/history.jade b/app/modules/history/history.jade index aad57410..12ef2b08 100644 --- a/app/modules/history/history.jade +++ b/app/modules/history/history.jade @@ -30,10 +30,7 @@ section.history( deleting="vm.deleting" project-id="vm.projectId" ) - div( + tg-history( ng-if="!vm.viewComments" - infinite-scroll="vm.nextActivityPage()" - infinite-scroll-disabled="vm.disabledActivityPagination" - infinite-scroll-immediate-check="false" + activities="vm.activities" ) - tg-history(activities="vm.activities") diff --git a/app/modules/resources/resources.coffee b/app/modules/resources/resources.coffee index 70c36bda..c68f9a67 100644 --- a/app/modules/resources/resources.coffee +++ b/app/modules/resources/resources.coffee @@ -27,7 +27,7 @@ services = [ "tgExternalAppsResource", "tgAttachmentsResource", "tgStatsResource", - "tgHistory", + "tgWikiHistory", "tgEpicsResource", "tgTrelloImportResource", "tgJiraImportResource", diff --git a/app/modules/resources/history-resource.service.coffee b/app/modules/resources/wiki-resource.service.coffee similarity index 65% rename from app/modules/resources/history-resource.service.coffee rename to app/modules/resources/wiki-resource.service.coffee index 89ffc829..42406567 100644 --- a/app/modules/resources/history-resource.service.coffee +++ b/app/modules/resources/wiki-resource.service.coffee @@ -14,25 +14,29 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # -# File: resources/history-resource.service.coffee +# File: resources/wiki-resource.service.coffee ### Resource = (urlsService, http) -> service = {} - service.getHistory = (historyType, contentType, objectId, page) -> - url = urlsService.resolve("history/#{contentType}", ) - return http.get("#{url}/#{objectId}", {page: page, type: historyType}) + service.getWikiHistory = (wikiId) -> + url = urlsService.resolve("history/wiki", wikiId) + + httpOptions = { + headers: { + "x-disable-pagination": "1" + } + } + + return http.get(url, null, httpOptions) .then (result) -> - return { - list: Immutable.fromJS(result.data) - headers: result.headers - } + return Immutable.fromJS(result.data) return () -> - return {"history": service} + return {"wikiHistory": service} Resource.$inject = ["$tgUrls", "$tgHttp"] module = angular.module("taigaResources2") -module.factory("tgHistory", Resource) +module.factory("tgWikiHistory", Resource) diff --git a/app/modules/wiki/history/wiki-history.controller.coffee b/app/modules/wiki/history/wiki-history.controller.coffee index d1e75552..61b0c843 100644 --- a/app/modules/wiki/history/wiki-history.controller.coffee +++ b/app/modules/wiki/history/wiki-history.controller.coffee @@ -23,25 +23,17 @@ module = angular.module("taigaWikiHistory") class WikiHistoryController @.$inject = [ - "tgActivityService" + "tgWikiHistoryService" ] - constructor: (@activityService) -> - taiga.defineImmutableProperty @, 'historyEntries', () => - return @activityService.entries - taiga.defineImmutableProperty @, 'disablePagination', () => - return @activityService.disablePagination + constructor: (@wikiHistoryService) -> + taiga.defineImmutableProperty @, 'historyEntries', () => return @wikiHistoryService.historyEntries @.toggle = false - initializeHistory: (wikiId) -> + initializeHistoryEntries: (wikiId) -> if wikiId - @activityService.init('wiki', wikiId) - @.loadHistory() + @wikiHistoryService.setWikiId(wikiId) - loadHistory: ()-> - @activityService.fetchEntries() - - nextPage: () -> - @activityService.nextPage() + @wikiHistoryService.loadHistoryEntries() 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 069df315..2eaf171e 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 = {} - _mockTgActivityService = () -> - mocks.tgActivityService = { - init: sinon.stub(), - fetchEntries: sinon.stub() + _mockTgWikiHistoryService = () -> + mocks.tgWikiHistoryService = { + setWikiId: sinon.stub(), + loadHistoryEntries: sinon.stub() } - provide.value "tgActivityService", mocks.tgActivityService + provide.value "tgWikiHistoryService", mocks.tgWikiHistoryService _mocks = () -> module ($provide) -> provide = $provide - _mockTgActivityService() + _mockTgWikiHistoryService() return null beforeEach -> @@ -44,19 +44,19 @@ describe "WikiHistorySection", -> inject ($controller) -> controller = $controller - it "initialize history entries with id", -> + it "initialize histori entries with id", -> wikiId = 42 historyCtrl = controller "WikiHistoryCtrl" - historyCtrl.initializeHistory(wikiId) + historyCtrl.initializeHistoryEntries(wikiId) - expect(mocks.tgActivityService.init).to.be.calledOnce - expect(mocks.tgActivityService.init).to.be.calledWith('wiki', wikiId) - expect(mocks.tgActivityService.fetchEntries).to.be.calledOnce + expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledOnce + expect(mocks.tgWikiHistoryService.setWikiId).to.be.calledWith(wikiId) + expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce it "initialize history entries without id", -> historyCtrl = controller "WikiHistoryCtrl" - historyCtrl.initializeHistory() + historyCtrl.initializeHistoryEntries() - expect(mocks.tgActivityService.init).to.not.be.calledOnce - expect(mocks.tgActivityService.fetchEntries).to.be.calledOnce + expect(mocks.tgWikiHistoryService.setWikiId).to.not.be.calledOnce + expect(mocks.tgWikiHistoryService.loadHistoryEntries).to.be.calledOnce diff --git a/app/modules/wiki/history/wiki-history.directive.coffee b/app/modules/wiki/history/wiki-history.directive.coffee index d8fe0615..39243b16 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.initializeHistory(value) + ctrl.initializeHistoryEntries(value) return { scope: {}, diff --git a/app/modules/wiki/history/wiki-history.jade b/app/modules/wiki/history/wiki-history.jade index 7535d47c..b093fbe6 100644 --- a/app/modules/wiki/history/wiki-history.jade +++ b/app/modules/wiki/history/wiki-history.jade @@ -6,13 +6,8 @@ nav.history-tabs(ng-if="vm.historyEntries.count()>0") title="{{ACTIVITY.TITLE}}" translate="ACTIVITY.TITLE" ) -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" -) + +section.wiki-history(ng-if="vm.historyEntries.count()>0 && vm.toggle") 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 new file mode 100644 index 00000000..2acc177d --- /dev/null +++ b/app/modules/wiki/history/wiki-history.service.coffee @@ -0,0 +1,51 @@ +### +# 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 new file mode 100644 index 00000000..be03aaac --- /dev/null +++ b/app/modules/wiki/history/wiki-history.service.spec.coffee @@ -0,0 +1,92 @@ +### +# 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)