From c6d24ba4ffee489fb08e466d76e74ce49fdea1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 28 Apr 2015 20:59:46 +0200 Subject: [PATCH] [i18n] Fix activity tab and add pluralization ability to $translate service --- app/coffee/app.coffee | 1 + app/coffee/modules/common/history.coffee | 88 ++++++++++++------- app/locales/locale-en.json | 42 ++++++++- app/locales/locale-es.json | 46 +++++++++- app/locales/locale-fr.json | 48 ++++++++-- .../common/history/history-activity.jade | 3 +- .../history/history-change-attachment.jade | 6 +- .../history/history-deleted-comment.jade | 9 +- gulpfile.js | 5 +- 9 files changed, 197 insertions(+), 51 deletions(-) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index f10b1de6..008382a4 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -236,6 +236,7 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven prefix: "/locales/locale-", suffix: ".json" }) + .addInterpolation('$translateMessageFormatInterpolation') .preferredLanguage(window.taigaConfig.defaultLanguage || "en") if not window.taigaConfig.debugInfo diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index 2d7ddced..ef2dd1a7 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -96,25 +96,40 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c # Helpers getHumanizedFieldName = (field) -> - humanizedFieldNames = {} - - # US - humanizedFieldNames.assigned_to = $translate.instant("COMMON.FIELDS.ASSIGNED_TO").toLowerCase() - humanizedFieldNames.is_closed = $translate.instant("IS_CLOSED").toLowerCase() - humanizedFieldNames.finish_date = $translate.instant("US.FIELDS.FINISH_DATE").toLowerCase() - humanizedFieldNames.client_repquirement = $translate.instant("US.FIELDS.CLIENT_REQUIREMENT").toLowerCase() - humanizedFieldNames.team_requirement = $translate.instant("US.FIELDS.TEAM_REQUIREMENT").toLowerCase() - - # Task - humanizedFieldNames.milestone = $translate.instant("TASK.FIELDS.MILESTONE").toLowerCase() - humanizedFieldNames.user_story = $translate.instant("TASK.FIELDS.USER_STORY").toLowerCase() - humanizedFieldNames.is_iocaine = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase() - - # Attachment - humanizedFieldNames.is_deprecated = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase() - - humanizedFieldNames.blocked_note = $translate.instant("TASK.FIELDS.IS_IOCAINE").toLowerCase() - humanizedFieldNames.is_blocked = $translate.instant("TASK.FIELDS.IS_BLOCKED").toLowerCase() + humanizedFieldNames = { + subject : $translate.instant("ACTIVITY.FIELDS.SUBJECT") + name: $translate.instant("ACTIVITY.FIELDS.NAME") + description : $translate.instant("ACTIVITY.FIELDS.DESCRIPTION") + content: $translate.instant("ACTIVITY.FIELDS.CONTENT") + status: $translate.instant("ACTIVITY.FIELDS.STATUS") + is_closed : $translate.instant("ACTIVITY.FIELDS.IS_CLOSED") + finish_date : $translate.instant("ACTIVITY.FIELDS.FINISH_DATE") + type: $translate.instant("ACTIVITY.FIELDS.TYPE") + priority: $translate.instant("ACTIVITY.FIELDS.PRIORITY") + severity: $translate.instant("ACTIVITY.FIELDS.SEVERITY") + assigned_to : $translate.instant("ACTIVITY.FIELDS.ASSIGNED_TO") + watchers : $translate.instant("ACTIVITY.FIELDS.WATCHERS") + milestone : $translate.instant("ACTIVITY.FIELDS.MILESTONE") + user_story: $translate.instant("ACTIVITY.FIELDS.USER_STORY") + project: $translate.instant("ACTIVITY.FIELDS.PROJECT") + is_blocked: $translate.instant("ACTIVITY.FIELDS.IS_BLOCKED") + blocked_note: $translate.instant("ACTIVITY.FIELDS.BLOCKED_NOTE") + points: $translate.instant("ACTIVITY.FIELDS.POINTS") + client_requirement : $translate.instant("ACTIVITY.FIELDS.CLIENT_REQUIREMENT") + team_requirement : $translate.instant("ACTIVITY.FIELDS.TEAM_REQUIREMENT") + is_iocaine: $translate.instant("ACTIVITY.FIELDS.IS_IOCAINE") + tags: $translate.instant("ACTIVITY.FIELDS.TAGS") + attachments : $translate.instant("ACTIVITY.FIELDS.ATTACHMENTS") + is_deprecated: $translate.instant("ACTIVITY.FIELDS.IS_DEPRECATED") + blocked_note: $translate.instant("ACTIVITY.FIELDS.BLOCKED_NOTE") + is_blocked: $translate.instant("ACTIVITY.FIELDS.IS_BLOCKED") + order: $translate.instant("ACTIVITY.FIELDS.ORDER") + backlog_order: $translate.instant("ACTIVITY.FIELDS.BACKLOG_ORDER") + sprint_order: $translate.instant("ACTIVITY.FIELDS.SPRINT_ORDER") + kanban_order: $translate.instant("ACTIVITY.FIELDS.KANBAN_ORDER") + taskboard_order: $translate.instant("ACTIVITY.FIELDS.TASKBOARD_ORDER") + us_order: $translate.instant("ACTIVITY.FIELDS.US_ORDER") + } return humanizedFieldNames[field] or field @@ -133,17 +148,17 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c formatChange = (change) -> if _.isArray(change) if change.length == 0 - return "empty" + return $translate.instant("ACTIVITY.VALUES.EMPTY") return change.join(", ") if change == "" - return "empty" + return $translate.instant("ACTIVITY.VALUES.EMPTY") if not change? or change == false - return "no" + return $translate.instant("ACTIVITY.VALUES.NO") if change == true - return "yes" + return $translate.instant("ACTIVITY.VALUES.YES") return change @@ -153,20 +168,26 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c attachments = _.map value, (changes, type) -> if type == "new" return _.map changes, (change) -> - return templateChangeDiff({name: $translate.instant("ACTIVITY.NEW_ATTACHMENT"), diff: change.filename}) + return templateChangeDiff({ + name: $translate.instant("ACTIVITY.NEW_ATTACHMENT"), + diff: change.filename + }) else if type == "deleted" return _.map changes, (change) -> - return templateChangeDiff({name: $translate.instant("ACTIVITY.DELETED_ATTACHMENT"), diff: change.filename}) + return templateChangeDiff({ + name: $translate.instant("ACTIVITY.DELETED_ATTACHMENT"), + diff: change.filename + }) else return _.map changes, (change) -> - name = $tranlsate.instant("ACTIVITY.UPDATED_ATTACHMENT", {filename: change.filename}) + name = $translate.instant("ACTIVITY.UPDATED_ATTACHMENT", {filename: change.filename}) diff = _.map change.changes, (values, name) -> return { name: getHumanizedFieldName(name) from: formatChange(values[0]) to: formatChange(values[1]) - } + } return templateChangeAttachment({name: name, diff: diff}) @@ -229,8 +250,8 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c return html[0].outerHTML else if field == "assigned_to" name = getHumanizedFieldName(field) - from = formatChange(value[0] or "Unassigned") - to = formatChange(value[1] or "Unassigned") + from = formatChange(value[0] or $translate.instant("ACTIVITY.VALUES.UNASSIGNED")) + to = formatChange(value[1] or $translate.instant("ACTIVITY.VALUES.UNASSIGNED")) return templateChangeGeneric({name:name, from:from, to: to}) else name = getHumanizedFieldName(field) @@ -243,8 +264,7 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c renderChangesHelperText = (change) -> size = countChanges(change) - - return $translate.instant("ACTIVITY.SIZE_CHANGE", {size: size}) + return $translate.instant("ACTIVITY.SIZE_CHANGE", {size: size}, 'messageformat') renderComment = (comment) -> if (comment.delete_comment_date or comment.delete_comment_user?.name) @@ -253,7 +273,8 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c deleteCommentUser: comment.delete_comment_user.name deleteComment: comment.comment_html activityId: comment.id - canRestoreComment: comment.delete_comment_user.pk == $scope.user.id or $scope.project.my_permissions.indexOf("modify_project") > -1 + canRestoreComment: (comment.delete_comment_user.pk == $scope.user.id or + $scope.project.my_permissions.indexOf("modify_project") > -1) }) html = $compile(html)($scope) @@ -428,4 +449,5 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c } -module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", "$translate", "$compile", HistoryDirective]) +module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", "$translate", + "$compile", HistoryDirective]) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index 65d3ed64..9bd06b4d 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -565,7 +565,7 @@ } }, "COMMENTS": { - "DELETED_INFO": "Comment deleted by {{deleteCommentUser}} on {{deleteCommentDate}}", + "DELETED_INFO": "Comment deleted by {{user}} on {{date}}", "TITLE": "Comments", "COMMENT": "Comment", "TYPE_NEW_COMMENT": "Type a new comment here", @@ -584,7 +584,45 @@ "DELETED_ATTACHMENT": "deleted attachment", "UPDATED_ATTACHMENT": "updated attachment {{filename}}", "DELETED_CUSTOM_ATTRIBUTE": "deleted custom attribute", - "SIZE_CHANGE": "Made {{size}} {size, plural, one{change} other{changes}}" + "SIZE_CHANGE": "Made {size, plural, one{one change} other{# changes}}", + "VALUES": { + "YES": "yes", + "NO": "no", + "EMPTY": "empty", + "UNASSIGNED": "unassigned" + }, + "FIELDS": { + "SUBJECT" : "subject", + "NAME": "name", + "DESCRIPTION" : "description", + "CONTENT": "content", + "STATUS": "status", + "IS_CLOSED" : "is closed", + "FINISH_DATE" : "finish date", + "TYPE": "type", + "PRIORITY": "priority", + "SEVERITY": "severity", + "ASSIGNED_TO" : "assigned to", + "WATCHERS" : "watchers", + "MILESTONE" : "sprint", + "USER_STORY": "user story", + "PROJECT": "project", + "IS_BLOCKED": "is blocked", + "BLOCKED_NOTE": "blocked note", + "POINTS": "points", + "CLIENT_REQUIREMENT" : "client requirement", + "TEAM_REQUIREMENT" : "team requirement", + "IS_IOCAINE": "is iocaine", + "TAGS": "tags", + "ATTACHMENTS" : "attachments", + "IS_DEPRECATED": "is deprecated", + "ORDER" : "order", + "BACKLOG_ORDER" : "backlog order", + "SPRINT_ORDER" : "sprint order", + "KANBAN_ORDER" : "kanban order", + "TASKBOARD_ORDER" : "taskboard order", + "US_ORDER" : "us order" + } }, "BACKLOG": { "SECTION_NAME": "Backlog", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 571f804b..9088e521 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -563,7 +563,7 @@ } }, "COMMENTS": { - "DELETED_INFO": "Comentario borrado por {{deleteCommentUser}} el {{deleteCommentDate}}", + "DELETED_INFO": "Comentario borrado por {{user}} el {{date}}", "TITLE": "Comentarios", "COMMENT": "Comentar", "TYPE_NEW_COMMENT": "Escribe un nuevo comentario aquí", @@ -576,13 +576,51 @@ "SHOW_MORE": "+ Ver entradas anteriores ({{showMore}} más)", "TITLE": "Actividad", "REMOVED": "borrado", - "ADDED": "Agregado", + "ADDED": "agregado", "US_POINTS": "Puntos de historia ({{name}})", "NEW_ATTACHMENT": "nuevo adjunto", "DELETED_ATTACHMENT": "adjunto eliminado", "UPDATED_ATTACHMENT": "Adjunto {{filename}} actualizado", "DELETED_CUSTOM_ATTRIBUTE": "eliminar atributos personalizados", - "SIZE_CHANGE": "Hechos {{size}} {size, plural, one{cambio} other{cambios}}\n" + "SIZE_CHANGE": "{size, plural, one{Un cambio} other{# cambios}} realizados\n", + "VALUES": { + "YES": "sí", + "NO": "no", + "EMPTY": "vacío", + "UNASSIGNED": "sin asignar" + }, + "FIELDS": { + "SUBJECT": "asunto", + "NAME": "nombre", + "DESCRIPTION": "descripción", + "CONTENT": "contenido", + "STATUS": "estado", + "IS_CLOSED": "está cerrada", + "FINISH_DATE": "fecha de finalización", + "TYPE": "tipo", + "PRIORITY": "prioridad", + "SEVERITY": "gravedad", + "ASSIGNED_TO": "asignado a", + "WATCHERS": "observadores", + "MILESTONE": "sprint", + "USER_STORY": "historia de usuario", + "PROJECT": "proyecto", + "IS_BLOCKED": "está bloqueada", + "BLOCKED_NOTE": "motivo del bloqueo", + "POINTS": "puntos", + "CLIENT_REQUIREMENT": "requerido por el cliente", + "TEAM_REQUIREMENT": "requerido por el equipo", + "IS_IOCAINE": "tiene iocaína", + "TAGS": "etiquetas", + "ATTACHMENTS": "adjuntos", + "IS_DEPRECATED": "está desactualizado", + "ORDER": "orden", + "BACKLOG_ORDER": "orden en backlog", + "SPRINT_ORDER": "orden en sprint", + "KANBAN_ORDER": "orden en kanban", + "TASKBOARD_ORDER": "orden en panel de tareras", + "US_ORDER": "orden en historia" + } }, "BACKLOG": { "SECTION_NAME": "Backlog", @@ -662,7 +700,7 @@ "TASKBOARD": { "SECTION_NAME": "Panel de Tareas", "TITLE_ACTION_ADD": "Añade una nueva tarea", - "TITLE_ACTION_ADD_BULK": "Añadir nuevas Tareas en bloque", + "TITLE_ACTION_ADD_BULK": "Añadir nuevas tareas en bloque", "TITLE_ACTION_ASSIGN": "Asignar tarea", "TITLE_ACTION_EDIT": "Editar tarea", "TABLE": { diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 1c761f7c..015e3ad3 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -129,21 +129,21 @@ "DELETE_SPRINTS": "Delete sprints" }, "USER_STORIES": { - "NAME": "User Stories", + "NAME": "Histoires Utilisateur", "VIEW_USER_STORIES": "View user stories", "ADD_USER_STORIES": "Add user stories", "MODIFY_USER_STORIES": "Modify user stories", "DELETE_USER_STORIES": "Delete user stories" }, "TASKS": { - "NAME": "Tasks", + "NAME": "Tâches", "VIEW_TASKS": "View tasks", "ADD_TASKS": "Add tasks", "MODIFY_TASKS": "Modify tasks", "DELETE_TASKS": "Delete tasks" }, "ISSUES": { - "NAME": "Issues", + "NAME": "Problèmes", "VIEW_ISSUES": "View issues", "ADD_ISSUES": "Add issues", "MODIFY_ISSUES": "Modify issues", @@ -563,7 +563,7 @@ } }, "COMMENTS": { - "DELETED_INFO": "Commentaire supprimé par {{deleteCommentUser}} on {{deleteCommentDate}}", + "DELETED_INFO": "Commentaire supprimé par {{user}} on {{date}}\n", "TITLE": "Commentaires", "COMMENT": "Commentaire", "TYPE_NEW_COMMENT": "Entrez un nouveau commentaire ici", @@ -582,7 +582,45 @@ "DELETED_ATTACHMENT": "Pièce-jointe supprimée", "UPDATED_ATTACHMENT": "Pièce jointe {{filename}} modifiée", "DELETED_CUSTOM_ATTRIBUTE": "Attribut personnalisé supprimé", - "SIZE_CHANGE": "Made {{size}} {size, plural, one{change} other{changes}}" + "SIZE_CHANGE": "Made {size, plural, one{one change} other{# changes}}", + "VALUES": { + "YES": "oui", + "NO": "no", + "EMPTY": "empty", + "UNASSIGNED": "non affecté" + }, + "FIELDS": { + "SUBJECT": "sujet", + "NAME": "nom", + "DESCRIPTION": "description", + "CONTENT": "content", + "STATUS": "état", + "IS_CLOSED": "is closed", + "FINISH_DATE": "date de fin", + "TYPE": "type", + "PRIORITY": "priorité", + "SEVERITY": "sévérité", + "ASSIGNED_TO": "affecté à", + "WATCHERS": "observateurs", + "MILESTONE": "sprint", + "USER_STORY": "histoire utilisateur", + "PROJECT": "projet", + "IS_BLOCKED": "est bloqué", + "BLOCKED_NOTE": "note bloquée", + "POINTS": "points", + "CLIENT_REQUIREMENT": "exigence du client", + "TEAM_REQUIREMENT": "exigence de l'équipe", + "IS_IOCAINE": "est sous iocaine", + "TAGS": "étiquettes", + "ATTACHMENTS": "pièces jointes", + "IS_DEPRECATED": "est obsolète", + "ORDER": "order", + "BACKLOG_ORDER": "backlog order", + "SPRINT_ORDER": "sprint order", + "KANBAN_ORDER": "kanban order", + "TASKBOARD_ORDER": "taskboard order", + "US_ORDER": "us order" + } }, "BACKLOG": { "SECTION_NAME": "Backlog", diff --git a/app/partials/common/history/history-activity.jade b/app/partials/common/history/history-activity.jade index cf39359d..22b46912 100644 --- a/app/partials/common/history/history-activity.jade +++ b/app/partials/common/history/history-activity.jade @@ -12,7 +12,8 @@ div(class!="activity-single <%- mode %>") <% if (comment.length > 0) { %> <% if ((deleteCommentDate || deleteCommentUser)) { %> .deleted-comment - span(translate="COMMENTS.DELETED_INFO", translate-values!="{ deleteCommentUser: '<%- deleteCommentUser %>', deleteCommentDate: '<% deleteCommentDate %>'}") + span(translate="COMMENTS.DELETED_INFO", + translate-values!="{ user: '<%- deleteCommentUser %>', date: '<% deleteCommentDate %>'}") <% } %> .comment.wysiwyg | <%= comment %> diff --git a/app/partials/common/history/history-change-attachment.jade b/app/partials/common/history/history-change-attachment.jade index 8b4ac0f1..6b12816f 100644 --- a/app/partials/common/history/history-change-attachment.jade +++ b/app/partials/common/history/history-change-attachment.jade @@ -4,11 +4,13 @@ .activity-fromto <% _.each(diff, function(change) { %> p - strong <%- change.name %> from + strong <%- change.name %>  + strong(translate="COMMON.FROM") br span <%- change.from %> p - strong <%- change.name %> to + strong <%- change.name %>  + strong(translate="COMMON.TO") br span <%- change.to %> <% }) %> diff --git a/app/partials/common/history/history-deleted-comment.jade b/app/partials/common/history/history-deleted-comment.jade index f4bc6c9d..2e8cfe44 100644 --- a/app/partials/common/history/history-deleted-comment.jade +++ b/app/partials/common/history/history-deleted-comment.jade @@ -1,8 +1,11 @@ .activity-single.comment.deleted-comment div - span(translate="COMMENTS.DELETED_INFO", translate-values!="{deleteCommentUser: '<%- deleteCommentUser %>', deleteCommentDate: '<%- deleteCommentDate %>'}") - a(href="", title="{{'COMMENTS.SHOW_DELETED' | translate}}", class="show-deleted-comment", translate="COMMENTS.SHOW_DELETED") - a(href="", title="{{'COMMENTS.HIDE_DELETED' | translate}}", class="hide-deleted-comment hidden", translate="COMMENTS.HIDE_DELETED") + span(translate="COMMENTS.DELETED_INFO", + translate-values!="{user: '<%- deleteCommentUser %>', date: '<%- deleteCommentDate %>'}") + a(href="", title="{{'COMMENTS.SHOW_DELETED' | translate}}", + class="show-deleted-comment", translate="COMMENTS.SHOW_DELETED") + a(href="", title="{{'COMMENTS.HIDE_DELETED' | translate}}", + class="hide-deleted-comment hidden", translate="COMMENTS.HIDE_DELETED") .comment-body.wysiwyg <%= deleteComment %> <% if (canRestoreComment) { %> a(href="", class="comment-restore", data-activity-id!="<%- activityId %>") diff --git a/gulpfile.js b/gulpfile.js index f601bbfb..b630327c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -113,15 +113,17 @@ paths.coffee_order = [ paths.libs = [ paths.vendor + "jquery/dist/jquery.js", - paths.vendor + "/lodash/dist/lodash.js", + paths.vendor + "lodash/dist/lodash.js", paths.vendor + "emoticons/lib/emoticons.js", paths.vendor + "underscore.string/lib/underscore.string.js", + paths.vendor + "messageformat/messageformat.js", paths.vendor + "angular/angular.js", paths.vendor + "angular-route/angular-route.js", paths.vendor + "angular-sanitize/angular-sanitize.js", paths.vendor + "angular-animate/angular-animate.js", paths.vendor + "angular-translate/angular-translate.js", paths.vendor + "angular-translate-loader-static-files/angular-translate-loader-static-files.js", + paths.vendor + "angular-translate-interpolation-messageformat/angular-translate-interpolation-messageformat.js", paths.vendor + "i18next/i18next.js", paths.vendor + "moment/min/moment-with-langs.js", paths.vendor + "checksley/checksley.js", @@ -136,6 +138,7 @@ paths.libs = [ paths.vendor + "malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js", paths.vendor + "raven-js/dist/raven.js", paths.vendor + "l.js/l.js", + paths.vendor + "messageformat/locale/*.js", paths.app + "js/jquery.ui.git-custom.js", paths.app + "js/jquery-ui.drag-multiple-custom.js", paths.app + "js/jquery.ui.touch-punch.min.js",