From cc04ee80a60dfb01e02a9a53831933b2dc8ef7e3 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 10 Sep 2014 12:36:52 +0200 Subject: [PATCH 1/3] Remove unused local variables on main common module file. --- app/coffee/modules/common.coffee | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/coffee/modules/common.coffee b/app/coffee/modules/common.coffee index cb3b0db1..a84b5ccd 100644 --- a/app/coffee/modules/common.coffee +++ b/app/coffee/modules/common.coffee @@ -21,9 +21,6 @@ taiga = @.taiga -trim = @.taiga.trim -typeIsArray = @.taiga.typeIsArray - module = angular.module("taigaCommon", []) ############################################################################# From bf732f7a179629cb2483d90c28449aabc5287f71 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 10 Sep 2014 12:37:18 +0200 Subject: [PATCH 2/3] Simplify the tg-check-permission directive. --- app/coffee/modules/common.coffee | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/coffee/modules/common.coffee b/app/coffee/modules/common.coffee index a84b5ccd..d4fd3c65 100644 --- a/app/coffee/modules/common.coffee +++ b/app/coffee/modules/common.coffee @@ -28,19 +28,15 @@ module = angular.module("taigaCommon", []) ############################################################################# CheckPermissionDirective = -> - showElementIfPermission = (element, permission, project) -> - element.show() if project.my_permissions.indexOf(permission) > -1 + render = ($el, project, permission) -> + $el.show() if project.my_permissions.indexOf(permission) > -1 link = ($scope, $el, $attrs) -> $el.hide() permission = $attrs.tgCheckPermission - #Sometimes this directive from a self included html template - if $scope.project? - showElementIfPermission($el, permission, $scope.project) - - $scope.$on "project:loaded", (ctx, project) -> - showElementIfPermission($el, permission, project) + $scope.$watch "project", (project) -> + render($el, project, permission) if project? $scope.$on "$destroy", -> $el.off() From 4bd1f40893f0a48990764e116055107f19457a73 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 10 Sep 2014 12:38:03 +0200 Subject: [PATCH 3/3] Rewrite attachments directives and make them work as isolated components. Also, it fixes #914 issue. --- app/coffee/modules/common/attachments.coffee | 394 ++++++++++++------- app/coffee/modules/controllerMixins.coffee | 41 -- app/coffee/modules/issues/detail.coffee | 7 +- app/coffee/modules/resources.coffee | 8 +- app/coffee/modules/tasks/detail.coffee | 5 +- app/coffee/modules/userstories/detail.coffee | 6 +- app/coffee/modules/wiki/main.coffee | 6 +- app/partials/issues-detail-edit.jade | 5 +- app/partials/issues-detail.jade | 5 +- app/partials/task-detail-edit.jade | 5 +- app/partials/task-detail.jade | 5 +- app/partials/us-detail-edit.jade | 5 +- app/partials/us-detail.jade | 5 +- app/partials/views/modules/attachments.jade | 31 -- app/partials/wiki-edit.jade | 4 +- app/partials/wiki.jade | 4 +- app/styles/modules/common/attachments.scss | 9 +- 17 files changed, 269 insertions(+), 276 deletions(-) delete mode 100644 app/partials/views/modules/attachments.jade diff --git a/app/coffee/modules/common/attachments.coffee b/app/coffee/modules/common/attachments.coffee index edef5486..7a4bf87b 100644 --- a/app/coffee/modules/common/attachments.coffee +++ b/app/coffee/modules/common/attachments.coffee @@ -21,22 +21,189 @@ taiga = @.taiga sizeFormat = @.taiga.sizeFormat +bindOnce = @.taiga.bindOnce module = angular.module("taigaCommon") -############################################################################# -## Attachments Directive -############################################################################# +class AttachmentsController extends taiga.Controller + @.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$tgConfirm", "$q"] -AttachmentsDirective = ($repo, $rs, $confirm) -> - link = ($scope, $el, $attrs, $model) -> - $ctrl = $el.controller() - $scope.uploadingFiles = [] + constructor: (@scope, @rootscope, @repo, @rs, @confirm, @q) -> + _.bindAll(@) + @.type = null + @.objectId = null + + @.uploadingAttachments = [] + @.attachments = [] + @.attachmentsCount = 0 + @.deprecatedAttachmentsCount = 0 + @.showDeprecated = false + + initialize: (type, objectId) -> + @.type = type + @.objectId = objectId + + loadAttachments: -> + urlname = "attachments/#{@.type}" + id = @.objectId + + return @rs.attachments.list(urlname, id).then (attachments) => + @.attachments = _.sortBy(attachments, "order") + @.updateCounters() + return attachments + + updateCounters: -> + @.attachmentsCount = @.attachments.length + @.deprecatedAttachmentsCount = _.filter(@.attachments, {is_deprecated: true}).length + + _createAttachment: (attachment) -> + projectId = @scope.projectId + urlName = "attachments/#{@.type}" + + promise = @rs.attachments.create(urlName, projectId, @.objectId, attachment) + promise = promise.then (data) => + data.isCreatedRightNow = true + + index = @.uploadingAttachments.indexOf(attachment) + @.uploadingAttachments.splice(index, 1) + @.attachments.push(data) + @rootscope.$broadcast("attachment:create") + + promise = promise.then null, (data) -> + index = @.uploadingAttachments.indexOf(attachment) + @.uploadingAttachments.splice(index, 1) + @confirm.notify("error", null, "We have not been able to upload '#{attachment.name}'.") + return @q.reject(data) + + return promise + + # Create attachments in bulk + createAttachments: (attachments) -> + promises = _.map(attachments, (x) => @._createAttachment(x)) + return @q.all.apply(null, promises).then => + @.updateCounters() + + # Add uploading attachment tracking. + addUploadingAttachments: (attachments) -> + @.uploadingAttachments = _.union(@.uploadingAttachments, attachments) + + # Change order of attachment in a ordered list. + # This function is mainly executed after sortable ends. + reorderAttachment: (attachment, newIndex) -> + oldIndex = @.attachments.indexOf(attachment) + return if oldIndex == newIndex + + @.attachments.splice(oldIndex, 1) + @.attachments.splice(newIndex, 0, attachment) + + _.each(@.attachments, (x,i) -> x.order = i+1) + + # Persist one concrete attachment. + # This function is mainly used when user clicks + # to save button for save one unique attachment. + updateAttachment: (attachment) -> + onSuccess = => + @.updateCounters() + @rootscope.$broadcast("attachment:edit") + + onError = => + @confirm.notify("error") + return @q.reject() + + return @repo.save(attachment).then(onSuccess, onError) + + # Persist all pending modifications on attachments. + # This function is used mainly for persist the order + # after sorting. + saveAttachments: -> + return @repo.saveAll(@.attachments).then null, => + for item in @.attachments + item.revert() + @.attachments = _.sorBy(@.attachments, "order") + + # Remove one concrete attachment. + removeAttachment: (attachment) -> + title = "Delete attachment" #TODO: i18in + subtitle = "the attachment '#{attachment.name}'" #TODO: i18in + + onSuccess = => + index = @.attachments.indexOf(attachment) + @.attachments.splice(index, 1) + @.updateCounters() + @rootscope.$broadcast("attachment:delete") + + onError = => + @confirm.notify("error", null, "We have not been able to delete #{subtitle}.") + return @q.reject() + + return @confirm.ask(title, subtitle).then => + return @repo.remove(attachment).then(onSuccess, onError) + + # Function used in template for filter visible attachments + filterAttachments: (item) -> + if @.showDeprecated + return true + return not item.is_deprecated + + +AttachmentsDirective = ($confirm) -> + template = _.template(""" +
+
+

