From d9da36283ad6db1413a2eda7c7f7a8fc52fab337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 31 Jul 2014 19:23:55 +0200 Subject: [PATCH] finish with attachment module --- app/coffee/modules/common/attachments.coffee | 81 +++++++++++++++---- app/coffee/modules/controllerMixins.coffee | 1 - .../modules/resources/attachments.coffee | 52 +++++++++++- app/partials/views/modules/attachments.jade | 15 +++- 4 files changed, 129 insertions(+), 20 deletions(-) diff --git a/app/coffee/modules/common/attachments.coffee b/app/coffee/modules/common/attachments.coffee index 72740768..b39daa88 100644 --- a/app/coffee/modules/common/attachments.coffee +++ b/app/coffee/modules/common/attachments.coffee @@ -29,9 +29,14 @@ module = angular.module("taigaCommon") ## Attachments Directive ############################################################################# -AttachmentsDirective = ($repo) -> +AttachmentsDirective = ($repo, $rs) -> link = ($scope, $el, $attrs, $model) -> + $ctrl = $el.controller() + $scope.uploadingFiles = [] + + ########### ## Drag & drop + ########### tdom = $el.find("div.attachment-body.sortable") tdom.sortable({ @@ -47,24 +52,29 @@ AttachmentsDirective = ($repo) -> newIndex = ui.item.index() index = $scope.attachments.indexOf(attachment) - if index != newIndex - # 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 + return if index == newIndex - # Save or revert changes - $repo.saveAll($scope.attachments).then null, -> - _.forEach $scope.attachments, attach -> - attach.revert() - _.sorBy($scope.attachments, 'order') + # 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 + # Save or revert changes + $repo.saveAll($scope.attachments).then null, -> + _.forEach $scope.attachments, attach -> + attach.revert() + _.sorBy($scope.attachments, 'order') + + ########### ## Total attachments counter + ########### $scope.$watch "attachmentsCount", (count) -> $el.find("span.attachments-num").html(count) + ########### ## Show/Hide deprecated attachments + ########### $scope.showDeprecatedAttachments = false $scope.$watch "deprecatedAttachmentsCount", (deprecatedAttachmentsCount) -> @@ -90,7 +100,42 @@ AttachmentsDirective = ($repo) -> .prop("title", "show deprecated attachments") # TODO: i18n $el.find("div.single-attachment.deprecated").addClass("hidden") + ########### + ## Add Attachments + ########### + $el.on "click", "a.add-attach", -> + angular.element("input.add-attach").trigger("click") + + $el.on "change", "input.add-attach", -> + files = _.map(event.target.files, (x) -> x) + return if files.length < 1 + + $scope.$apply => + if not $scope.uploadingFiles or $scope.uploadingFiles.length == 0 + $scope.uploadingFiles = files + else + $scope.uploadingFiles = scope.uploadingFiles.concat(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) -> + $scope.uploadingFiles = _.without($scope.uploadingFiles, file) + data.isCreatedRightNow = true + $scope.attachments[$scope.attachments.length] = data + $scope.attachmentsCount = $scope.attachments.length + + promise.then null, (data) -> + $scope.uploadingFiles = _.without($scope.uploadingFiles, file) + $confirm.notify("error", null, "We have not been able to upload '#{file.name}'.") #TODO: i18in + + ########### ## On destroy + ########### $scope.$on "$destroy", -> $el.off() @@ -99,7 +144,7 @@ AttachmentsDirective = ($repo) -> require: "ngModel" } -module.directive("tgAttachments", ["$tgRepo", AttachmentsDirective]) +module.directive("tgAttachments", ["$tgRepo", "$tgResources", AttachmentsDirective]) ############################################################################# @@ -169,14 +214,18 @@ AttachmentDirective = ($log, $repo, $confirm) -> $el.removeClass("deprecated") $el.removeClass("hidden") + ########### ## Initialize + ########### if not $attrs.tgAttachment? return $log.error "AttachmentDirective the directive need an attachment" attachment = $scope.$eval($attrs.tgAttachment) - render(attachment) + render(attachment, attachment.isCreatedRightNow) + ########### ## Actions (on view mode) + ########### $el.on "click", "a.settings.icon-edit", (event) -> event.preventDefault() render(attachment, true) @@ -197,7 +246,9 @@ AttachmentDirective = ($log, $repo, $confirm) -> $confirm.ask(title, subtitle).then -> $repo.remove(attachment).then(onSuccess, onError) + ########### ## Actions (on edit mode) + ########### $el.on "click", "a.editable.icon-delete", (event) -> event.preventDefault() render(attachment) @@ -220,7 +271,9 @@ AttachmentDirective = ($log, $repo, $confirm) -> $repo.save(attachment).then(onSuccess, onError) + ########### ## On destroy + ########### $scope.$on "$destroy", -> $el.off() diff --git a/app/coffee/modules/controllerMixins.coffee b/app/coffee/modules/controllerMixins.coffee index ef57d950..3b95cdbc 100644 --- a/app/coffee/modules/controllerMixins.coffee +++ b/app/coffee/modules/controllerMixins.coffee @@ -112,7 +112,6 @@ class AttachmentsMixin return @log.error "AttachmentsMixin: @.attachmentsUrlName is required" @scope.attachmentsCount = 0 - @scope.activeAttachmentsCount = 0 @scope.deprecatedAttachmentsCount = 0 return @rs.attachments.list(@.attachmentsUrlName, objectId).then (attachments) => diff --git a/app/coffee/modules/resources/attachments.coffee b/app/coffee/modules/resources/attachments.coffee index c99c3802..764c4868 100644 --- a/app/coffee/modules/resources/attachments.coffee +++ b/app/coffee/modules/resources/attachments.coffee @@ -21,17 +21,65 @@ taiga = @.taiga +sizeFormat = @.taiga.sizeFormat -resourceProvider = ($repo) -> + +resourceProvider = ($rootScope, $urls, $repo, $auth, $q) -> service = {} service.list = (urlName, objectId) -> params = {object_id: objectId} return $repo.queryMany(urlName, params) + service.create = (urlName, projectId, objectId, file) -> + defered = $q.defer() + + if file is undefined + defered.reject(null) + return defered.promise + + uploadProgress = (evt) => + $rootScope.$apply => + file.status = "in-progress" + file.size = sizeFormat(evt.total) + file.progressMessage = "upload #{sizeFormat(evt.loaded)} of #{sizeFormat(evt.total)}" + file.progressPercent = Math.round((evt.loaded / evt.total) * 100) + + uploadComplete = (evt) => + $rootScope.$apply -> + file.status = "done" + try + data = JSON.parse(evt.target.responseText) + catch + data = {} + defered.resolve(data) + + uploadFailed = (evt) => + $rootScope.$apply -> + file.status = "error" + defered.reject("fail") + + data = new FormData() + data.append("project", projectId) + data.append("object_id", objectId) + data.append("attached_file", file) + + xhr = new XMLHttpRequest() + xhr.upload.addEventListener("progress", uploadProgress, false) + xhr.addEventListener("load", uploadComplete, false) + xhr.addEventListener("error", uploadFailed, false) + + xhr.open("POST", $urls.resolve(urlName)) + xhr.setRequestHeader("Authorization", "Bearer #{$auth.getToken()}") + xhr.setRequestHeader('Accept', 'application/json') + xhr.send(data) + + return defered.promise + return (instance) -> instance.attachments = service module = angular.module("taigaResources") -module.factory("$tgAttachmentsResourcesProvider", ["$tgRepo", resourceProvider]) +module.factory("$tgAttachmentsResourcesProvider", ["$rootScope", "$tgUrls", "$tgRepo", "$tgAuth", "$q", + resourceProvider]) diff --git a/app/partials/views/modules/attachments.jade b/app/partials/views/modules/attachments.jade index cef988a0..a6935313 100644 --- a/app/partials/views/modules/attachments.jade +++ b/app/partials/views/modules/attachments.jade @@ -7,8 +7,9 @@ section.attachments(tg-attachments, ng-model=attachModel) span.icon.icon-attachment span.attachments-num 0 span.attachments-text attachments - a.button.button-gray(href="", title="Add new attachment") + a.button.button-gray.add-attach(href="", title="Add new attachment") span +new file + input.hidden.add-attach(type="file", multiple="multiple") div.attachment-body.sortable div.hidden.single-attachment(ng-repeat="attach in attachments", @@ -19,7 +20,6 @@ section.attachments(tg-attachments, ng-model=attachModel) //- An attachment ('deprecated' class for deprecxated attachments) //-div.single-attachment //- div.attachment-name - //- span.icon.icon-document //- a(href="", title="Attachment pefildeusuario.png") pefildeusuariopefuario.png //- div.attachment-comment //- span.attachment-size (42 B) @@ -31,7 +31,6 @@ section.attachments(tg-attachments, ng-model=attachModel) //- An edittable attachment ('deprecated' class for deprecxated attachments) //-div.single-attachment //- div.attachment-name - //- span.icon.icon-document //- a(href="", title="Attachment pefildeusuario.png") pefildeusuariopefuario.png //- div.editable.editable-attachment-comment //- span.attachment-size (42 B) @@ -42,6 +41,16 @@ section.attachments(tg-attachments, ng-model=attachModel) //- a.editable.icon.icon-floppy(href="#", "Save") //- a.editable.icon.icon-delete(href="#", "Cancel") + //-TODO: XAVI, FIX ME :-) + div.single-attachment(ng-repeat="file in uploadingFiles") + div.attachment-name + span + a(href="", title="{{ file.name }}") file.name + div.attachment-comment + span.attachment-size ({{ file.size }}) + span(ng-if="file.progressMessage", style="color:#72a114; font-weight: bold;") {{ file.progressMessage }} | {{ file.progressPercent }}% + //-END_TODO + a.hidden.more-attachments(href="", title="show deprecated atachments") span.text + show deprecated atachments span.more-attachments-num (0 deprecated)