+ + + attachments + +
+ +new file + +
+

+
+ + +
""") + + + link = ($scope, $el, $attrs, $ctrls) -> + $ctrl = $ctrls[0] + $model = $ctrls[1] + + bindOnce $scope, $attrs.ngModel, (value) -> + $ctrl.initialize($attrs.type, value.id) + $ctrl.loadAttachments() - ## Drag & drop tdom = $el.find("div.attachment-body.sortable") - tdom.sortable({ items: "div.single-attachment" handle: "a.settings.icon.icon-drag-v" @@ -49,101 +216,58 @@ AttachmentsDirective = ($repo, $rs, $confirm) -> tdom.on "sortstop", (event, ui) -> attachment = ui.item.scope().attach newIndex = ui.item.index() - index = $scope.attachments.indexOf(attachment) - return if index == newIndex + $ctrl.reorderAttachment(attachment, newIndex) + $ctrl.saveAttachments() - # Move attachment to newIndex and recalculate order - $scope.attachments.splice(index, 1) - $scope.attachments.splice(newIndex, 0, attachment) - _.forEach $scope.attachments, (attach, idx) -> - attach.order = idx+1 + $el.on "click", "a.add-attach", (event) -> + event.preventDefault() + $el.find("input.add-attach").trigger("click") - # Save or revert changes - $repo.saveAll($scope.attachments).then null, -> - _.forEach $scope.attachments, attach -> - attach.revert() - _.sorBy($scope.attachments, 'order') + $el.on "change", "input.add-attach", (event) -> + files = _.toArray(event.target.files) + return if files.length < 1 - ## Total attachments counter - $scope.$watch "attachmentsCount", (count) -> - $el.find("span.attachments-num").html(count) + $scope.$apply -> + $ctrl.addUploadingAttachments(files) + $ctrl.createAttachments(files) - ## Show/Hide deprecated attachments - $scope.showDeprecatedAttachments = false - - $scope.$watch "deprecatedAttachmentsCount", (deprecatedAttachmentsCount) -> - $el.find("span.more-attachments-num").html("(#{deprecatedAttachmentsCount} deprecated)") # TODO: i18n - - if deprecatedAttachmentsCount - $el.find("a.more-attachments").removeClass("hidden") - else - $el.find("a.more-attachments").addClass("hidden") - - $el.on "click", "a.more-attachments", -> + $el.on "click", ".more-attachments", (event) -> event.preventDefault() target = angular.element(event.currentTarget) - $scope.showDeprecatedAttachments = not $scope.showDeprecatedAttachments + $scope.$apply -> + $ctrl.showDeprecated = not $ctrl.showDeprecated - if $scope.showDeprecatedAttachments - target.find("span.text").html("- hide deprecated attachments") # TODO: i18n - .prop("title", "hide deprecated attachments") # TODO: i18n - $el.find("div.single-attachment.deprecated").removeClass("hidden") + target.find("span.text").addClass("hidden") + if $ctrl.showDeprecated + target.find("span[data-type=hide]").removeClass("hidden") + target.find("more-attachments-num").addClass("hidden") else - target.find("span.text").html("+ show deprecated attachments") # TODO: i18n - .prop("title", "show deprecated attachments") # TODO: i18n - $el.find("div.single-attachment.deprecated").addClass("hidden") + target.find("span[data-type=show]").removeClass("hidden") + target.find("more-attachments-num").removeClass("hidden") - $el.on "change", "input.add-attach", -> - files = _.map(event.target.files, (x) -> x) - return if files.length < 1 - - # Add files to uploadingFiles array - $scope.$apply => - if not $scope.uploadingFiles or $scope.uploadingFiles.length == 0 - $scope.uploadingFiles = files - else - $scope.uploadingFiles = scope.uploadingFiles.concat(files) - - # Upload new files - urlName = $ctrl.attachmentsUrlName - projectId = $scope.projectId - objectId = $model.$modelValue.id - - _.forEach files, (file) -> - promise = $rs.attachments.create(urlName, projectId, objectId, file) - - promise.then (data) -> - data.isCreatedRightNow = true - - index = $scope.uploadingFiles.indexOf(file) - $scope.uploadingFiles.splice(index, 1) - $ctrl.onCreateAttachment(data) - - promise.then null, (data) -> - index = $scope.uploadingFiles.indexOf(file) - $scope.uploadingFiles.splice(index, 1) - $confirm.notify("error", null, "We have not been able to upload '#{file.name}'.") #TODO: i18in - - ## On destroy $scope.$on "$destroy", -> $el.off() + templateFn = ($el, $attrs) -> + return template({type: $attrs.type}) + return { - link: link, - require: "ngModel" + require: ["tgAttachments", "ngModel"] + controller: AttachmentsController + controllerAs: "ctrl" + restrict: "AE" + scope: true + link: link + template: templateFn } -module.directive("tgAttachments", ["$tgRepo", "$tgResources", "$tgConfirm", AttachmentsDirective]) +module.directive("tgAttachments", ["$tgConfirm", AttachmentsDirective]) -############################################################################# -## Attachment Directive -############################################################################# - -AttachmentDirective = ($log, $repo, $confirm) -> - singleAttachment = _.template(""" +AttachmentDirective = -> + template = _.template(""" <% } %> - """) #TODO: i18n + """) - singleAttachmentEditable = _.template(""" + templateEdit = _.template("""
<%- name %> @@ -188,13 +312,13 @@ AttachmentDirective = ($log, $repo, $confirm) ->
- """) # TODO: i18n + """) - link = ($scope, $el, $attrs) -> - $ctrl = $el.controller() + link = ($scope, $el, $attrs, $ctrl) -> + render = (attachment, edit=false) -> + permissions = $scope.project.my_permissions + modifyPermission = permissions.indexOf("modify_#{$ctrl.type}") > -1 - render = (attachment, isEditable=false) -> - modifyPermission = $scope.project.my_permissions.indexOf("modify_#{$attrs.permissionSuffix}") > -1 ctx = { id: attachment.id name: attachment.name @@ -205,30 +329,29 @@ AttachmentDirective = ($log, $repo, $confirm) -> modifyPermission: modifyPermission } - if isEditable - html = singleAttachmentEditable(ctx) + if edit + html = templateEdit(ctx) else - html = singleAttachment(ctx) + html = template(ctx) $el.html(html) - if attachment.is_deprecated $el.addClass("deprecated") - if $scope.showDeprecatedAttachments - $el.removeClass("hidden") - else - $el.addClass("hidden") - else - $el.removeClass("deprecated") - $el.removeClass("hidden") - ## Initialize - if not $attrs.tgAttachment? - return $log.error "AttachmentDirective the directive need an attachment" + ## Actions (on edit mode) + $el.on "click", "a.editable-settings.icon-floppy", (event) -> + event.preventDefault() - attachment = $scope.$eval($attrs.tgAttachment) - render(attachment, attachment.isCreatedRightNow) - delete attachment.isCreatedRightNow + attachment.description = $el.find("input[name='description']").val() + attachment.is_deprecated = $el.find("input[name='is-deprecated']").prop("checked") + + $scope.$apply -> + $ctrl.updateAttachment(attachment).then -> + render(attachment) + + $el.on "click", "a.editable-settings.icon-delete", (event) -> + event.preventDefault() + render(attachment, false) ## Actions (on view mode) $el.on "click", "a.settings.icon-edit", (event) -> @@ -237,49 +360,20 @@ AttachmentDirective = ($log, $repo, $confirm) -> $el.on "click", "a.settings.icon-delete", (event) -> event.preventDefault() + $scope.$apply -> + $ctrl.removeAttachment(attachment) - title = "Delete attachment" #TODO: i18in - subtitle = "the attachment '#{attachment.name}'" #TODO: i18in - - onSuccess = -> - $ctrl.onDeleteAttachment(attachment) - - onError = -> - $confirm.notify("error", null, "We have not been able to delete #{subtitle}.") #TODO: i18in - - $confirm.ask(title, subtitle).then -> - $repo.remove(attachment).then(onSuccess, onError) - - ## Actions (on edit mode) - $el.on "click", "a.editable-settings.icon-floppy", (event) -> - event.preventDefault() - - newDescription = $el.find("input[name='description']").val() - newIsDeprecated = $el.find("input[name='is-deprecated']").prop("checked") - - if newDescription != attachment.description - attachment.description = newDescription - if newIsDeprecated != attachment.is_deprecated - attachment.is_deprecated = newIsDeprecated - - onSuccess = -> - $ctrl.onEditAttachment(attachment) - render(attachment) - - onError = -> - $confirm.notify("error") - - $repo.save(attachment).then(onSuccess, onError) - - $el.on "click", "a.editable-settings.icon-delete", (event) -> - event.preventDefault() - render(attachment) - - ## On destroy $scope.$on "$destroy", -> $el.off() - return {link: link} + # Bootstrap + attachment = $scope.$eval($attrs.tgAttachment) + render(attachment, attachment.isCreatedRightNow) -module.directive("tgAttachment", ["$log", "$tgRepo", "$tgConfirm", - AttachmentDirective]) + return { + link: link + require: "^tgAttachments" + restrict: "AE" + } + +module.directive("tgAttachment", AttachmentDirective) diff --git a/app/coffee/modules/controllerMixins.coffee b/app/coffee/modules/controllerMixins.coffee index 10dccc59..860e3777 100644 --- a/app/coffee/modules/controllerMixins.coffee +++ b/app/coffee/modules/controllerMixins.coffee @@ -102,44 +102,3 @@ class FiltersMixin location.search(name, value) taiga.FiltersMixin = FiltersMixin - - -############################################################################# -## Attachments Mixin -############################################################################# -# This mixin requires @rs ($tgResources), @scope and @log ($tgLog) -# The mixin required @..attachmentsUrlName (p.e. 'issues/attachments',see resources.coffee) - -class AttachmentsMixin - loadAttachments: (objectId) -> - if not @.attachmentsUrlName - return @log.error "AttachmentsMixin: @.attachmentsUrlName is required" - - @scope.attachmentsCount = 0 - @scope.deprecatedAttachmentsCount = 0 - - return @rs.attachments.list(@.attachmentsUrlName, objectId).then (attachments) => - @scope.attachments = _.sortBy(attachments, "order") - @.updateAttachmentsCounters() - return attachments - - updateAttachmentsCounters: -> - @scope.attachmentsCount = @scope.attachments.length - @scope.deprecatedAttachmentsCount = _.filter(@scope.attachments, is_deprecated: true).length - - onCreateAttachment: (attachment) -> - @scope.attachments[@scope.attachments.length] = attachment - @.updateAttachmentsCounters() - @scope.$emit("attachment:create") - - onEditAttachment: (attachment) -> - @.updateAttachmentsCounters() - @scope.$emit("attachment:edit") - - onDeleteAttachment: (attachment) -> - index = @scope.attachments.indexOf(attachment) - @scope.attachments.splice(index, 1) - @.updateAttachmentsCounters() - @scope.$emit("attachment:delete") - -taiga.AttachmentsMixin = AttachmentsMixin diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index 35a06c0e..fd1de78e 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -33,7 +33,7 @@ module = angular.module("taigaIssues") ## Issue Detail Controller ############################################################################# -class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.AttachmentsMixin) +class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", @@ -49,8 +49,6 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin, tai ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @log, @appTitle, @navUrls) -> - @.attachmentsUrlName = "issues/attachments" - @scope.issueRef = @params.issueref @scope.sectionName = "Issue Details" @@ -118,8 +116,7 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin, tai return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) - .then(=> @q.all([@.loadIssue(), - @.loadAttachments(@scope.issueId)])) + .then(=> @.loadIssue()) block: -> @rootscope.$broadcast("block", @scope.issue) diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index a886a157..f5d2e97e 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -88,10 +88,10 @@ urls = { "history/wiki": "/api/v1/history/wiki" # Attachments - "userstories/attachments": "/api/v1/userstories/attachments" - "issues/attachments": "/api/v1/issues/attachments" - "tasks/attachments": "/api/v1/tasks/attachments" - "wiki/attachments": "/api/v1/wiki/attachments" + "attachments/us": "/api/v1/userstories/attachments" + "attachments/issue": "/api/v1/issues/attachments" + "attachments/task": "/api/v1/tasks/attachments" + "attachments/wiki_page": "/api/v1/wiki/attachments" } # Initialize api urls service diff --git a/app/coffee/modules/tasks/detail.coffee b/app/coffee/modules/tasks/detail.coffee index c1f08250..8b62037f 100644 --- a/app/coffee/modules/tasks/detail.coffee +++ b/app/coffee/modules/tasks/detail.coffee @@ -30,7 +30,7 @@ module = angular.module("taigaTasks") ## Task Detail Controller ############################################################################# -class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.AttachmentsMixin) +class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", @@ -46,8 +46,6 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taig ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @log, @appTitle, @navUrls) -> - @.attachmentsUrlName = "tasks/attachments" - @scope.taskRef = @params.taskref @scope.sectionName = "Task Details" @@ -110,7 +108,6 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taig return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) .then(=> @.loadTask()) - .then(=> @.loadAttachments(@scope.taskId)) block: -> @rootscope.$broadcast("block", @scope.task) diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index f2e1b618..c821425e 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -31,7 +31,7 @@ module = angular.module("taigaUserStories") ## User story Detail Controller ############################################################################# -class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.AttachmentsMixin) +class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", @@ -47,7 +47,6 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin, ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @log, @appTitle, @navUrls) -> - @.attachmentsUrlName = "userstories/attachments" @scope.issueRef = @params.issueref @scope.sectionName = "User Story Details" @@ -114,8 +113,7 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin, return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) - .then(=> @q.all([@.loadUs(), - @.loadAttachments(@scope.usId)])) + .then(=> @.loadUs()) block: -> @rootscope.$broadcast("block", @scope.us) diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 965f491c..49d188a7 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -32,7 +32,7 @@ module = angular.module("taigaWiki") ## Wiki Detail Controller ############################################################################# -class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.AttachmentsMixin) +class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @.$inject = [ "$scope", "$rootScope", @@ -50,7 +50,6 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taig constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location, @filter, @log, @appTitle, @navUrls) -> - @.attachmentsUrlName = "wiki/attachments" @scope.projectSlug = @params.pslug @scope.wikiSlug = @params.slug @scope.sectionName = "Wiki" @@ -116,8 +115,7 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin, taig return promise.then(=> @.loadProject()) .then(=> @.loadUsersAndRoles()) .then(=> @q.all([@.loadWikiLinks(), - @.loadWiki(), - @.loadAttachments(@scope.wikiId)])) + @.loadWiki()])) edit: -> ctx = { diff --git a/app/partials/issues-detail-edit.jade b/app/partials/issues-detail-edit.jade index e1652f59..eec7223a 100644 --- a/app/partials/issues-detail-edit.jade +++ b/app/partials/issues-detail-edit.jade @@ -28,10 +28,7 @@ block content section.us-content textarea(placeholder="Write a description of your issue", ng-model="issue.description", tg-markitup) - - var attachModel = "issue" - - var permissionSuffix = "issue" - include views/modules/attachments - + tg-attachments(ng-model="issue", type="issue") tg-history(ng-model="issue", type="issue", mode="edit") sidebar.menu-secondary.sidebar diff --git a/app/partials/issues-detail.jade b/app/partials/issues-detail.jade index 41173be9..dfd6acc3 100644 --- a/app/partials/issues-detail.jade +++ b/app/partials/issues-detail.jade @@ -28,10 +28,7 @@ block content section.us-content.wysiwyg(tg-bind-html="issue.description_html") - - var attachModel = "issue" - - var permissionSuffix = "issue" - include views/modules/attachments - + tg-attachments(ng-model="issue", type="issue") tg-history(ng-model="issue", type="issue") sidebar.menu-secondary.sidebar diff --git a/app/partials/task-detail-edit.jade b/app/partials/task-detail-edit.jade index 09215380..16359f96 100644 --- a/app/partials/task-detail-edit.jade +++ b/app/partials/task-detail-edit.jade @@ -28,10 +28,7 @@ block content section.us-content textarea(placeholder="Write a description of your task", ng-model="task.description", tg-markitup) - - var attachModel = "task" - - var permissionSuffix = "task" - include views/modules/attachments - + tg-attachments(ng-model="task", type="task") tg-history(ng-model="task", type="task", mode="edit") sidebar.menu-secondary.sidebar diff --git a/app/partials/task-detail.jade b/app/partials/task-detail.jade index c4100cfb..e362e84f 100644 --- a/app/partials/task-detail.jade +++ b/app/partials/task-detail.jade @@ -28,10 +28,7 @@ block content section.us-content.wysiwyg(tg-bind-html="task.description_html") - - var attachModel = "task" - - var permissionSuffix = "task" - include views/modules/attachments - + tg-attachments(ng-model="task", type="task") tg-history(ng-model="task", type="task") sidebar.menu-secondary.sidebar diff --git a/app/partials/us-detail-edit.jade b/app/partials/us-detail-edit.jade index c1c5b832..21b5b489 100644 --- a/app/partials/us-detail-edit.jade +++ b/app/partials/us-detail-edit.jade @@ -28,10 +28,7 @@ block content section.us-content textarea(placeholder="Write a description of your user story", ng-model="us.description", tg-markitup) - - var attachModel = "us" - - var permissionSuffix = "us" - include views/modules/attachments - + tg-attachments(ng-model="us", type="us") tg-history(ng-model="us", type="us", mode="edit") sidebar.menu-secondary.sidebar diff --git a/app/partials/us-detail.jade b/app/partials/us-detail.jade index 628fc529..6985bccb 100644 --- a/app/partials/us-detail.jade +++ b/app/partials/us-detail.jade @@ -32,10 +32,7 @@ block content include views/modules/related-tasks - - var attachModel = "us" - - var permissionSuffix = "us" - include views/modules/attachments - + tg-attachments(ng-model="us", type="us") tg-history(ng-model="us", type="us") sidebar.menu-secondary.sidebar diff --git a/app/partials/views/modules/attachments.jade b/app/partials/views/modules/attachments.jade deleted file mode 100644 index 146dbad1..00000000 --- a/app/partials/views/modules/attachments.jade +++ /dev/null @@ -1,31 +0,0 @@ -//- NOTE: You must to define 'var attachModel' 'var permissionSuffix' with the object model -//- that have attachments - -section.attachments(tg-attachments, ng-model=attachModel, ng-if="#{attachModel}.id") - div.attachments-header - h3.attachments-title - span.icon.icon-attachments - span.attachments-num 0 - span.attachments-text attachments - div.button.button-gray.add-attach(tg-check-permission="modify_"+permissionSuffix, title="Add new attachment") - span +new file - input.add-attach(type="file", multiple="multiple") - - div.attachment-body.sortable - div.hidden.single-attachment(ng-repeat="attach in attachments", - tg-attachment="attach", permission-suffix=permissionSuffix) - - //- See modules/common/attachments.coffee - AttachmentDirective - - div.single-attachment(ng-repeat="file in uploadingFiles") - div.attachment-name - a(href="", tg-bo-title="file.name", tg-bo-bind="file.name") - div.attachment-size - span.attachment-size(tg-bo-bind="file.size") - div.attachment-comments - span(ng-bind="file.progressMessage") - div.percentage(ng-style="{'width': file.progressPercent}") - - a.hidden.more-attachments(href="", title="show deprecated atachments") - span.text + show deprecated atachments - span.more-attachments-num (0 deprecated) diff --git a/app/partials/wiki-edit.jade b/app/partials/wiki-edit.jade index e9517ce9..d714784f 100644 --- a/app/partials/wiki-edit.jade +++ b/app/partials/wiki-edit.jade @@ -21,6 +21,4 @@ block content section.wysiwyg textarea(placeholder="Write a your wiki page", ng-model="wiki.content", tg-markitup) - - var attachModel = "wiki" - - var permissionSuffix = "wiki_page" - include views/modules/attachments + tg-attachments(ng-model="wiki", type="wiki_page") diff --git a/app/partials/wiki.jade b/app/partials/wiki.jade index 7e42a6e7..27d95235 100644 --- a/app/partials/wiki.jade +++ b/app/partials/wiki.jade @@ -25,6 +25,4 @@ block content section.wiki-content.wysiwyg(tg-bind-html="wiki.html") - - var attachModel = "wiki" - - var permissionSuffix = "wiki_page" - include views/modules/attachments + tg-attachments(ng-model="wiki", type="wiki_page") diff --git a/app/styles/modules/common/attachments.scss b/app/styles/modules/common/attachments.scss index 0d392fb9..9ffab8d5 100644 --- a/app/styles/modules/common/attachments.scss +++ b/app/styles/modules/common/attachments.scss @@ -159,16 +159,19 @@ } .add-attach { + overflow: hidden; position: relative; + cursor: pointer; + input { cursor: pointer; - height: 100%; + font-size: 99px; + height: 120%; left: 0; opacity: 0; position: absolute; - top: 0; + top: -5px; width: 100%; z-index: 9999; } } -