From 5a92810008873bc113dc63094794ba8ffa78e884 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 17 Jun 2015 21:16:50 +0100 Subject: [PATCH 001/403] Initial commit of multi-line text fields --- .../modules/common/custom-field-values.coffee | 14 +++++++------- .../custom-attribute-value-edit.jade | 8 ++++++++ .../modules/admin/admin-custom-attributes.jade | 11 ++++++++++- .../modules/admin/admin-custom-attributes.scss | 4 ++++ app/styles/modules/common/custom-fields.scss | 6 ++++++ 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/app/coffee/modules/common/custom-field-values.coffee b/app/coffee/modules/common/custom-field-values.coffee index 8203d59f..7e031615 100644 --- a/app/coffee/modules/common/custom-field-values.coffee +++ b/app/coffee/modules/common/custom-field-values.coffee @@ -128,6 +128,7 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> link = ($scope, $el, $attrs, $ctrl) -> render = (attributeValue, edit=false) -> value = attributeValue.value + innerText = attributeValue.value editable = isEditable() ctx = { id: attributeValue.id @@ -135,6 +136,7 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> description: attributeValue.description value: value isEditable: editable + field_type: attributeValue.field_type } if editable and (edit or not value) @@ -152,14 +154,14 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> return permissions.indexOf(requiredEditionPerm) > -1 saveAttributeValue = -> - attributeValue.value = $el.find("input").val() + attributeValue.value = $el.find("input, textarea").val() $scope.$apply -> $ctrl.updateAttributeValue(attributeValue).then -> render(attributeValue, false) - $el.on "keyup", "input[name=description]", (event) -> - if event.keyCode == 13 + $el.on "keyup", "input[name=description], textarea[name='description']", (event) -> + if event.keyCode == 13 and event.currentTarget.type != "textarea" submit(event) else if event.keyCode == 27 render(attributeValue, false) @@ -169,14 +171,12 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> return if not isEditable() return if $selectedText.get().length render(attributeValue, true) - $el.find("input[name='description']").focus().select() - $scope.$apply() + $el.find("input[name='description'], textarea[name='description']").focus().select() $el.on "click", "a.icon-edit", (event) -> event.preventDefault() render(attributeValue, true) - $el.find("input[name='description']").focus().select() - $scope.$apply() + $el.find("input[name='description'], textarea[name='description']").focus().select() ## Actions (on edit mode) submit = debounce 2000, (event) => diff --git a/app/partials/custom-attributes/custom-attribute-value-edit.jade b/app/partials/custom-attributes/custom-attribute-value-edit.jade index 900518bb..a03bebd6 100644 --- a/app/partials/custom-attributes/custom-attribute-value-edit.jade +++ b/app/partials/custom-attributes/custom-attribute-value-edit.jade @@ -8,7 +8,15 @@ form.custom-field-single.editable <% } %> div.custom-field-value + + <% if (field_type=="MULTI") { %> + textarea#custom-field-description(name="description") + <%- value %> + <% } %> + + <% if (field_type=="TEXT") { %> input#custom-field-description(name="description", type="text", value!="<%- value %>") + <% } %> div.custom-field-options a.icon.icon-floppy(href="", title="{{'COMMON.CUSTOM_ATTRIBUTES.SAVE' | translate}}") diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade index 1872a0a9..f35912cb 100644 --- a/app/partials/includes/modules/admin/admin-custom-attributes.jade +++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade @@ -10,6 +10,8 @@ section.custom-fields-table.basic-table span(translate="COMMON.FIELDS.NAME") div.custom-description span(translate="COMMON.FIELDS.DESCRIPTION") + div.custom-field-type + span(translate="COMMON.FIELDS.FIELD_TYPE") div.custom-options div.table-body @@ -21,6 +23,8 @@ section.custom-fields-table.basic-table span {{ attr.name }} div.custom-description span {{ attr.description }} + div.custom-field-type + span(translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_{{ attr.field_type }}") div.custom-options div.custom-options-wrapper a.js-edit-custom-field-button.icon.icon-edit(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.EDIT' | translate}}") @@ -33,6 +37,9 @@ section.custom-fields-table.basic-table fieldset.custom-description input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}", ng-model="attr.description") + fieldset.custom-field-type + select(ng-model="attr.field_type", + ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") fieldset.custom-options div.custom-options-wrapper @@ -46,7 +53,9 @@ section.custom-fields-table.basic-table fieldset.custom-description input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}", ng-model="newAttr.description") - + fieldset.custom-field-type + select(ng-model="newAttr.field_type", + ng-options="e.id as translate(e.name) for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") fieldset.custom-options div.custom-options-wrapper a.js-create-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.SAVE_TITLE' | translate}}") diff --git a/app/styles/modules/admin/admin-custom-attributes.scss b/app/styles/modules/admin/admin-custom-attributes.scss index a6ba34fa..a507f240 100644 --- a/app/styles/modules/admin/admin-custom-attributes.scss +++ b/app/styles/modules/admin/admin-custom-attributes.scss @@ -73,6 +73,10 @@ flex-basis: 90%; flex-grow: 8; } + .custom-field-type { + flex-basis: 25%; + flex-grow: 0; + } .custom-options { flex-basis: 100px; flex-grow: 0; diff --git a/app/styles/modules/common/custom-fields.scss b/app/styles/modules/common/custom-fields.scss index 9500491a..851a1d04 100644 --- a/app/styles/modules/common/custom-fields.scss +++ b/app/styles/modules/common/custom-fields.scss @@ -67,6 +67,12 @@ .custom-field-value { flex: 1; padding: 0 1rem 0 2rem; + .read-mode { + white-space: pre + } + } + .read-mode { + white-space: pre } form { label { From ea5a78ae73fc0c3f95341b2beb1c216f5ec8dccd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 17 Jun 2015 21:38:03 +0100 Subject: [PATCH 002/403] Refining styles and adding locale string defs --- app/locales/locale-en.json | 4 +++- .../includes/modules/admin/admin-custom-attributes.jade | 2 +- app/styles/modules/admin/admin-custom-attributes.scss | 2 +- app/styles/modules/common/custom-fields.scss | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index a45f77e3..c684c476 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -448,7 +448,9 @@ "TASK_DESCRIPTION": "Tasks custom fields", "TASK_ADD": "Add a custom field in tasks", "ISSUE_DESCRIPTION": "Issues custom fields", - "ISSUE_ADD": "Add a custom field in issues" + "ISSUE_ADD": "Add a custom field in issues", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade index f35912cb..94b35d80 100644 --- a/app/partials/includes/modules/admin/admin-custom-attributes.jade +++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade @@ -11,7 +11,7 @@ section.custom-fields-table.basic-table div.custom-description span(translate="COMMON.FIELDS.DESCRIPTION") div.custom-field-type - span(translate="COMMON.FIELDS.FIELD_TYPE") + span(translate="COMMON.FIELDS.TYPE") div.custom-options div.table-body diff --git a/app/styles/modules/admin/admin-custom-attributes.scss b/app/styles/modules/admin/admin-custom-attributes.scss index a507f240..e0fdfff0 100644 --- a/app/styles/modules/admin/admin-custom-attributes.scss +++ b/app/styles/modules/admin/admin-custom-attributes.scss @@ -70,7 +70,7 @@ } .custom-description { @include ellipsis(100%); - flex-basis: 90%; + flex-basis: 50%; flex-grow: 8; } .custom-field-type { diff --git a/app/styles/modules/common/custom-fields.scss b/app/styles/modules/common/custom-fields.scss index 851a1d04..929546ba 100644 --- a/app/styles/modules/common/custom-fields.scss +++ b/app/styles/modules/common/custom-fields.scss @@ -68,11 +68,11 @@ flex: 1; padding: 0 1rem 0 2rem; .read-mode { - white-space: pre + white-space: pre; } } .read-mode { - white-space: pre + white-space: pre; } form { label { From ccec9e79b144adaffc855098757e804758ce1bbc Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 18 Jun 2015 12:20:49 +0200 Subject: [PATCH 003/403] fix user-timeline tests --- ...imeline-pagination-sequence.service.coffee | 6 +- ...ne-pagination-sequence.service.spec.coffee | 6 +- .../user-timeline.service.coffee | 8 +- .../user-timeline.service.spec.coffee | 105 +++++++++--------- 4 files changed, 62 insertions(+), 63 deletions(-) diff --git a/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.coffee b/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.coffee index 13bd45cd..7c8e08ec 100644 --- a/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.coffee +++ b/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.coffee @@ -1,5 +1,7 @@ UserTimelinePaginationSequence = () -> - return (config) -> + obj = {} + + obj.generate = (config) -> page = 1 items = Immutable.List() @@ -32,4 +34,6 @@ UserTimelinePaginationSequence = () -> next: () -> next() } + return obj + angular.module("taigaUserTimeline").factory("tgUserTimelinePaginationSequenceService", UserTimelinePaginationSequence) diff --git a/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.spec.coffee b/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.spec.coffee index 5fa4937b..95585d5c 100644 --- a/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline-pagination-sequence/user-timeline-pagination-sequence.service.spec.coffee @@ -35,7 +35,7 @@ describe "tgUserTimelinePaginationSequenceService", -> config.minItems = 10 - seq = userTimelinePaginationSequenceService(config) + seq = userTimelinePaginationSequenceService.generate(config) seq.next().then (result) -> result = result.toJS() @@ -66,7 +66,7 @@ describe "tgUserTimelinePaginationSequenceService", -> config.minItems = 10 - seq = userTimelinePaginationSequenceService(config) + seq = userTimelinePaginationSequenceService.generate(config) seq.next().then (result) -> result = result.toJS() @@ -97,7 +97,7 @@ describe "tgUserTimelinePaginationSequenceService", -> config.minItems = 2 - seq = userTimelinePaginationSequenceService(config) + seq = userTimelinePaginationSequenceService.generate(config) seq.next().then () -> seq.next().then (result) -> diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee index 83e90752..052c491b 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee @@ -70,7 +70,7 @@ class UserTimelineService extends taiga.Service return _.some @._invalid, (invalid) => return invalid.check.call(this, timeline) - getProfileTimeline: (userId, page) -> + getProfileTimeline: (userId) -> config = {} config.fetch = (page) => @@ -79,7 +79,7 @@ class UserTimelineService extends taiga.Service config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) - return @userTimelinePaginationSequenceService(config) + return @userTimelinePaginationSequenceService.generate(config) getUserTimeline: (userId) -> config = {} @@ -90,7 +90,7 @@ class UserTimelineService extends taiga.Service config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) - return @userTimelinePaginationSequenceService(config) + return @userTimelinePaginationSequenceService.generate(config) getProjectTimeline: (projectId) -> config = {} @@ -101,6 +101,6 @@ class UserTimelineService extends taiga.Service config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) - return @userTimelinePaginationSequenceService(config) + return @userTimelinePaginationSequenceService.generate(config) angular.module("taigaUserTimeline").service("tgUserTimelineService", UserTimelineService) diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee index 8dbe3c6d..4735b474 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee @@ -1,7 +1,5 @@ -describe.skip "tgUserTimelineService", -> +describe "tgUserTimelineService", -> provide = null - $q = null - $rootScope = null userTimelineService = null mocks = {} @@ -26,6 +24,7 @@ describe.skip "tgUserTimelineService", -> _mocks = () -> module ($provide) -> provide = $provide + _mockResources() _mockUserTimelinePaginationSequence() return null @@ -34,10 +33,8 @@ describe.skip "tgUserTimelineService", -> _mocks() _inject = (callback) -> - inject (_tgUserTimelineService_, _$q_, _$rootScope_) -> + inject (_tgUserTimelineService_) -> userTimelineService = _tgUserTimelineService_ - $q = _$q_ - $rootScope = _$rootScope_ callback() if callback beforeEach -> @@ -146,79 +143,77 @@ describe.skip "tgUserTimelineService", -> } ] - it "filter invalid profile timeline items", (done) -> + it "filter invalid profile timeline items", () -> userId = 3 page = 2 - mocks.resources.users.getProfileTimeline = (_userId_, _page_) -> + mocks.resources.users.getProfileTimeline = (_userId_) -> expect(_userId_).to.be.equal(userId) - expect(_page_).to.be.equal(page) - return $q (resolve, reject) -> - resolve(Immutable.fromJS(valid_items)) + return Immutable.fromJS(valid_items) + mocks.userTimelinePaginationSequence.generate = (config) -> + all = config.fetch() + expect(all.size).to.be.equal(11) - .then (_items_) -> - items = _items_.toJS() + items = config.filter(all).toJS() + expect(items).to.have.length(4) + expect(items[0]).to.be.eql(valid_items[0]) + expect(items[1]).to.be.eql(valid_items[3]) + expect(items[2]).to.be.eql(valid_items[5]) + expect(items[3]).to.be.eql(valid_items[9]) - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) - - done() + return true result = userTimelineService.getProfileTimeline(userId) + expect(result).to.be.true - mocks.userTimelinePaginationSequence.withArgs() - - - it "filter invalid user timeline items", (done) -> + it "filter invalid user timeline items", () -> userId = 3 page = 2 - mocks.resources.users.getUserTimeline = (_userId_, _page_) -> + mocks.resources.users.getUserTimeline = (_userId_) -> expect(_userId_).to.be.equal(userId) - expect(_page_).to.be.equal(page) - return $q (resolve, reject) -> - resolve(Immutable.fromJS(valid_items)) + return Immutable.fromJS(valid_items) - userTimelineService.getUserTimeline(userId, page) - .then (_items_) -> - items = _items_.toJS() + mocks.userTimelinePaginationSequence.generate = (config) -> + all = config.fetch() + expect(all.size).to.be.equal(11) - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) + items = config.filter(all).toJS() + expect(items).to.have.length(4) + expect(items[0]).to.be.eql(valid_items[0]) + expect(items[1]).to.be.eql(valid_items[3]) + expect(items[2]).to.be.eql(valid_items[5]) + expect(items[3]).to.be.eql(valid_items[9]) - done() + return true - $rootScope.$apply() + result = userTimelineService.getUserTimeline(userId) + expect(result).to.be.true - it "filter invalid project timeline items", (done) -> - projectId = 3 + it "filter invalid user timeline items", () -> + userId = 3 page = 2 - mocks.resources.projects.getTimeline = (_projectId_, _page_) -> - expect(_projectId_).to.be.equal(projectId) - expect(_page_).to.be.equal(page) + mocks.resources.projects.getTimeline = (_userId_) -> + expect(_userId_).to.be.equal(userId) - return $q (resolve, reject) -> - resolve(Immutable.fromJS(valid_items)) + return Immutable.fromJS(valid_items) - userTimelineService.getProjectTimeline(projectId, page) - .then (_items_) -> - items = _items_.toJS() + mocks.userTimelinePaginationSequence.generate = (config) -> + all = config.fetch() + expect(all.size).to.be.equal(11) - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) - done() + items = config.filter(all).toJS() + expect(items).to.have.length(4) + expect(items[0]).to.be.eql(valid_items[0]) + expect(items[1]).to.be.eql(valid_items[3]) + expect(items[2]).to.be.eql(valid_items[5]) + expect(items[3]).to.be.eql(valid_items[9]) - $rootScope.$apply() + return true + + result = userTimelineService.getProjectTimeline(userId) + expect(result).to.be.true From c1146c595e35e04053a074d8959cdae1ca55aefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 18 Jun 2015 14:43:45 +0200 Subject: [PATCH 004/403] [i18n] Update locales --- app/locales/locale-ca.json | 40 +++++++++---------- app/locales/locale-de.json | 46 +++++++++++----------- app/locales/locale-fr.json | 68 ++++++++++++++++---------------- app/locales/locale-nl.json | 80 +++++++++++++++++++------------------- 4 files changed, 117 insertions(+), 117 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index 0d31c3a7..af5b4123 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -244,7 +244,7 @@ }, "LOGIN": { "PAGE_TITLE": "Login - Taiga", - "PAGE_DESCRIPTION": "Logging in to Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_DESCRIPTION": "Entra a Taiga, una plataforma de gestió de projectes per a empreses àgils que necessiten una eïna sencilla i elegant que et permet gaudir del teu treball" }, "AUTH": { "INVITED_YOU": "T'ha convidat a participar en el projecte", @@ -266,11 +266,11 @@ "SUCCESS": "Our Oompa Loompas están contents, benvinguts a Taiga." }, "REGISTER": { - "PAGE_TITLE": "Register - Taiga", - "PAGE_DESCRIPTION": "Create your account in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "Registre - Taiga", + "PAGE_DESCRIPTION": "Crea un nou compte de Taiga, una plataforma de gestió de projectes per a empreses àgils que necessiten una eïna sencilla i elegant que et permet gaudir del teu treball" }, "REGISTER_FORM": { - "TITLE": "Register a new Taiga account (free)", + "TITLE": "Registra un nou compte de Taiga (gratis)", "PLACEHOLDER_NAME": "Trieu un nom d'usuari (sensible a majúscules i minúscules)", "PLACEHOLDER_FULL_NAME": "Escriu el teu nom complet", "PLACEHOLDER_EMAIL": "El teu correu", @@ -280,8 +280,8 @@ "LINK_LOGIN": "Ja estàs registrat? Entra" }, "FORGOT_PASSWORD": { - "PAGE_TITLE": "Forgot password - Taiga", - "PAGE_DESCRIPTION": "Enter your username or email to get a new password and you can access to Taiga again." + "PAGE_TITLE": "Recuperar contrasenya", + "PAGE_DESCRIPTION": "Escriviu el vostre nom d'usuari o correu electrònic per a conseguir-ne un de nou" }, "FORGOT_PASSWORD_FORM": { "TITLE": "Oops, has oblidat la teua contrasenya?", @@ -293,8 +293,8 @@ "ERROR": "Segons els nostres Oompa Loompas, no estàs registrat encara." }, "CHANGE_PASSWORD": { - "PAGE_TITLE": "Change you password - Taiga", - "PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_TITLE": "Canvi de contrasenya - Taiga", + "PAGE_DESCRIPTION": "Crea un nou password per Taiga i... hey! Menja un poc més de ferro, es bo pel cervell :P ", "SECTION_NAME": "Canvi de contrasenya", "FIELD_CURRENT_PASSWORD": "Contrasenya actual", "PLACEHOLDER_CURRENT_PASSWORD": "La teua contrasenya actua (buit si no tens contrasenya encara)", @@ -316,8 +316,8 @@ "SUCCESS": "Els Oompa Loompas han salvat la teua contrasenya
Prova a entrar amb ella." }, "INVITATION": { - "PAGE_TITLE": "Invitation acceptance - Taiga", - "PAGE_DESCRIPTION": "Accept the invitation to join a project in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "Acceptar invitació - Taiga", + "PAGE_DESCRIPTION": "Accepta la invitació a un projecte en Taiga, una plataforma de gestió de projectes per a empreses àgils que necessiten una eïna sencilla i elegant que et permet gaudir del teu treball" }, "INVITATION_LOGIN_FORM": { "NOT_FOUND": "Ooops, ha hagut un problema
Els nosters Oompa Loompas no troben la teua invitació.", @@ -326,16 +326,16 @@ }, "HOME": { "PAGE_TITLE": "Home - Taiga", - "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", - "EMPTY_WATCHING": "Follow the projects, User Stories, Tasks, Issues... that you want to know about :)", - "EMPTY_PROJECT_LIST": "You don't have any projects yet", - "WORKING_ON_SECTION": "Working on", - "WATCHING_SECTION": "Watching" + "PAGE_DESCRIPTION": "La home de Taiga amb els teus projectes principals, totes les històries d'usuari, tasques e incidències que tens assignades i aquelles que estàs Watching", + "EMPTY_WATCHING": "Segueix els projectes, històries d'usuari, tasques e incidències... de les que vols conèixer la evolució.", + "EMPTY_PROJECT_LIST": "No tens cap projecte encara", + "WORKING_ON_SECTION": "En Progrés", + "WATCHING_SECTION": "Observant" }, "PROJECTS": { - "PAGE_TITLE": "My projects - Taiga", - "PAGE_DESCRIPTION": "A list with all your projects, you can reorder or create a new one.", - "MY_PROJECTS": "My projects" + "PAGE_TITLE": "Els meus projectes - Taiga", + "PAGE_DESCRIPTION": "Una llista de tots els teus projects, que pots reordenar o crear nous.", + "MY_PROJECTS": "Els meus projectes." }, "ATTACHMENT": { "SECTION_NAME": "Adjunts", @@ -624,7 +624,7 @@ "USER": { "PROFILE": { "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", - "EDIT": "Edit profile", + "EDIT": "Editar perfil", "FOLLOW": "Follow", "PROJECTS": "Projectes", "CLOSED_US": "Closed US", @@ -640,7 +640,7 @@ "PROJECTS_EMPTY": "{{username}} doesn't' have projects yet" }, "PROFILE_SIDEBAR": { - "TITLE": "Your profile", + "TITLE": "El teu perfil", "DESCRIPTION": "La gent pot vore tot el que fas i en qué estàs treballant. Afegix una bio interessant per a donar una millor versió de la teua informació.", "ADD_INFO": "Edita la teua bio" } diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index b9abd76b..302ebdb1 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -22,7 +22,7 @@ "BLOCKED": "Blockiert", "CREATED_BY": "Erstellt von {{fullDisplayName}}", "FROM": "von", - "TO": "an", + "TO": "zu", "CLOSE": "schließen", "BLOCKED_NOTE": "Warum ist diese User-Story gesperrt?", "BLOCKED_REASON": "Bitte erklären Sie den Grund ", @@ -250,7 +250,7 @@ "INVITED_YOU": "hat Sie zum Projekt eingeladen", "NOT_REGISTERED_YET": "Noch nicht registiert?", "REGISTER": "Registrieren", - "CREATE_ACCOUNT": "Ein kostenloses Konto anlegen" + "CREATE_ACCOUNT": "Ein kostenloses Benutzerkonto anlegen" }, "LOGIN_COMMON": { "HEADER": "Ich bin bereits bei Taiga angemeldet", @@ -267,10 +267,10 @@ }, "REGISTER": { "PAGE_TITLE": "Registrieren - Taiga", - "PAGE_DESCRIPTION": "Erstellen Sie Ihren Account in Taiga, einer Projekt-Management Plattform für Neugründer und agile Entwickler und Designer, die ein unkompliziertes und ansprechendes Tool möchten, das die Arbeit wirklich angenehm macht. " + "PAGE_DESCRIPTION": "Erstellen Sie Ihr Benutzerkonto in Taiga, einer Projekt-Management Plattform für Neugründer und agile Entwickler und Designer, die ein unkompliziertes und ansprechendes Tool möchten, das die Arbeit wirklich angenehm macht. " }, "REGISTER_FORM": { - "TITLE": "Einen neuen Taiga Account registrieren (kostenlos)", + "TITLE": "Ein neues Taiga Benutzerkonto registrieren (kostenlos)", "PLACEHOLDER_NAME": "Wählen Sie einen Benutzernamen (Groß- und Kleinschreibung beachten)", "PLACEHOLDER_FULL_NAME": "Wählen Sie Ihren vollständigen Namen ", "PLACEHOLDER_EMAIL": "Ihre E-Mail", @@ -294,13 +294,13 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Ändern Sie Ihr Passwort - Taiga", - "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihren Taiga Account, und hey!, es empfiehlt sich, mehr eisenreiche Nahrung zu sich zu nehmen - die ist gut für's Gehirn :P", + "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihr Taiga Benutzerkonto, und hey!, es empfiehlt sich, mehr eisenreiche Nahrung zu sich zu nehmen - die ist gut für's Gehirn :P", "SECTION_NAME": "Passwort ändern", "FIELD_CURRENT_PASSWORD": "Aktuelles Passwort", "PLACEHOLDER_CURRENT_PASSWORD": "Ihr aktuelles Passwort (oder leer, wenn Sie noch kein Passwort haben)", "FIELD_NEW_PASSWORD": "Neues Passwort", "PLACEHOLDER_NEW_PASSWORD": "Geben Sie ein neues Passwort ein", - "FIELD_RETYPE_PASSWORD": "Nochmals neues Passwort eingeben", + "FIELD_RETYPE_PASSWORD": "Neues Passwort wiederholen", "PLACEHOLDER_RETYPE_PASSWORD": "Wiederholen Sie das neue Passwort", "ERROR_PASSWORD_MATCH": "Die Passwörter stimmen nicht überein" }, @@ -329,8 +329,8 @@ "PAGE_DESCRIPTION": "Die Taiga Homepage mit Ihren wichtigsten Projekten und all Ihren zugeordneten und beobachteten User-Stories, Aufgaben und Tickets. ", "EMPTY_WATCHING": "Folgen Sie den Projekten, User-Stories, Aufgaben, Tickets... über die Sie etwas wissen möchten :)", "EMPTY_PROJECT_LIST": "Sie haben noch keine Projekte", - "WORKING_ON_SECTION": "Arbeiten an", - "WATCHING_SECTION": "Beobachtung" + "WORKING_ON_SECTION": "Zuletzt bearbeitet", + "WATCHING_SECTION": "Beobachtet" }, "PROJECTS": { "PAGE_TITLE": "Meine Projekte - Taiga", @@ -505,12 +505,12 @@ "BITBUCKET": { "SECTION_NAME": "Bitbucket", "PAGE_TITLE": "Bitbucket - {{projectName}}", - "INFO_VERIFYING_IP": "Bitbucket requests are not signed so the best way of verifying the origin is by IP. If the field is empty there will be no IP validation." + "INFO_VERIFYING_IP": "Bitbucket Anfragen sind nicht signiert, daher ist der beste Weg die Quelle anhand der IP zu prüfen. Wenn das Feld leer bleibt, wird keine Prüfung der IP vorgenommen." }, "GITLAB": { "SECTION_NAME": "Gitlab", "PAGE_TITLE": "Gitlab - {{projectName}}", - "INFO_VERIFYING_IP": "Gitlab requests are not signed so the best way of verifying the origin is by IP. If the field is empty there will be no IP validation." + "INFO_VERIFYING_IP": "Gitlab rAnfragen sind nicht signiert, daher ist der beste Weg die Quelle anhand der IP zu prüfen. Wenn das Feld leer bleibt, wird keine Prüfung der IP vorgenommen." }, "GITHUB": { "SECTION_NAME": "Github", @@ -641,7 +641,7 @@ }, "PROFILE_SIDEBAR": { "TITLE": "Ihr Profil", - "DESCRIPTION": "People can see everything you do and what are you working on. Add a nice bio to give an enhanced version of your information.", + "DESCRIPTION": "Da andere Mitglieder sehen, dass sie ebenfalls an einem Projekt arbeiten wäre es schön, wenn Sie ein paar Informationen zu Ihrer Person angeben.", "ADD_INFO": "Bearbeiten Sie Ihre Bio" } }, @@ -649,7 +649,7 @@ "PAGE_TITLE": "{{projectName}}", "WELCOME": "Willkommen", "SECTION_PROJECTS": "Projekte", - "HELP": "Reorder your projects to set in the top the most used ones.
The top 10 projects will appear in the top navigation bar project list", + "HELP": "Sortieren Sie Ihre Projekte nach Wichtigkeit.
Die ersten 10 Projekte erscheinen prominent in der Projektliste der Navigationsleiste.", "PRIVATE": "Privates Projekt", "STATS": { "PROJECT": "Projekt
Punkte", @@ -715,8 +715,8 @@ }, "LIGHTBOX": { "DELETE_ACCOUNT": { - "SECTION_NAME": "Taiga Konto löschen", - "CONFIRM": "Sind Sie sicher, dass Sie Ihr Taiga Konto löschen wollen?", + "SECTION_NAME": "Taiga Benutzerkonto löschen", + "CONFIRM": "Sind Sie sicher, dass Sie Ihr Taiga Benutzerkonto löschen wollen?", "SUBTITLE": "Wir werden Sie vermissen! :-(", "NEWSLETTER_LABEL_TEXT": "Ich möchte keinen Newsletter mehr erhalten" }, @@ -794,7 +794,7 @@ "PREVIOUS": "Vorherige User-Story", "NEXT": "nächste User-Story", "TITLE_DELETE_ACTION": "User-Story löschen", - "LIGHTBOX_TITLE_BLOKING_US": "Blocking us", + "LIGHTBOX_TITLE_BLOKING_US": "Blockiert uns", "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} Aufgaben fertiggestellt", "ASSIGN": "Zugeordnete User-Story", "NOT_ESTIMATED": "Nicht abgeschätzt", @@ -826,7 +826,7 @@ "DELETED_ATTACHMENT": "Gelöschter Anhang", "UPDATED_ATTACHMENT": "aktualisierter Anhang {{filename}}", "DELETED_CUSTOM_ATTRIBUTE": "gelöschtes Kundenattribut ", - "SIZE_CHANGE": "Made {size, plural, one{one change} other{# changes}}", + "SIZE_CHANGE": "Machte {size, plural, one{eine Änderung} other{# Änderungen}}", "VALUES": { "YES": "ja", "NO": "nein", @@ -945,7 +945,7 @@ "NOT_FOUND_TEXT": "Fehler 404. Die angeforderte Seite existiert nicht mehr. Möglicherweise finden Sie das Gesuchte, wenn Sie zur TAIGA Homepage zurückkehren. ", "PERMISSION_DENIED": "Berechtigung verweigert", "PERMISSION_DENIED_CODE": "Fehler 403.", - "VERSION_ERROR": "Someone inside Taiga has changed this before and our Oompa Loompas cannot apply your changes. Please reload and apply your changes again (they will be lost)." + "VERSION_ERROR": "Jemand anderes hat dies schon geändert und unsere Heinzelmännchen können Ihre Änderungen deshalb nicht übernehmen. Bitte laden Sie die Seite neu und machen Sie die Änderungen erneut (die aktuelle Eingabe geht dabei verloren)." }, "TASKBOARD": { "PAGE_TITLE": "{{sprintName}} - Sprint Taskboard - {{projectName}}", @@ -1009,9 +1009,9 @@ "CANCEL_ACCOUNT": { "TITLE": "Ihr Benutzerkonto löschen", "SUBTITLE": "Wir bedauern, dass Sie die Taiga verlassen. Wir hoffen, Sie hatten einen angenehmen Aufenthalt. :)", - "PLACEHOLDER_INPUT_TOKEN": "Account Token ungültig machen", + "PLACEHOLDER_INPUT_TOKEN": "Benutzerkonto Token ungültig machen", "ACTION_LEAVING": "Ja, ich gehe! ", - "SUCCESS": "Unsere Heinzelmännchen haben Ihren Account entfernt. " + "SUCCESS": "Unsere Heinzelmännchen haben Ihr Benutzerkonto entfernt. " }, "CHANGE_EMAIL_FORM": { "TITLE": "Ändern Sie Ihre E-Mail", @@ -1170,8 +1170,8 @@ "USER_PROFILE": { "IMAGE_HELP": "Das Bild wird auf 80x80px skaliert.
", "ACTION_CHANGE_IMAGE": "Änderung", - "ACTION_USE_GRAVATAR": "Benutze Gravatar ", - "ACTION_DELETE_ACCOUNT": "Taiga Account löschen", + "ACTION_USE_GRAVATAR": "Gravatar verwenden", + "ACTION_DELETE_ACCOUNT": "Taiga Benutzerkonto löschen", "CHANGE_EMAIL_SUCCESS": "Sehen Sie in Ihren Posteingang!
Wir haben eine E-Mail an Ihr Konto gesendet
mit der Anleitung, wie Sie Ihre neue Adresse anlegen", "CHANGE_PHOTO": "Foto ändern", "FIELD": { @@ -1219,9 +1219,9 @@ "HINT2_TITLE": "Wussten Sie, dass Sie benutzerdefinierte Felder erstellen können?", "HINT2_TEXT": "Teams können jetzt benutzerdefinierte Felder erstellen, als eine flexible Möglichkeit, spezifische Daten einzutragen. Dies ist praktisch für ihren jeweiligen Arbeitsablauf", "HINT3_TITLE": "Sortieren Sie ihre Projekte neu, um die zu zeigen, die für Sie am relevantesten sind", - "HINT3_TEXT": "The top 10 project will be in your top bar direct access", + "HINT3_TEXT": "Das Top 10 Projekt wird in der Navigationsleiste direkt zugreifbar sein.", "HINT4_TITLE": "Haben Sie vergessen, woran Sie arbeiten?", - "HINT4_TEXT": "Don't worry, on your dashboard you'll find your open tasks, issues, and user stories in the order you worked on them." + "HINT4_TEXT": "Machen Sie sich keine Sorgen, im Dashboard finden Sie Aufgaben, Tickets und User-Stories in der Reihenfolge in der Sie diese bearbeitet haben." }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} hat einen neuen Anhang hochgeladen in {{obj_name}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index d3a5ebfa..379ce57e 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -239,12 +239,12 @@ }, "META": { "PAGE_TITLE": "Taiga", - "PAGE_DESCRIPTION": "Taiga is a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_DESCRIPTION": "Taiga est une plateforme de gestion de projets pour les startups, les développeurs et les designers agiles qui veulent un outil simple, beau et qui rend le travail vraiment agréable." } }, "LOGIN": { "PAGE_TITLE": "Connexion - Taiga", - "PAGE_DESCRIPTION": "Logging in to Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_DESCRIPTION": "Connectez-vous à Taiga, une plateforme de gestion de projets pour les startups, les développeurs et les designers agiles qui veulent un outil simple, beau et qui rend le travail vraiment agréable." }, "AUTH": { "INVITED_YOU": "vous a invité-e à rejoindre le projet", @@ -266,8 +266,8 @@ "SUCCESS": "Nos Oompa Loompas sont heureux, bienvenue sur Taiga." }, "REGISTER": { - "PAGE_TITLE": "Register - Taiga", - "PAGE_DESCRIPTION": "Create your account in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "S'inscrire - Taiga", + "PAGE_DESCRIPTION": "Créez votre compte sur Taiga, une plateforme de gestion de projets pour les startups, les développeurs et les designers agiles qui veulent un outil simple, beau et qui rend le travail vraiment agréable." }, "REGISTER_FORM": { "TITLE": "Créer un compte Taiga (gratuit)", @@ -280,8 +280,8 @@ "LINK_LOGIN": "Êtes-vous déjà enregistré? Connectez-vous." }, "FORGOT_PASSWORD": { - "PAGE_TITLE": "Forgot password - Taiga", - "PAGE_DESCRIPTION": "Enter your username or email to get a new password and you can access to Taiga again." + "PAGE_TITLE": "Mot de passe oublié - Taiga", + "PAGE_DESCRIPTION": "Saisissez votre nom d'utilisateur ou votre adresse courriel pour recevoir un nouveau mot de passe et accéder à nouveau à Taiga." }, "FORGOT_PASSWORD_FORM": { "TITLE": "Oops, avez-vous oublié votre mot de passe ?", @@ -316,8 +316,8 @@ "SUCCESS": "Nos Oompa Loompas ont sauvegardé votre nouveau mot de passe.
Essayez de vous connecter avec." }, "INVITATION": { - "PAGE_TITLE": "Invitation acceptance - Taiga", - "PAGE_DESCRIPTION": "Accept the invitation to join a project in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "Acceptation des invitations - Taiga", + "PAGE_DESCRIPTION": "Acceptez l'invitation à rejoindre un projet sur Taiga, une plateforme de gestion de projets pour les startups, les développeurs et les designers agiles qui veulent un outil simple, beau et qui rend le travail vraiment agréable." }, "INVITATION_LOGIN_FORM": { "NOT_FOUND": "Oh là là, nous avons un problème
Nos Oompa Loompas trouvent pas votre invitation.", @@ -325,16 +325,16 @@ "ERROR": "D'après nos Oompa Loompas, vous n'êtes pas encore enregistrés ou vous avez saisi un mot de passe incorrect." }, "HOME": { - "PAGE_TITLE": "Home - Taiga", - "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", + "PAGE_TITLE": "Accueil - Taiga", + "PAGE_DESCRIPTION": "La page d'accueil de Taiga sur laquelle apparaissent vos projets principaux et toutes les récits utilisateur, tâches et suivis de problèmes qui vont sont assignés et surveillés.", "EMPTY_WATCHING": "Suivre les projets, Récits Utilisateur, Tâches, Problèmes... que vous voulez connaître :)", - "EMPTY_PROJECT_LIST": "You don't have any projects yet", + "EMPTY_PROJECT_LIST": "Vous n'avez aucun projet pour l'instant", "WORKING_ON_SECTION": "Projets en cours", "WATCHING_SECTION": "Observant" }, "PROJECTS": { "PAGE_TITLE": "Mes projets - Taiga", - "PAGE_DESCRIPTION": "A list with all your projects, you can reorder or create a new one.", + "PAGE_DESCRIPTION": "Une liste de tous vos projets, vous pouvez la trier ou en créer une nouvelle.", "MY_PROJECTS": "Mes projets" }, "ATTACHMENT": { @@ -374,7 +374,7 @@ }, "MEMBERSHIPS": { "TITLE": "Gérer les membres", - "PAGE_TITLE": "Memberships - {{projectName}}", + "PAGE_TITLE": "Membres - {{projectName}}", "ADD_BUTTON": "+ Nouveau membre", "ADD_BUTTON_TITLE": "Ajouter un membre" }, @@ -451,7 +451,7 @@ "ISSUE_ADD": "Ajouter un champ personnalisé dans les problèmes" }, "PROJECT_VALUES": { - "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - Valeurs du projet - {{projectName}}", "REPLACEMENT": "Tous les éléments avec cette valeur seront modifiés pour ", "ERROR_DELETE_ALL": "Vous ne pouvez pas effacer toutes les valeurs." }, @@ -641,7 +641,7 @@ }, "PROFILE_SIDEBAR": { "TITLE": "Votre profil", - "DESCRIPTION": "People can see everything you do and what are you working on. Add a nice bio to give an enhanced version of your information.", + "DESCRIPTION": "Tout le monde peut voir ce que vous faites et ce sur quoi vous travaillez. Ajoutez une bio détaillée pour améliorer la vision perçue de votre profil.", "ADD_INFO": "Modifier votre biographie" } }, @@ -778,8 +778,8 @@ } }, "US": { - "PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Completed {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). Points: {{userStoryPoints}}. Description: {{userStoryDescription}}", + "PAGE_TITLE": "{{userStorySubject}} - Récit utilisateur {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "État : {{userStoryStatus }}. Achevé {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} sur {{userStoryTotalTasks}} tâches fermées). Points : {{userStoryPoints}}. Description : {{userStoryDescription}}", "SECTION_NAME": "Détails du récit utilisateur", "LINK_TASKBOARD": "Tableau des tâches", "TITLE_LINK_TASKBOARD": "Aller au tableau des tâches", @@ -867,8 +867,8 @@ } }, "BACKLOG": { - "PAGE_TITLE": "Backlog - {{projectName}}", - "PAGE_DESCRIPTION": "The backlog panel, with user stories and sprints of the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "Carnet - {{projectName}}", + "PAGE_DESCRIPTION": "Le panneau carnet avec les récits utilisateurs et sprints du projet {{projectName}} : {{projectDescription}}", "SECTION_NAME": "Carnet", "MOVE_US_TO_CURRENT_SPRINT": "Déplacer vers le Sprint Courant", "SHOW_FILTERS": "Afficher les filtres", @@ -948,8 +948,8 @@ "VERSION_ERROR": "Quelqu'un a changé ça auparavant dans Taiga et nos Oompa Loompas ne peuvent appliquer vos modifications. Veuillez recharger la page et appliquer vos modifications de nouveaux (elles seront perdues)." }, "TASKBOARD": { - "PAGE_TITLE": "{{sprintName}} - Sprint taskboard - {{projectName}}", - "PAGE_DESCRIPTION": "Sprint {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. Completed {{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} opened tasks of {{totalTasks}}.", + "PAGE_TITLE": "{{sprintName}} - Liste de tâches du sprint - {{projectName}}", + "PAGE_DESCRIPTION": "Sprint {{sprintName}} (du {{startDate}} au {{endDate}}) de {{projectName}}. Achevé {{completedPercentage}}% ({{completedPoints}} sur {{totalPoints}} points). {{openTasks}} tâches ouvertes sur {{totalTasks}}.", "SECTION_NAME": "Tableau des tâches", "TITLE_ACTION_ADD": "Ajouter une nouvelle tâche", "TITLE_ACTION_ADD_BULK": "Ajouter de nouvelles tâches en lot", @@ -973,7 +973,7 @@ } }, "TASK": { - "PAGE_TITLE": "{{taskSubject}} - Task {{taskRef}} - {{projectName}}", + "PAGE_TITLE": "{{taskSubject}} - Tâche {{taskRef}} - {{projectName}}", "PAGE_DESCRIPTION": "État: {{taskStatus }}. Description: {{taskDescription}}", "SECTION_NAME": "Détails de la tâche", "LINK_TASKBOARD": "Tableau des tâches", @@ -1022,7 +1022,7 @@ }, "ISSUES": { "PAGE_TITLE": "Problèmes - {{projectName}}", - "PAGE_DESCRIPTION": "The issues list panel of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Le panneau de la liste des problèmes du projet {{projectName}} : {{projectDescription}}", "LIST_SECTION_NAME": "Problèmes", "SECTION_NAME": "Detalhes do problema", "ACTION_NEW_ISSUE": "+ NOUVEAU PROBLÈME", @@ -1087,12 +1087,12 @@ } }, "ISSUE": { - "PAGE_TITLE": "{{issueSubject}} - Issue {{issueRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priority: {{issuePriority}}. Severity: {{issueSeverity}}. Description: {{issueDescription}}" + "PAGE_TITLE": "{{issueSubject}} - Problème {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "État : {{issueStatus }}. Type : {{issueType}}, Priorité : {{issuePriority}}. Sévérité : {{issueSeverity}}. Description : {{issueDescription}}" }, "KANBAN": { "PAGE_TITLE": "Kanban - {{projectName}}", - "PAGE_DESCRIPTION": "The kanban panel, with user stories of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Le panneau kanban avec les récits utilisateurs du {{projectName}} : {{projectDescription}}", "SECTION_NAME": "Kanban", "TITLE_ACTION_FOLD": "Replier la colonne", "TITLE_ACTION_UNFOLD": "Déplier la colonne", @@ -1108,7 +1108,7 @@ }, "SEARCH": { "PAGE_TITLE": "Chercher - {{projectName}}", - "PAGE_DESCRIPTION": "Search anything, user stories, issues, tasks or wiki pages, in the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Chercher tout, récits utilisateurs, problèmes, tâches ou pages de wiki, dans le projet {{projectName}} : {{projectDescription}}", "FILTER_USER_STORIES": "Récits utilisateur", "FILTER_ISSUES": "Problèmes", "FILTER_TASKS": "Tâches", @@ -1120,7 +1120,7 @@ }, "TEAM": { "PAGE_TITLE": "EQUIPE - {{projectName}}", - "PAGE_DESCRIPTION": "The team panel to show all the members of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Le panneau équipe montre la liste des membres du projet {{projectName}} : {{projectDescription}}", "SECTION_NAME": "Equipe", "APP_TITLE": "EQUIPE - {{projectName}}", "PLACEHOLDER_INPUT_SEARCH": "Rechercher par nom...", @@ -1217,18 +1217,18 @@ "HINT1_TITLE": "Savez-vous que vous pouvez importer et exporter les projets?", "HINT1_TEXT": "Cela vous permet d'extraire toutes vos données d'un Taiga et de le déplacer vers un autre", "HINT2_TITLE": "Savez-vous que vous pouvez créer des champs personnalisés ?", - "HINT2_TEXT": "Teams can now create custom fields as a flexible means to enter specific data useful for their particular workflow", - "HINT3_TITLE": "Reorder your projects to feature those most relevant to you", - "HINT3_TEXT": "The top 10 project will be in your top bar direct access", - "HINT4_TITLE": "Did you forgot what were you working on?", - "HINT4_TEXT": "Don't worry, on your dashboard you'll find your open tasks, issues, and user stories in the order you worked on them." + "HINT2_TEXT": "Les équipes peuvent maintenant créer des champs personnalisés de façon à leur permettre de saisir les données qui font sens à leur flux de travail", + "HINT3_TITLE": "Triez vos projets pour mettre en avant ceux qui sont les plus pertinants pour vous", + "HINT3_TEXT": "Vos 10 principaux projets seront accessibles via la barre du haut", + "HINT4_TITLE": "Avez-vous oublié ce sur quoi vous travailliez ?", + "HINT4_TEXT": "Pas d'inquiétude, vous trouverez dans votre tableau de bord vos tâches, problèmes et récits utilisateurs dans l'ordre dans lequel vous avez travaillé dessus." }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} a téléversé une nouvelle pièce jointe dans {{obj_name}}", "US_CREATED": "{{username}} a créé un nouveau récit utilisateur {{obj_name}} dans {{project_name}}", "ISSUE_CREATED": "{{username}} a créé un nouveau suivi de problème {{obj_name}} dans {{project_name}}", "TASK_CREATED": "{{username}} a créé une nouvelle Tâche {{obj_name}} dans {{project_name}}", - "TASK_CREATED_WITH_US": "{{username}} has created a new task {{obj_name}} in {{project_name}} which belongs to the US {{us_name}}", + "TASK_CREATED_WITH_US": "{{username}} a créé une nouvelle tâche {{obj_name}} dans le projet {{project_name}} pour le récit utilisateur {{us_name}}", "WIKI_CREATED": "{{username}} a créé une nouvelle page wiki {{obj_name}} dans {{project_name}}", "MILESTONE_CREATED": "{{username}} a créé un nouveau sprint {{obj_name}} dans {{project_name}}", "NEW_PROJECT": "{{username}} a créé le projet {{project_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 2810a196..02baf2ab 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -316,8 +316,8 @@ "SUCCESS": "Onze Oempa-Loempas hebben je nieuwe wachtwoord opgeslagen.
Probeer ermee in te loggen." }, "INVITATION": { - "PAGE_TITLE": "Invitation acceptance - Taiga", - "PAGE_DESCRIPTION": "Accept the invitation to join a project in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "Uitnodiging accepteren - Taiga", + "PAGE_DESCRIPTION": "Accepteer de uitnodiging voor een project in Taiga, een project management platform voor startups en agile ontwikkelaars & designers die een simpele, mooie tool willen om werken echt leuk te maken." }, "INVITATION_LOGIN_FORM": { "NOT_FOUND": "Ooeps, we hebben een probleem
Onze Oempa-Loempa's kunnen je uitnodiging niet vinden.", @@ -325,16 +325,16 @@ "ERROR": "Volgens onze Oempa-Loempa's, ben je nog niet geregistreerd of heb je een fout wachtwoord getypt." }, "HOME": { - "PAGE_TITLE": "Home - Taiga", - "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", + "PAGE_TITLE": "Home -Taiga", + "PAGE_DESCRIPTION": "De Taiga start pagina met jouw projecten en de aan jou toegewezen en gevolgde user stories, taken en issues", "EMPTY_WATCHING": "Volg de projecten, User Stories, Taken, Issues... waarvan je op de hoogte gehouden wilt worden :)", - "EMPTY_PROJECT_LIST": "You don't have any projects yet", + "EMPTY_PROJECT_LIST": "Je hebt nog geen projecten", "WORKING_ON_SECTION": "Werkt aan", "WATCHING_SECTION": "Volgers" }, "PROJECTS": { - "PAGE_TITLE": "My projects - Taiga", - "PAGE_DESCRIPTION": "A list with all your projects, you can reorder or create a new one.", + "PAGE_TITLE": "Mijn projecten - Taiga", + "PAGE_DESCRIPTION": "Een lijst met al jouw projecten, je kunt deze herodenen of een nieuwe aanmaken.", "MY_PROJECTS": "Mijn projecten" }, "ATTACHMENT": { @@ -374,7 +374,7 @@ }, "MEMBERSHIPS": { "TITLE": "Gebruikers beheren", - "PAGE_TITLE": "Memberships - {{projectName}}", + "PAGE_TITLE": "Lidmaatschappen - {{projectName}}", "ADD_BUTTON": "+ Nieuwe gebruiker", "ADD_BUTTON_TITLE": "Nieuwe gebruiker toevoegen" }, @@ -451,7 +451,7 @@ "ISSUE_ADD": "Voeg een aangepast veld toe in issues" }, "PROJECT_VALUES": { - "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - Project waardes - {{projectName}}", "REPLACEMENT": "Alle items met deze waarde zullen worden veranderd in", "ERROR_DELETE_ALL": "Je kunt niet alle waardes verwijderen" }, @@ -464,13 +464,13 @@ "PROJECT_VALUES_PRIORITIES": { "TITLE": "Prioriteit", "SUBTITLE": "Specificeer de prioriteit die je issues zullen hebben", - "ISSUE_TITLE": "Issue priorities", + "ISSUE_TITLE": "Issue prioriteit", "ACTION_ADD": "Nieuwe prioriteit toevoegen" }, "PROJECT_VALUES_SEVERITIES": { - "TITLE": "Severities", + "TITLE": "Ernstniveaus", "SUBTITLE": "Specifieer de ernstigheid die je issues zullen hebben", - "ISSUE_TITLE": "Issue severities", + "ISSUE_TITLE": "Ernst van het issue", "ACTION_ADD": "Nieuwe ernst toevoegen" }, "PROJECT_VALUES_STATUS": { @@ -487,7 +487,7 @@ "ACTION_ADD": "Voeg nieuwe {{objName}} toe" }, "ROLES": { - "PAGE_TITLE": "Roles - {{projectName}}", + "PAGE_TITLE": "Rollen - {{projectName}}", "WARNING_NO_ROLE": "Wees voorzichtig, geen enkele rol in je project zal de puntenwaarde van een user story kunnen estimeren", "HELP_ROLE_ENABLED": "Als dit actief is, zullen leden met deze rol de punten waarde voor user stories kunnen schatten", "COUNT_MEMBERS": "{{ role.members_count }} leden met deze rol", @@ -543,7 +543,7 @@ "WEBHOOK_NAME": "Webhook '{{name}}'" }, "CUSTOM_ATTRIBUTES": { - "PAGE_TITLE": "{{sectionName}} - Custom Attributes - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - Eigen attributen - {{projectName}}", "ADD": "Voeg aangepast veld toe", "EDIT": "Eigen veld bewerken", "DELETE": "Eigen veld verwijderen", @@ -641,8 +641,8 @@ }, "PROFILE_SIDEBAR": { "TITLE": "Jouw profiel", - "DESCRIPTION": "People can see everything you do and what are you working on. Add a nice bio to give an enhanced version of your information.", - "ADD_INFO": "Edit your bio" + "DESCRIPTION": "Mensen kunnen alles zien wat je doet en waar je aan werkt. Voeg een mooie biografie toe voor een meer uitgebreide versie van jouw informatie.", + "ADD_INFO": "Bewerk je bio" } }, "PROJECT": { @@ -672,10 +672,10 @@ "SECTION_TITLE": "Jouw projecten", "PLACEHOLDER_SEARCH": "Zoeken in...", "ACTION_CREATE_PROJECT": "Project aanmaken", - "ACTION_IMPORT_PROJECT": "Import project", + "ACTION_IMPORT_PROJECT": "Importeer project", "SEE_MORE_PROJECTS": "Bekijk meer projecten", - "TITLE_CREATE_PROJECT": "Create project", - "TITLE_IMPORT_PROJECT": "Import project", + "TITLE_CREATE_PROJECT": "Project aanmaken", + "TITLE_IMPORT_PROJECT": "Importeer project", "TITLE_PRVIOUS_PROJECT": "Toon voorgaande projecten", "TITLE_NEXT_PROJECT": "Toon volgende projecten", "HELP_TITLE": "Taiga support pagina", @@ -779,7 +779,7 @@ }, "US": { "PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Completed {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). Points: {{userStoryPoints}}. Description: {{userStoryDescription}}", + "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Voltooid {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} van {{userStoryTotalTasks}} taken gesloten). Punten: {{userStoryPoints}}. Omschrijving: {{userStoryDescription}}", "SECTION_NAME": "User story details", "LINK_TASKBOARD": "Taakbord", "TITLE_LINK_TASKBOARD": "Ga naar het dashboard", @@ -868,7 +868,7 @@ }, "BACKLOG": { "PAGE_TITLE": "Backlog - {{projectName}}", - "PAGE_DESCRIPTION": "The backlog panel, with user stories and sprints of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Het backlog overzicht, met user stories en sprints van het project {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Backlog", "MOVE_US_TO_CURRENT_SPRINT": "Verplaats naar huidige sprint", "SHOW_FILTERS": "Toon filters", @@ -948,8 +948,8 @@ "VERSION_ERROR": "Iemand bij Taiga heeft dit vooraf veranderd en onze Oempa-Loempa's konden je veranderingen niet toepassen. Gelieve te herladen en je veranderingen opnieuw toe te passen (ze zullen verloren gaan)" }, "TASKBOARD": { - "PAGE_TITLE": "{{sprintName}} - Sprint taskboard - {{projectName}}", - "PAGE_DESCRIPTION": "Sprint {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. Completed {{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} opened tasks of {{totalTasks}}.", + "PAGE_TITLE": "{{sprintName}} - Sprint taakbord - {{projectName}}", + "PAGE_DESCRIPTION": "Sprint {{sprintName}} (van {{startDate}} tot {{endDate}}) van {{projectName}}. Voltooid {{completedPercentage}}% ({{completedPoints}} van {{totalPoints}} punten). {{openTasks}} geopende taken van {{totalTasks}}.", "SECTION_NAME": "Taakbord", "TITLE_ACTION_ADD": "Voeg een nieuwe taak toe", "TITLE_ACTION_ADD_BULK": "Wat nieuwe taken in bulk toevoegen", @@ -973,8 +973,8 @@ } }, "TASK": { - "PAGE_TITLE": "{{taskSubject}} - Task {{taskRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{taskStatus }}. Description: {{taskDescription}}", + "PAGE_TITLE": "{{taskSubject}} - Taak {{taskRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Status: {{taskStatus }}. Omschrijving: {{taskDescription}}", "SECTION_NAME": "Taak details", "LINK_TASKBOARD": "Taakbord", "TITLE_LINK_TASKBOARD": "Ga naar het taakbord", @@ -1022,7 +1022,7 @@ }, "ISSUES": { "PAGE_TITLE": "Issues - {{projectName}}", - "PAGE_DESCRIPTION": "The issues list panel of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Het issue lijst overzicht van het project {{projectName}}: {{projectDescription}}", "LIST_SECTION_NAME": "Issues", "SECTION_NAME": "Issue details", "ACTION_NEW_ISSUE": "+ nieuw probleem", @@ -1088,11 +1088,11 @@ }, "ISSUE": { "PAGE_TITLE": "{{issueSubject}} - Issue {{issueRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priority: {{issuePriority}}. Severity: {{issueSeverity}}. Description: {{issueDescription}}" + "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Prioriteit: {{issuePriority}}. Ernst: {{issueSeverity}}. Omschrijving: {{issueDescription}}" }, "KANBAN": { "PAGE_TITLE": "Kanban - {{projectName}}", - "PAGE_DESCRIPTION": "The kanban panel, with user stories of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Het kanban overzicht, met user stories van het project {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Kanban", "TITLE_ACTION_FOLD": "Kolom inklappen", "TITLE_ACTION_UNFOLD": "Kolom uitklappen", @@ -1107,8 +1107,8 @@ "UNDO_ARCHIVED": "Drag & drop nog een keer om ongedaan te maken" }, "SEARCH": { - "PAGE_TITLE": "Search - {{projectName}}", - "PAGE_DESCRIPTION": "Search anything, user stories, issues, tasks or wiki pages, in the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "Zoek - {{projectName}}", + "PAGE_DESCRIPTION": "Zoek op alles, user stories, issues, taken, wiki pagina's, in het project {{projectName}}: {{projectDescription}}", "FILTER_USER_STORIES": "User Stories", "FILTER_ISSUES": "Issues", "FILTER_TASKS": "Taken", @@ -1120,7 +1120,7 @@ }, "TEAM": { "PAGE_TITLE": "Team - {{projectName}}", - "PAGE_DESCRIPTION": "The team panel to show all the members of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Het team overzicht toont alle leden van het project {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Team", "APP_TITLE": "TEAM - {{projectName}}", "PLACEHOLDER_INPUT_SEARCH": "Zoek op volledige naam", @@ -1195,7 +1195,7 @@ }, "WIKI": { "PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}", - "PAGE_DESCRIPTION": "Last edition on {{lastModifiedDate}} ({{totalEditions}} editions in total) Content: {{ wikiPageContent }}", + "PAGE_DESCRIPTION": "Laatst bewerkt op {{lastModifiedDate}} ({{totalEditions}} keer bewerkt in totaal) Inhoud: {{ wikiPageContent }}", "DATETIME": "DD MMM YYYY HH:mm", "PLACEHOLDER_PAGE": "Schrijf je wiki pagina", "REMOVE": "Verwijder deze wiki pagina", @@ -1217,21 +1217,21 @@ "HINT1_TITLE": "Wist je dat je nu projecten kunt importeren en exporteren?", "HINT1_TEXT": "Dit maakt het mogelijk om al je data vanuit de ene taiga te verplaatsen naar een andere", "HINT2_TITLE": "Weet je dat je custom velden kunt aanmaken?", - "HINT2_TEXT": "Teams can now create custom fields as a flexible means to enter specific data useful for their particular workflow", - "HINT3_TITLE": "Reorder your projects to feature those most relevant to you", - "HINT3_TEXT": "The top 10 project will be in your top bar direct access", - "HINT4_TITLE": "Did you forgot what were you working on?", - "HINT4_TEXT": "Don't worry, on your dashboard you'll find your open tasks, issues, and user stories in the order you worked on them." + "HINT2_TEXT": "Teams kunnen nu eigen velden definiëren als een flexibele manier om specifieke data in te voeren die nuttig is voor hun specifieke workflow", + "HINT3_TITLE": "Herorden je projecten zodat de belangrijkste bovenaan staan", + "HINT3_TEXT": "De top 10 projecten verschijnen in je directe toegang bovenbalk", + "HINT4_TITLE": "Ben je vergeten waar je aan hebt gewerkt?", + "HINT4_TEXT": "Maak je geen zorgen, op je dashboard vind je al jouw open taken, issues en user stories in de volgorde waarin je hebt gewerkt." }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} heeft een nieuwe bijlage geüpload in {{obj_name}}", "US_CREATED": "{{username}} heeft een nieuwe US aangemaakt {{obj_name}} in {{project_name}}", "ISSUE_CREATED": "{{username}} heeft een nieuw Issue aangemaakt {{obj_name}} in {{project_name}}", "TASK_CREATED": "{{username}} heeft een nieuwe taak aangemaakt {{obj_name}} in {{project_name}}", - "TASK_CREATED_WITH_US": "{{username}} has created a new task {{obj_name}} in {{project_name}} which belongs to the US {{us_name}}", + "TASK_CREATED_WITH_US": "{{username}} heeft de nieuwe taak {{obj_name}} aangemakt in {{project_name}} die hoort bij de US {{us_name}}", "WIKI_CREATED": "{{username}} heeft een nieuwe Wiki-pagina aangemaakt {{obj_name}} in {{project_name}}", "MILESTONE_CREATED": "{{username}} heeft een nieuwe sprint aangemaakt {{obj_name}} in {{project_name}}", - "NEW_PROJECT": "{{username}} created the project {{project_name}}", + "NEW_PROJECT": "{{username}} heeft een nieuw project aangemaakt {{project_name}}", "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", @@ -1246,6 +1246,6 @@ "US_REMOVED_FROM_MILESTONE": "{{username}} heeft de US {{obj_name}} toegevoegd aan de Backlog", "BLOCKED": "{{username}} heeft {{obj_name}} geblokkeerd", "UNBLOCKED": "{{username}} heeft {{obj_name}} gedeblokkeerd", - "NEW_USER": "{{username}} has joined Taiga" + "NEW_USER": "{{username}} heeft zich aangemeld voor Taiga" } } \ No newline at end of file From e0366ce64f9b807cb4d321f89f2293d91c828fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 18 Jun 2015 15:12:27 +0200 Subject: [PATCH 005/403] issue #2893 - Fix role selector in admin > members --- app/coffee/modules/admin/memberships.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/coffee/modules/admin/memberships.coffee b/app/coffee/modules/admin/memberships.coffee index 9d46467c..3cb8ae9b 100644 --- a/app/coffee/modules/admin/memberships.coffee +++ b/app/coffee/modules/admin/memberships.coffee @@ -90,7 +90,6 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai loadInitialData: -> promise = @.loadProject() promise.then => - @.loadUsersAndRoles() @.loadMembers() return promise @@ -301,7 +300,7 @@ MembershipsRowRoleSelectorDirective = ($log, $repo, $confirm) -> link = ($scope, $el, $attrs) -> render = (member) -> ctx = { - roleList: $scope.roles, + roleList: $scope.project.roles, selectedRole: member.role } From eece62792c1b666ff144387792d45619f269cdd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 18 Jun 2015 18:03:36 +0200 Subject: [PATCH 006/403] Issue #2902: Fix role selector at the new member lightbox --- app/coffee/modules/admin/lightboxes.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/admin/lightboxes.coffee b/app/coffee/modules/admin/lightboxes.coffee index b8230dfa..9b43695c 100644 --- a/app/coffee/modules/admin/lightboxes.coffee +++ b/app/coffee/modules/admin/lightboxes.coffee @@ -57,7 +57,7 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading, lightboxService, link = ($scope, $el, $attrs) -> createFieldSet = (required = true)-> - ctx = {roleList: $scope.roles, required: required} + ctx = {roleList: $scope.project.roles, required: required} return $compile(template(ctx))($scope) resetForm = -> From e878015b7becb4d97ba86d74d8be7319579c298e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Fri, 19 Jun 2015 11:22:16 +0200 Subject: [PATCH 007/403] issue #2904: Fix wiki meta title --- app/coffee/modules/wiki/main.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 4386a1e0..7316ba5c 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -68,8 +68,8 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) _setMeta: -> title = @translate.instant("WIKI.PAGE_TITLE", { - wikiPageName: @scope.wiki.slug - projectName: unslugify(@scope.wiki.slug) + wikiPageName: unslugify(@scope.wiki.slug) + projectName: @scope.project.name }) description = @translate.instant("WIKI.PAGE_DESCRIPTION", { wikiPageContent: angular.element(@scope.wiki.html or "").text() From 2b9022e663a1417a557adf8e5d3eab851307bcff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 20 Jun 2015 22:22:30 +0200 Subject: [PATCH 008/403] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ef083cc..cd48e5d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog # +## 1.9.0 ??? (unreleased) +### Features +- ... + +### Misc +- Lots of small and not so small bugfixes. + + ## 1.8.0 Saracenia Purpurea (2015-06-18) ### Features From f2e3b6528cd2a66e42dfc26a50c075b3e3e53686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 20 Jun 2015 22:27:58 +0200 Subject: [PATCH 009/403] [i18n] Update locales --- app/locales/locale-de.json | 126 ++++++++++++++++++------------------- app/locales/locale-fr.json | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 302ebdb1..5d8a7417 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -20,11 +20,11 @@ "BLOCK": "Blockieren", "UNBLOCK": "Blockierung aufheben", "BLOCKED": "Blockiert", - "CREATED_BY": "Erstellt von {{fullDisplayName}}", + "CREATED_BY": "Erstellt durch {{fullDisplayName}}", "FROM": "von", "TO": "zu", "CLOSE": "schließen", - "BLOCKED_NOTE": "Warum ist diese User-Story gesperrt?", + "BLOCKED_NOTE": "Was blockiert diese User-Story?", "BLOCKED_REASON": "Bitte erklären Sie den Grund ", "GO_HOME": "Führe mich heim", "PLUGINS": "Plugins", @@ -34,7 +34,7 @@ "RELATED_TASKS": "Verbundene Aufgaben", "LOGOUT": "Ausloggen", "EXTERNAL_USER": "ein externer Benutzer", - "GENERIC_ERROR": "Eins unserer Heinzelmännchen sagt {{error}}.", + "GENERIC_ERROR": "Eins unserer Helferlein sagt {{error}}.", "IOCAINE_TEXT": "Fühlen Sie sich von einer Aufgabe etwas erdrückt? Stellen Sie sicher, dass andere davon erfahren, indem Sie auf Locaine klicken, wenn Sie eine Aufgabe ändern. Es ist möglich, gegen dieses (fiktive) tödliche Gift immun zu werden, indem man kleine Mengen über einen Zeitraum hinweg einnimmt. Genauso, wie es möglich ist, besser in dem zu werden, was man tut, indem man gelegentlich zusätzliche Herausforderungen annimmt! ", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Dieser Wert scheint ungültig zu sein. ", @@ -128,8 +128,8 @@ "PRIORITY": "Priorität", "ASSIGNED_TO": "Zugewiesen an", "POINTS": "Punkte", - "BLOCKED_NOTE": "gesperrte Notiz", - "IS_BLOCKED": "ist gesperrt ", + "BLOCKED_NOTE": "Blockierungsgrund", + "IS_BLOCKED": "wird blockiert", "REF": "Ref" }, "ROLES": { @@ -191,7 +191,7 @@ "LINK_SAMPLE_TEXT": "Geben Sie Ihren Linktext ein...", "QUOTE_BLOCK_BUTTON": "Blockzitat", "QUOTE_BLOCK_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", - "CODE_BLOCK_BUTTON": "Code Block", + "CODE_BLOCK_BUTTON": "Kodeblock", "CODE_BLOCK_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", "PREVIEW_BUTTON": "Vorschau", "EDIT_BUTTON": "Bearbeiten", @@ -262,8 +262,8 @@ "PLACEHOLDER_AUTH_PASSWORD": "Passwort (Groß- und Kleinschreibung beachten)" }, "LOGIN_FORM": { - "ERROR_AUTH_INCORRECT": "Laut unseren Heinzelmännchen ist Ihr Benutzername/Ihre E-Mail-Adresse oder Ihr Passwort nicht korrekt. ", - "SUCCESS": "Herzlich willkommen bei Taiga, unsere Heinzelmännchen freuen sich. " + "ERROR_AUTH_INCORRECT": "Laut unseren Helferlein ist Ihr Benutzername/Ihre E-Mail-Adresse oder Ihr Passwort nicht korrekt. ", + "SUCCESS": "Herzlich willkommen bei Taiga, unsere Helferlein freuen sich. " }, "REGISTER": { "PAGE_TITLE": "Registrieren - Taiga", @@ -272,7 +272,7 @@ "REGISTER_FORM": { "TITLE": "Ein neues Taiga Benutzerkonto registrieren (kostenlos)", "PLACEHOLDER_NAME": "Wählen Sie einen Benutzernamen (Groß- und Kleinschreibung beachten)", - "PLACEHOLDER_FULL_NAME": "Wählen Sie Ihren vollständigen Namen ", + "PLACEHOLDER_FULL_NAME": "Wählen Sie Ihren Anzeigenamen", "PLACEHOLDER_EMAIL": "Ihre E-Mail", "PLACEHOLDER_PASSWORD": "Setzen Sie ein Passwort (Groß- und Kleinschreibung beachten)", "ACTION_SIGN_UP": "Anmelden", @@ -290,7 +290,7 @@ "ACTION_RESET_PASSWORD": "Passwort zurücksetzen", "LINK_CANCEL": "Nein, bring mich zurück. Ich denke, ich erinnere mich daran. ", "SUCCESS": "Sehen Sie in Ihren Posteingang!
Wir haben Ihnen eine E-Mail mit einer Anleitung gesendet, um ein neues Passwort festzulegen.", - "ERROR": "Laut unseren Heinzelmännchen sind Sie bislang noch nicht registriert. " + "ERROR": "Laut unseren Helferlein sind Sie bislang noch nicht registriert. " }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Ändern Sie Ihr Passwort - Taiga", @@ -320,9 +320,9 @@ "PAGE_DESCRIPTION": "Nehmen Sie die Einladung an und treten Sie einem Projekt in Taiga bei, einer Projekt-Management Plattform für Neugründer und agile Entwickler und Designer, die ein unkompliziertes und ansprechendes Tool möchten, das die Arbeit wirklich angenehm macht. " }, "INVITATION_LOGIN_FORM": { - "NOT_FOUND": "Huch, wir haben ein Problem
Unsere Heinzelmännchen können Ihre Einladung nicht finden.", + "NOT_FOUND": "Huch, wir haben ein Problem
Unsere Helferlein können Ihre Einladung nicht finden.", "SUCCESS": "Sie sind diesem Projekt erfolgreich beigetreten. Herzlich willkommen bei {{project_name}}", - "ERROR": "Laut unseren Heinzelmännchen sind Sie noch nicht registriert, oder Sie haben ein ungültiges Passwort eingegeben. " + "ERROR": "Laut unseren Helferlein sind Sie noch nicht registriert, oder Sie haben ein ungültiges Passwort eingegeben. " }, "HOME": { "PAGE_TITLE": "Home - Taiga", @@ -388,9 +388,9 @@ "LOADING_MESSAGE": "Bitte lassen Sie diese Seite geöffnet!", "ASYNC_MESSAGE": "Wir werden nach Fertigstellung eine E-Mail senden.", "SYNC_MESSAGE": "Wenn der Download nicht automatisch startet, klicken Sie hier.", - "ERROR": "Unsere Heinzelmännchen haben Probleme, Ihre Export-Datei zu erzeugen. Bitte versuchen Sie es erneut.", - "ERROR_BUSY": "Entschuldigung, unsere Heinzelmännchen sind zur Zeit sehr beschäftigt. Bitte versuchen Sie es in ein paar Minuten erneut. ", - "ERROR_MESSAGE": "Unsere Heinzelmännchen haben Probleme, Ihre Export-Datei zu erstellen: {{message}} " + "ERROR": "Unsere Helferlein haben Probleme, Ihre Export-Datei zu erzeugen. Bitte versuchen Sie es erneut.", + "ERROR_BUSY": "Entschuldigung, unsere Helferlein sind zur Zeit sehr beschäftigt. Bitte versuchen Sie es in ein paar Minuten erneut. ", + "ERROR_MESSAGE": "Unsere Helferlein haben Probleme, Ihre Export-Datei zu erstellen: {{message}} " }, "MODULES": { "TITLE": "Module", @@ -637,7 +637,7 @@ "CONTACTS_EMPTY": "{{username}} hat noch keine Kontakte", "CURRENT_USER_CONTACTS_EMPTY": "Sie haben noch keine Kontakte ", "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "Die Leute, mit denen Sie auf Taiga zusammenarbeiten, werden automatisch zu Ihren Kontakten ", - "PROJECTS_EMPTY": "{{username}} hat noch keine Projekte" + "PROJECTS_EMPTY": "{{username}} besitzt noch keine Projekte" }, "PROFILE_SIDEBAR": { "TITLE": "Ihr Profil", @@ -703,13 +703,13 @@ "TITLE": "Projekt importieren", "UPLOADING_FILE": "Exportdatei wird hochgeladen", "DESCRIPTION": "Dieser Vorgang kann etwas dauern. Bitte schliessen Sie das Fenster nicht!", - "ASYNC_IN_PROGRESS_TITLE": "Unsere Heinzelmännchen importieren Ihr Projekt", + "ASYNC_IN_PROGRESS_TITLE": "Unsere Helferlein importieren Ihr Projekt", "ASYNC_IN_PROGRESS_MESSAGE": "Dieser Vorgang könnte ein paar Minuten benötigen
Nach Fertigstellung benachrichtigen wir Sie per E-Mail.", "UPLOAD_IN_PROGRESS_MESSAGE": "Hochgeladen {{uploadedSize}} von {{totalSize}}", - "ERROR": "Unsere Heinzelmännchen haben Probleme beim Importieren Ihrer Daten. Bitte versuchen Sie es erneut. ", - "ERROR_TOO_MANY_REQUEST": "Entschuldigung, unsere Heinzelmännchen sind derzeit sehr beschäftigt. Bitte versuchen Sie es in ein paar Minuten erneut. ", - "ERROR_MESSAGE": "Unsere Heinzelmännchen haben Probleme beim Importieren Ihrer Datei: {{error_message}}", - "ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) ist zu schwierig für unsere Heinzelmännchen, versuchen Sie es bitte mit einer kleineren Datei als({{maxFileSize}})", + "ERROR": "Unsere Helferlein haben Probleme beim Importieren Ihrer Daten. Bitte versuchen Sie es erneut. ", + "ERROR_TOO_MANY_REQUEST": "Entschuldigung, unsere Helferlein sind derzeit sehr beschäftigt. Bitte versuchen Sie es in ein paar Minuten erneut. ", + "ERROR_MESSAGE": "Unsere Helferlein haben Probleme beim Importieren Ihrer Datei: {{error_message}}", + "ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) ist zu schwierig für unsere Helferlein, versuchen Sie es bitte mit einer kleineren Datei als ({{maxFileSize}})", "SYNC_SUCCESS": "Ihr Projekt wurde erfolgreich importiert" } }, @@ -790,7 +790,7 @@ "TITLE_LINK_GO_TO_ISSUE": "Zum Ticket wechseln", "EXTERNAL_REFERENCE": "Dies User-Story wurde angelegt von", "GO_TO_EXTERNAL_REFERENCE": "Zur Quelle wechseln", - "BLOCKED": "Diese User-Story ist blockiert", + "BLOCKED": "Diese User-Story wird blockiert", "PREVIOUS": "Vorherige User-Story", "NEXT": "nächste User-Story", "TITLE_DELETE_ACTION": "User-Story löschen", @@ -849,8 +849,8 @@ "MILESTONE": "Sprint", "USER_STORY": "User-Story ", "PROJECT": "Projekt", - "IS_BLOCKED": "ist gesperrt ", - "BLOCKED_NOTE": "gesperrte Notiz", + "IS_BLOCKED": "wird blockiert", + "BLOCKED_NOTE": "Blockierungsgrund", "POINTS": "Punkte", "CLIENT_REQUIREMENT": "Kunden Anforderung ", "TEAM_REQUIREMENT": "Team Anforderung ", @@ -939,13 +939,13 @@ } }, "ERROR": { - "TEXT1": "Es gibt ein Problem und unsere Heinzelmännchen arbeiten schon daran!", + "TEXT1": "Es gibt ein Problem und unsere Helferlein arbeiten schon daran!", "TEXT2": "Versuchen Sie in Kürze neu zu laden. ", "NOT_FOUND": "Nicht gefunden", "NOT_FOUND_TEXT": "Fehler 404. Die angeforderte Seite existiert nicht mehr. Möglicherweise finden Sie das Gesuchte, wenn Sie zur TAIGA Homepage zurückkehren. ", "PERMISSION_DENIED": "Berechtigung verweigert", "PERMISSION_DENIED_CODE": "Fehler 403.", - "VERSION_ERROR": "Jemand anderes hat dies schon geändert und unsere Heinzelmännchen können Ihre Änderungen deshalb nicht übernehmen. Bitte laden Sie die Seite neu und machen Sie die Änderungen erneut (die aktuelle Eingabe geht dabei verloren)." + "VERSION_ERROR": "Jemand anderes hat dies schon geändert und unsere Helferlein können Ihre Änderungen deshalb nicht übernehmen. Bitte laden Sie die Seite neu und machen Sie die Änderungen erneut (die aktuelle Eingabe geht dabei verloren)." }, "TASKBOARD": { "PAGE_TITLE": "{{sprintName}} - Sprint Taskboard - {{projectName}}", @@ -982,13 +982,13 @@ "TITLE_SELECT_STATUS": "Status Bezeichnung", "OWNER_US": "Diese Aufgabe gehört zu ", "TITLE_LINK_GO_OWNER": "Zur User-Story wechseln", - "ORIGIN_US": "Diese Aufgabe wurde erstellt von ", + "ORIGIN_US": "Diese Aufgabe wurde erstellt durch ", "TITLE_LINK_GO_ORIGIN": "Zu User-Story wechseln", - "BLOCKED": "Diese Aufgabe ist gesperrt", + "BLOCKED": "Diese Aufgabe wird blockiert", "PREVIOUS": "vorherige Aufgabe", "NEXT": "nächste Aufgabe", "TITLE_DELETE_ACTION": "Aufgabe löschen", - "LIGHTBOX_TITLE_BLOKING_TASK": "Gesperrte Aufgabe", + "LIGHTBOX_TITLE_BLOKING_TASK": "Blockierende Aufgabe", "FIELDS": { "MILESTONE": "Sprint", "USER_STORY": "User-Story", @@ -1000,8 +1000,8 @@ "NOTIFICATION": { "OK": "Alles in Ordnung", "WARNING": "Huch, es gibt ein Problem...", - "WARNING_TEXT": "Unsere Heinzelmännchen bedauern, Ihre Änderungen wurden nicht gespeichert! ", - "SAVED": "Die Heinzelmännchen haben Ihre Änderungen gespeichert!", + "WARNING_TEXT": "Unsere Helferlein bedauern, Ihre Änderungen wurden nicht gespeichert! ", + "SAVED": "Die Helferlein haben Ihre Änderungen gespeichert!", "CLOSE": "Benachrichtigung schließen", "MAIL": "Benachrichtigungen per Mail", "ASK_DELETE": "Möchten Sie wirklich löschen?" @@ -1011,14 +1011,14 @@ "SUBTITLE": "Wir bedauern, dass Sie die Taiga verlassen. Wir hoffen, Sie hatten einen angenehmen Aufenthalt. :)", "PLACEHOLDER_INPUT_TOKEN": "Benutzerkonto Token ungültig machen", "ACTION_LEAVING": "Ja, ich gehe! ", - "SUCCESS": "Unsere Heinzelmännchen haben Ihr Benutzerkonto entfernt. " + "SUCCESS": "Unsere Helferlein haben Ihr Benutzerkonto entfernt. " }, "CHANGE_EMAIL_FORM": { "TITLE": "Ändern Sie Ihre E-Mail", "SUBTITLE": "Noch ein Klick und Ihre E-Mail wird aktualisiert! ", "PLACEHOLDER_INPUT_TOKEN": "E-Mail-Token ändern", "ACTION_CHANGE_EMAIL": "E-Mail ändern", - "SUCCESS": "Unsere Heinzelmännchen haben Ihre E-Mail-Adresse aktualisiert" + "SUCCESS": "Unsere Helferlein haben Ihre E-Mail-Adresse aktualisiert" }, "ISSUES": { "PAGE_TITLE": "Tickets - {{projectName}}", @@ -1029,13 +1029,13 @@ "ACTION_PROMOTE_TO_US": "Zur User-Story aufwerten", "PLACEHOLDER_FILTER_NAME": "Benennen Sie den Filter und drücken Sie die Eingabetaste", "PROMOTED": "Dieses Ticket wurde aufgewertet zu User-Story:", - "EXTERNAL_REFERENCE": "Dieses Ticket wurde erstellt von ", + "EXTERNAL_REFERENCE": "Dieses Ticket wurde erstellt durch ", "GO_TO_EXTERNAL_REFERENCE": "Zur Quelle wechseln", - "BLOCKED": "Dieses Ticket ist gesperrt", + "BLOCKED": "Dieses Ticket wird blockiert", "TITLE_PREVIOUS_ISSUE": "vorheriges Ticket ", "TITLE_NEXT_ISSUE": "nächstes Ticket", "ACTION_DELETE": "Ticket löschen", - "LIGHTBOX_TITLE_BLOKING_ISSUE": "Ticket sperren", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Blockierendes Ticket", "FIELDS": { "PRIORITY": "Priorität", "SEVERITY": "Gewichtung", @@ -1059,7 +1059,7 @@ "PRIORITIES": "Prioritäten", "TAGS": "Schlagwörter", "ASSIGNED_TO": "Zugeordnet", - "CREATED_BY": "Erstellt von", + "CREATED_BY": "Erstellt durch", "CUSTOM_FILTERS": "Benutzerfilter" }, "CONFIRM_DELETE": { @@ -1123,7 +1123,7 @@ "PAGE_DESCRIPTION": "Das Team Panel, um alle Mitglieder des Projekts anzuzeigen {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Team", "APP_TITLE": "TEAM - {{projectName}}", - "PLACEHOLDER_INPUT_SEARCH": "Unter vollständigem Namen suchen...", + "PLACEHOLDER_INPUT_SEARCH": "Unter Anzeigenamen suchen...", "COLUMN_MR_WOLF": "Herr Wolf", "EXPLANATION_COLUMN_MR_WOLF": "Geschlossene Tickets", "COLUMN_IOCAINE": "Locaine Trinker ", @@ -1169,7 +1169,7 @@ }, "USER_PROFILE": { "IMAGE_HELP": "Das Bild wird auf 80x80px skaliert.
", - "ACTION_CHANGE_IMAGE": "Änderung", + "ACTION_CHANGE_IMAGE": "Ändern", "ACTION_USE_GRAVATAR": "Gravatar verwenden", "ACTION_DELETE_ACCOUNT": "Taiga Benutzerkonto löschen", "CHANGE_EMAIL_SUCCESS": "Sehen Sie in Ihren Posteingang!
Wir haben eine E-Mail an Ihr Konto gesendet
mit der Anleitung, wie Sie Ihre neue Adresse anlegen", @@ -1177,8 +1177,8 @@ "FIELD": { "USERNAME": "Benutzername", "EMAIL": "E-Mail", - "FULL_NAME": "Vollständiger Name", - "PLACEHOLDER_FULL_NAME": "Geben Sie Ihren vollständigen Namen an (ex. Íñigo Montoya)", + "FULL_NAME": "Anzeigename", + "PLACEHOLDER_FULL_NAME": "Geben Sie Ihren Anzeigenamen an (z.B. Vorname Nachname)", "BIO": "Bio (max. 210 Zeichen)", "PLACEHOLDER_BIO": "Erzählen Sie etwas über sich", "LANGUAGE": "Sprache", @@ -1195,7 +1195,7 @@ }, "WIKI": { "PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}", - "PAGE_DESCRIPTION": "Letzte Änderung am {{lastModifiedDate}} ({{totalEditions}} Gesamtzahl der Änderungen) Inhalt: {{ wikiPageContent }}", + "PAGE_DESCRIPTION": "Letzte Bearbeitung am {{lastModifiedDate}} ({{totalEditions}} Gesamtzahl der Bearbeitungen) Inhalt: {{ wikiPageContent }}", "DATETIME": "DD MMM YYYY HH:mm", "PLACEHOLDER_PAGE": "Schreiben Sie Ihre Wiki Seite ", "REMOVE": "Diese Wiki Seite entfernen", @@ -1206,7 +1206,7 @@ }, "SUMMARY": { "TIMES_EDITED": "Zeiten
bearbeitet", - "LAST_EDIT": "letzte
Änderung", + "LAST_EDIT": "letzte
Bearbeitung", "LAST_MODIFICATION": "letzte Änderung" } }, @@ -1224,28 +1224,28 @@ "HINT4_TEXT": "Machen Sie sich keine Sorgen, im Dashboard finden Sie Aufgaben, Tickets und User-Stories in der Reihenfolge in der Sie diese bearbeitet haben." }, "TIMELINE": { - "UPLOAD_ATTACHMENT": "{{username}} hat einen neuen Anhang hochgeladen in {{obj_name}}", - "US_CREATED": "{{username}} hat eine neue user-story erstellt {{obj_name}} in {{project_name}}", - "ISSUE_CREATED": "{{username}} hat ein neues ticket erstellt {{obj_name}} in {{project_name}} ", - "TASK_CREATED": "{{username}} hat eine neue aufgabe erstellt {{obj_name}} in {{project_name}}", - "TASK_CREATED_WITH_US": "{{username}} hat eine neue Aufgabe erstellt {{obj_name}} in {{project_name}} die zur User-Story {{us_name}} gehört", - "WIKI_CREATED": "{{username}} hat eine neue Wiki Seite erstellt {{obj_name}} in {{project_name}}", - "MILESTONE_CREATED": "{{username}} hat einen neuen sprint erstellt {{obj_name}} in {{project_name}}", + "UPLOAD_ATTACHMENT": "{{username}} fügte {{obj_name}} einen neuen Anhang zu", + "US_CREATED": "{{username}} erstellte die neue User-Story {{obj_name}} in {{project_name}}", + "ISSUE_CREATED": "{{username}} erstellte das neue Ticket {{obj_name}} in {{project_name}} ", + "TASK_CREATED": "{{username}} erstellte die neue Aufgabe {{obj_name}} in {{project_name}}", + "TASK_CREATED_WITH_US": "{{username}} erstellte die neue Aufgabe {{obj_name}} in {{project_name}}, die zur User-Story {{us_name}} gehört", + "WIKI_CREATED": "{{username}} erstellte die neue Wiki Seite {{obj_name}} in {{project_name}}", + "MILESTONE_CREATED": "{{username}} erstellte den neuen Sprint {{obj_name}} in {{project_name}}", "NEW_PROJECT": "{{username}} erstellte das Projekt {{project_name}}", - "MILESTONE_UPDATED": "{{username}} hat den sprint aktualisiert {{obj_name}}", - "US_UPDATED": "{{username}} hat das Attribut aktualisiert \"{{field_name}}\" von User-Story {{obj_name}}", - "ISSUE_UPDATED": "{{username}} hat das attribut aktualisiert \"{{field_name}}\" von ticket {{obj_name}}", - "TASK_UPDATED": "{{username}} hat das attribut aktualisiert \"{{field_name}}\" von aufgabe {{obj_name}}", - "TASK_UPDATED_WITH_US": "{{username}} hat das attribut aktualisiert \"{{field_name}}\" von aufgabe {{obj_name}} die zur user-story {{us_name}} gehört", - "WIKI_UPDATED": "{{username}} hat die wiki seite aktualisiert {{obj_name}}\n", - "NEW_COMMENT_US": "{{username}} hat in User-Story {{obj_name}} kommentiert", - "NEW_COMMENT_ISSUE": "{{username}} hat im Ticket kommentiert {{obj_name}}", - "NEW_COMMENT_TASK": "{{username}} hat in der Aufgabe kommentiert {{obj_name}}", + "MILESTONE_UPDATED": "{{username}} aktualisierte den Sprint {{obj_name}}", + "US_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}}", + "ISSUE_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}}", + "TASK_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}}", + "TASK_UPDATED_WITH_US": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} von User-Story {{us_name}}", + "WIKI_UPDATED": "{{username}} aktualisierte die WIKI Seite {{obj_name}}", + "NEW_COMMENT_US": "{{username}} schrieb einen Kommentar in der User-Story {{obj_name}}", + "NEW_COMMENT_ISSUE": "{{username}} schrieb einen Kommentar im Ticket {{obj_name}}", + "NEW_COMMENT_TASK": "{{username}} schrieb einen Kommentar in der Aufgabe {{obj_name}}", "NEW_MEMBER": "{{project_name}} hat ein neues Mitglied", - "US_ADDED_MILESTONE": "{{username}} hat die User-Story {{obj_name}} zu {{sprint_name}} hinzugefügt", - "US_REMOVED_FROM_MILESTONE": "{{username}} hat die User-Story {{obj_name}} zur Auftragsliste hinzugefügt ", - "BLOCKED": "{{username}} hat gesperrt {{obj_name}}", - "UNBLOCKED": "{{username}} hat entsperrt {{obj_name}}", + "US_ADDED_MILESTONE": "{{username}} fügte dem Sprint {{sprint_name}} die User-Story {{obj_name}} hinzu", + "US_REMOVED_FROM_MILESTONE": "{{username}} fügte der Auftragsliste die User-Story {{obj_name}} hinzu", + "BLOCKED": "{{username}} vermerkte die Blockierung von {{obj_name}}", + "UNBLOCKED": "{{username}} hob die Blockierung von {{obj_name}} auf", "NEW_USER": "{{username}} ist Taiga beigetreten" } } \ No newline at end of file diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 379ce57e..0a965d76 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Modifier votre mot de passe - Taiga", - "PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Paramètrez un nouveau mot de passe pour votre compte Taiga et, au fait, vous devriez manger de la nourriture plus riche en fer, c'est bon pour votre cerveau :P", "SECTION_NAME": "Modifier le mot de passe", "FIELD_CURRENT_PASSWORD": "Mot de passe courant", "PLACEHOLDER_CURRENT_PASSWORD": "Votre mot de passe courant (ne rien saisir si vous ne possédez pas encore de mot de passe)", From f834bf681e9fbcdc20894ce706bc05f06563a997 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 22 Jun 2015 08:31:51 +0200 Subject: [PATCH 010/403] remove view project permission when the user has not other permissions --- app/coffee/modules/admin/roles.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/coffee/modules/admin/roles.coffee b/app/coffee/modules/admin/roles.coffee index c678d775..b965e559 100644 --- a/app/coffee/modules/admin/roles.coffee +++ b/app/coffee/modules/admin/roles.coffee @@ -410,7 +410,10 @@ RolePermissionsDirective = ($rootscope, $repo, $confirm, $compile) -> activePermissions = _.sortBy(_.map(activePermissions, (t) -> permission = angular.element(t).parents(".category-item").data("id") )) - activePermissions.push("view_project") + + if activePermissions.length + activePermissions.push("view_project") + return activePermissions target = angular.element(event.currentTarget) From b970bfd4fec0c8986948f7422c9e095697ceb799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 16 Jun 2015 11:01:45 +0200 Subject: [PATCH 011/403] Removed min-width and improved selector efficiency --- app/modules/home/home.scss | 1 - app/modules/projects/project/project.jade | 2 +- app/styles/core/base.scss | 4 +++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/modules/home/home.scss b/app/modules/home/home.scss index 769c74ca..e605acea 100644 --- a/app/modules/home/home.scss +++ b/app/modules/home/home.scss @@ -1,6 +1,5 @@ .home-wrapper { display: flex; - padding-top: 2rem; .duty-summary { flex: 1; margin-right: 2rem; diff --git a/app/modules/projects/project/project.jade b/app/modules/projects/project/project.jade index e99fb1ec..9cf43a78 100644 --- a/app/modules/projects/project/project.jade +++ b/app/modules/projects/project/project.jade @@ -1,6 +1,6 @@ div.wrapper tg-project-menu - div.main.centered.single-project + div.centered.single-project section.single-project-intro h1 span.green(class="project-name") {{::vm.project.get("name")}} diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index 607251a4..fb8a0bd9 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -45,6 +45,7 @@ body { } .centered { + @extend %main; margin: 0 auto; max-width: 1200px; min-width: 960px; @@ -94,9 +95,10 @@ body { background: $whitish; } +%main, .main { flex: 4; - min-width: 600px; + flex-basis: 600px; padding: 1rem 2rem; } From a677048bd38bc52001e7c95af892ef6726ab0cc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Thu, 18 Jun 2015 09:52:07 +0200 Subject: [PATCH 012/403] Fix conflicts and IE11 --- app/styles/core/base.scss | 1 - app/styles/modules/home-project.scss | 39 +--------------------------- 2 files changed, 1 insertion(+), 39 deletions(-) diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index fb8a0bd9..3244ad0c 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -46,7 +46,6 @@ body { .centered { @extend %main; - margin: 0 auto; max-width: 1200px; min-width: 960px; width: 90%; diff --git a/app/styles/modules/home-project.scss b/app/styles/modules/home-project.scss index 3300ee9d..233e2170 100644 --- a/app/styles/modules/home-project.scss +++ b/app/styles/modules/home-project.scss @@ -37,7 +37,7 @@ flex: 1; flex-shrink: 3; margin-right: 1rem; - max-width: 800px; + max-width: 960px; width: 0; } .involved-data { @@ -63,40 +63,3 @@ } } } - - -//.summary-stats { -// align-items: flex-start; -// display: flex; -// .info-num { -// @extend %xlarge; -// @extend %bold; -// float: left; -// margin-right: .3rem; -// position: relative; -// top: 5px; -// } -// .info-text { -// @extend %small; -// float: left; -// line-height: .9rem; -// } -//} -// -//.project-data-container { -// display: flex; -// justify-content: space-between; -// ul { -// flex-grow: 0; -// max-width: 33%; -// } -// li { -// display: inline-block; -// margin-right: .1rem; -// width: 10%; -// figure { -// width: 100%; -// } -// } -//} -// From ed7f3599c2877064620160698386cc42bb686ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Thu, 18 Jun 2015 10:26:02 +0200 Subject: [PATCH 013/403] Fix centered in IE11 --- app/styles/core/base.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index 3244ad0c..aa891e32 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -45,7 +45,7 @@ body { } .centered { - @extend %main; + margin: 1rem auto; max-width: 1200px; min-width: 960px; width: 90%; From 7755f8292265fe1435e302989875bd30da2d5944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 16 Jun 2015 11:01:45 +0200 Subject: [PATCH 014/403] Removed min-width and improved selector efficiency --- app/styles/core/base.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index aa891e32..fb8a0bd9 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -45,7 +45,8 @@ body { } .centered { - margin: 1rem auto; + @extend %main; + margin: 0 auto; max-width: 1200px; min-width: 960px; width: 90%; From 06be7d0153bb8a6935e44cc65824590596f08ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Thu, 18 Jun 2015 09:52:07 +0200 Subject: [PATCH 015/403] Fix conflicts and IE11 --- app/styles/core/base.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index fb8a0bd9..3244ad0c 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -46,7 +46,6 @@ body { .centered { @extend %main; - margin: 0 auto; max-width: 1200px; min-width: 960px; width: 90%; From a7909ab39272f2b27c6199c60305dd5d439b0a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Thu, 18 Jun 2015 10:26:02 +0200 Subject: [PATCH 016/403] Fix centered in IE11 --- app/styles/core/base.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index 3244ad0c..aa891e32 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -45,7 +45,7 @@ body { } .centered { - @extend %main; + margin: 1rem auto; max-width: 1200px; min-width: 960px; width: 90%; From 30f24fc08412b87497ee7e681d89f2800ebc272f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 23 Jun 2015 09:05:45 +0200 Subject: [PATCH 017/403] Remove beta ribbon and fix it in unlogged pages --- app/modules/home/home.jade | 1 - app/modules/profile/profile.jade | 1 - app/styles/components/beta.scss | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/app/modules/home/home.jade b/app/modules/home/home.jade index eb815985..d1af66bd 100644 --- a/app/modules/home/home.jade +++ b/app/modules/home/home.jade @@ -1,6 +1,5 @@ doctype html -include ../../partials/includes/components/beta div.home-wrapper.centered div.duty-summary div(tg-working-on) diff --git a/app/modules/profile/profile.jade b/app/modules/profile/profile.jade index 5f0099d6..18058610 100644 --- a/app/modules/profile/profile.jade +++ b/app/modules/profile/profile.jade @@ -1,4 +1,3 @@ -include ../../partials/includes/components/beta div.profile.centered(ng-if="vm.user") div(tg-profile-bar, user="vm.user", isCurrentUser="vm.isCurrentUser") div.main diff --git a/app/styles/components/beta.scss b/app/styles/components/beta.scss index 6856d586..4e720fdf 100644 --- a/app/styles/components/beta.scss +++ b/app/styles/components/beta.scss @@ -1,6 +1,6 @@ .beta { left: 0; position: absolute; - top: 0; + top: -40px; z-index: 9999; } From d7deb7ade33a499c2f9941ddab081559c224335c Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 22 Jun 2015 14:59:21 +0200 Subject: [PATCH 018/403] repeat by div instead of form in the admin lists --- .../admin/admin-custom-attributes.jade | 56 +++++++------- .../modules/admin/project-points.jade | 39 +++++----- .../modules/admin/project-status.jade | 53 ++++++------- .../includes/modules/admin/project-types.jade | 41 +++++----- .../modules/admin/project-us-status.jade | 75 ++++++++++--------- 5 files changed, 133 insertions(+), 131 deletions(-) diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade index 94b35d80..4a05b853 100644 --- a/app/partials/includes/modules/admin/admin-custom-attributes.jade +++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade @@ -16,35 +16,35 @@ section.custom-fields-table.basic-table div.table-body div.js-sortable - form.js-form(ng-repeat="attr in customAttributes track by attr.id", tg-bind-scope) - div.row.single-custom-field.js-view-custom-field - span.icon.icon-drag-v - div.custom-name - span {{ attr.name }} - div.custom-description - span {{ attr.description }} - div.custom-field-type - span(translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_{{ attr.field_type }}") - div.custom-options - div.custom-options-wrapper - a.js-edit-custom-field-button.icon.icon-edit(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.EDIT' | translate}}") - a.js-delete-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.DELETE' | translate}}") + div(ng-repeat="attr in customAttributes track by attr.id", tg-bind-scope) + form.js-form(tg-bind-scope) + div.row.single-custom-field.js-view-custom-field + span.icon.icon-drag-v + div.custom-name + span {{ attr.name }} + div.custom-description + span {{ attr.description }} + div.custom-field-type + span(translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_{{ attr.field_type }}") + div.custom-options + div.custom-options-wrapper + a.js-edit-custom-field-button.icon.icon-edit(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.EDIT' | translate}}") + a.js-delete-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.DELETE' | translate}}") - div.row.single-custom-field.js-edit-custom-field.hidden - fieldset.custom-name - input(type="text", name="name", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}", - ng-model="attr.name", data-required="true" data-maxlength="64") - fieldset.custom-description - input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}", - ng-model="attr.description") - fieldset.custom-field-type - select(ng-model="attr.field_type", - ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") - - fieldset.custom-options - div.custom-options-wrapper - a.js-update-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_UPDATE' | translate}}") - a.js-cancel-edit-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_CANCEL_EDITION' | translate}}") + div.row.single-custom-field.js-edit-custom-field.hidden + fieldset.custom-name + input(type="text", name="name", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}", + ng-model="attr.name", data-required="true" data-maxlength="64") + fieldset.custom-description + input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}", + ng-model="attr.description") + fieldset.custom-field-type + select(ng-model="attr.field_type", + ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") + fieldset.custom-options + div.custom-options-wrapper + a.js-update-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_UPDATE' | translate}}") + a.js-cancel-edit-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_CANCEL_EDITION' | translate}}") form.row.single-custom-field.js-new-custom-field.hidden fieldset.custom-name diff --git a/app/partials/includes/modules/admin/project-points.jade b/app/partials/includes/modules/admin/project-points.jade index ce42b043..bb991265 100644 --- a/app/partials/includes/modules/admin/project-points.jade +++ b/app/partials/includes/modules/admin/project-points.jade @@ -15,32 +15,31 @@ section.project-values-table div.project-values-body div.sortable - form(ng-repeat="value in values", tg-bind-scope) - div.project-values-row.row.table-main.visualization - span.icon.icon-drag-v + div(ng-repeat="value in values track by value.id", tg-bind-scope) + form(tg-bind-scope) + div.project-values-row.row.table-main.visualization + span.icon.icon-drag-v - div.project-values-name - span {{ value.name }} + div.project-values-name + span {{ value.name }} - div.project-values-value - span {{ value.value }} + div.project-values-value + span {{ value.value }} - div.project-values-settings - a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.POINTS.TITLE_ACTION_EDIT_VALUE' | translate}}") - a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.POINTS.TITLE_ACTION_DELETE_VALUE' | translate}}") + div.project-values-settings + a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.POINTS.TITLE_ACTION_EDIT_VALUE' | translate}}") + a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.POINTS.TITLE_ACTION_DELETE_VALUE' | translate}}") - div.project-values-row.row.table-main.edition.hidden - div.project-values-name - input(name="name", type="text", placeholder="{{'COMMON.FIELDS.NAME' | translate}}", ng-model="value.name", - data-required="true") + div.project-values-row.row.table-main.edition.hidden + div.project-values-name + input(name="name", type="text", placeholder="{{'COMMON.FIELDS.NAME' | translate}}", ng-model="value.name") - div.project-values-value - input(name="value", type="text", placeholder="{{'COMMON.FIELDS.VALUE' | translate}}", ng-model="value.value", - data-type="number") + div.project-values-value + input(name="value", type="text", placeholder="{{'COMMON.FIELDS.VALUE' | translate}}", ng-model="value.value", data-type="number") - div.project-values-settings - a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") - a.cancel.icon.icon-delete(href="", title="{{'COMON.CANCEL' | translate}}") + div.project-values-settings + a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") + a.cancel.icon.icon-delete(href="", title="{{'COMON.CANCEL' | translate}}") form div.project-values-row.new-value.hidden diff --git a/app/partials/includes/modules/admin/project-status.jade b/app/partials/includes/modules/admin/project-status.jade index 087ddc65..40c5c799 100644 --- a/app/partials/includes/modules/admin/project-status.jade +++ b/app/partials/includes/modules/admin/project-status.jade @@ -14,40 +14,41 @@ section.colors-table.admin-status-table div.table-main div.sortable - form(ng-repeat="value in values", tg-bind-scope) - div.row.table-main.visualization - span.icon.icon-drag-v - div.color-column - div.current-color(ng-style="{background: value.color}") + div(ng-repeat="value in values", tg-bind-scope) + form(tg-bind-scope) + div.row.table-main.visualization + span.icon.icon-drag-v + div.color-column + div.current-color(ng-style="{background: value.color}") - div.status-name - span {{ value.name }} + div.status-name + span {{ value.name }} - div.status-slug - span {{ value.slug }} + div.status-slug + span {{ value.slug }} - div.is-closed-column - div.icon.icon-check-square(ng-show="value.is_closed") + div.is-closed-column + div.icon.icon-check-square(ng-show="value.is_closed") - div.options-column - a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") - a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") + div.options-column + a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") + a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") - div.row.table-main.edition.hidden - div.color-column(tg-color-selection, ng-model="value") - div.current-color(ng-style="{background: value.color}") - include ../../components/select-color + div.row.table-main.edition.hidden + div.color-column(tg-color-selection, ng-model="value") + div.current-color(ng-style="{background: value.color}") + include ../../components/select-color - div.status-name - input(name="name", type="text", placeholder="{{'ADMIN.STATUS.PLACEHOLDER_WRITE_STATUS_NAME' | translate}}", - ng-model="value.name", data-required="true", data-maxlength="255") + div.status-name + input(name="name", type="text", placeholder="{{'ADMIN.STATUS.PLACEHOLDER_WRITE_STATUS_NAME' | translate}}", + ng-model="value.name", data-required="true", data-maxlength="255") - div.is-closed-column - select(name="is_closed", ng-model="value.is_closed", data-required="true", - ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") + div.is-closed-column + select(name="is_closed", ng-model="value.is_closed", data-required="true", + ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") - div.options-column - a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") + div.options-column + a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") a.cancel.icon.icon-delete(href="", title="{{'COMMON.CANCEL' | translate}}") form diff --git a/app/partials/includes/modules/admin/project-types.jade b/app/partials/includes/modules/admin/project-types.jade index 9d5b1f00..cd69b129 100644 --- a/app/partials/includes/modules/admin/project-types.jade +++ b/app/partials/includes/modules/admin/project-types.jade @@ -13,32 +13,33 @@ section.colors-table div.table-main div.sortable - form(ng-repeat="value in values", tg-bind-scope) - div.row.table-main.visualization - span.icon.icon-drag-v + div(ng-repeat="value in values", tg-bind-scope) + form(tg-bind-scope) + div.row.table-main.visualization + span.icon.icon-drag-v - div.color-column - div.current-color(ng-style="{background: value.color}") + div.color-column + div.current-color(ng-style="{background: value.color}") - div.status-name - span {{ value.name }} + div.status-name + span {{ value.name }} - div.options-column - a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") - a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") + div.options-column + a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") + a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") - div.row.table-main.edition.hidden - div.color-column(tg-color-selection, ng-model="value") - div.current-color(ng-style="{background: value.color}") - include ../../components/select-color + div.row.table-main.edition.hidden + div.color-column(tg-color-selection, ng-model="value") + div.current-color(ng-style="{background: value.color}") + include ../../components/select-color - div.status-name - input(name="name", type="text", placeholder="{{'ADMIN.TYPES.PLACEHOLDER_WRITE_NAME' | translate}}", - ng-model="value.name", data-required="true", data-maxlength="255") + div.status-name + input(name="name", type="text", placeholder="{{'ADMIN.TYPES.PLACEHOLDER_WRITE_NAME' | translate}}", + ng-model="value.name", data-required="true", data-maxlength="255") - div.options-column - a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") - a.cancel.icon.icon-delete(href="", title="{{'COMMON.CANCEL' | translate}}") + div.options-column + a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") + a.cancel.icon.icon-delete(href="", title="{{'COMMON.CANCEL' | translate}}") form div.row.table-main.new-value.hidden diff --git a/app/partials/includes/modules/admin/project-us-status.jade b/app/partials/includes/modules/admin/project-us-status.jade index 98eea63f..cf583523 100644 --- a/app/partials/includes/modules/admin/project-us-status.jade +++ b/app/partials/includes/modules/admin/project-us-status.jade @@ -18,57 +18,58 @@ section.project-us-status div.table-main div.sortable - form(ng-repeat="value in values", tg-bind-scope) - div.row.table-main.visualization - span.icon.icon-drag-v + div(ng-repeat="value in values", tg-bind-scope) + form(tg-bind-scope) + div.row.table-main.visualization + span.icon.icon-drag-v - div.color-column - div.current-color(ng-style="{background: value.color}") + div.color-column + div.current-color(ng-style="{background: value.color}") - div.status-name - span {{ value.name }} + div.status-name + span {{ value.name }} - div.status-slug - span {{ value.slug }} + div.status-slug + span {{ value.slug }} - div.is-closed-column - div.icon.icon-check-square(ng-show="value.is_closed") + div.is-closed-column + div.icon.icon-check-square(ng-show="value.is_closed") - div.is-archived-column - div.icon.icon-check-square(ng-show="value.is_archived") + div.is-archived-column + div.icon.icon-check-square(ng-show="value.is_archived") - div.status-wip-limit - span(ng-hide="value.is_archived") {{ value.wip_limit }} + div.status-wip-limit + span(ng-hide="value.is_archived") {{ value.wip_limit }} - div.options-column - a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") - a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") + div.options-column + a.edit-value.icon.icon-edit(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_EDIT_VALUE' | translate}}") + a.delete-value.icon.icon-delete(href="", title="{{'ADMIN.COMMON.TITLE_ACTION_DELETE_VALUE' | translate}}") - div.row.table-main.edition.hidden - div.color-column(tg-color-selection, ng-model="value") - div.current-color(ng-style="{background: value.color}") - include ../../components/select-color + div.row.table-main.edition.hidden + div.color-column(tg-color-selection, ng-model="value") + div.current-color(ng-style="{background: value.color}") + include ../../components/select-color - div.status-name - input(name="name", type="text", placeholder="{{'ADMIN.US_STATUS.PLACEHOLDER_WRITE_NAME' | translate}}", - ng-model="value.name", data-required="true", data-maxlength="255") + div.status-name + input(name="name", type="text", placeholder="{{'ADMIN.US_STATUS.PLACEHOLDER_WRITE_NAME' | translate}}", + ng-model="value.name", data-required="true", data-maxlength="255") - div.is-closed-column - select(name="is_closed", ng-model="value.is_closed", data-required="true", - ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") + div.is-closed-column + select(name="is_closed", ng-model="value.is_closed", data-required="true", + ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") - div.is-archived-column - select(name="is_archived", ng-model="value.is_archived", data-required="true", - ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") + div.is-archived-column + select(name="is_archived", ng-model="value.is_archived", data-required="true", + ng-options="e.id as e.name | translate for e in [{'id':true, 'name':'COMMON.YES'},{'id':false, 'name': 'COMMON.NO'}]") - div.status-wip-limit - input(name="wip_limit", type="number", ng-hide="value.is_archived", - ng-model="value.wip_limit", data-type="digits", - placeholder="{{'ADMIN.US_STATUS.WIP_LIMIT_COLUMN' | translate}}") + div.status-wip-limit + input(name="wip_limit", type="number", ng-hide="value.is_archived", + ng-model="value.wip_limit", data-type="digits", + placeholder="{{'ADMIN.US_STATUS.WIP_LIMIT_COLUMN' | translate}}") - div.options-column - a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") + div.options-column + a.save.icon.icon-floppy(href="", title="{{'COMMON.SAVE' | translate}}") a.cancel.icon.icon-delete(href="", title="{{'COMMON.CANCEL' | translate}}") form From 68c946c4ccf9f7ae590779ea230b856979f6544a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 23 Jun 2015 09:55:44 +0200 Subject: [PATCH 019/403] Detect if points/role selector its at the bottom of the page --- app/coffee/modules/common/estimation.coffee | 4 ++++ app/styles/modules/backlog/backlog-table.scss | 3 +++ 2 files changed, 7 insertions(+) diff --git a/app/coffee/modules/common/estimation.coffee b/app/coffee/modules/common/estimation.coffee index b6ff0f5d..890a2fde 100644 --- a/app/coffee/modules/common/estimation.coffee +++ b/app/coffee/modules/common/estimation.coffee @@ -226,6 +226,10 @@ EstimationsService = ($template, $qqueue, $repo, $confirm, $q) -> @$el.find(".pop-points-open").show() + pop = @$el.find(".pop-points-open") + if pop.offset().top + pop.height() > document.body.clientHeight + pop.addClass('pop-bottom') + create = ($el, us, project) -> $el.unbind("click") diff --git a/app/styles/modules/backlog/backlog-table.scss b/app/styles/modules/backlog/backlog-table.scss index 02d61896..00c47757 100644 --- a/app/styles/modules/backlog/backlog-table.scss +++ b/app/styles/modules/backlog/backlog-table.scss @@ -78,6 +78,9 @@ } .pop-points-open { @include popover(200px, 0, 30px, '', ''); + &.pop-bottom { + @include popover(200px, 'auto', 30px, 0, ''); + } li { display: inline-block; width: 23%; From 6d365c48e4d0aa3f2916d43e1eba2b0f20047b44 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 23 Jun 2015 10:04:57 +0200 Subject: [PATCH 020/403] make currentUserService loadProjects public and add it after project modification --- app/coffee/modules/admin/project-profile.coffee | 5 +++-- app/coffee/modules/projects/lightboxes.coffee | 4 ++-- app/modules/services/current-user.service.coffee | 6 +++--- app/modules/services/current-user.service.spec.coffee | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/app/coffee/modules/admin/project-profile.coffee b/app/coffee/modules/admin/project-profile.coffee index 6cf7d5a9..9c6acc07 100644 --- a/app/coffee/modules/admin/project-profile.coffee +++ b/app/coffee/modules/admin/project-profile.coffee @@ -104,7 +104,7 @@ module.controller("ProjectProfileController", ProjectProfileController) ## Project Profile Directive ############################################################################# -ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, projectService) -> +ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, projectService, currentUserService) -> link = ($scope, $el, $attrs) -> $ctrl = $el.controller() @@ -128,6 +128,7 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje $ctrl.loadInitialData() projectService.fetchProject() + currentUserService.loadProjects() promise.then null, (data) -> $loading.finish(submitButton) @@ -142,7 +143,7 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje return {link:link} module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", - "tgProjectService", ProjectProfileDirective]) + "tgProjectService", "tgCurrentUserService", ProjectProfileDirective]) ############################################################################# diff --git a/app/coffee/modules/projects/lightboxes.coffee b/app/coffee/modules/projects/lightboxes.coffee index 1c4eac5c..b027f58c 100644 --- a/app/coffee/modules/projects/lightboxes.coffee +++ b/app/coffee/modules/projects/lightboxes.coffee @@ -46,7 +46,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project $location.url($projectUrl.get(response)) lightboxService.close($el) - currentUserService._loadProjects() + currentUserService.loadProjects() onErrorSubmit = (response) -> $loading.finish(submitButton) @@ -170,7 +170,7 @@ DeleteProjectDirective = ($repo, $rootscope, $auth, $location, $navUrls, $confir $rootscope.$broadcast("projects:reload") $location.path($navUrls.resolve("home")) $confirm.notify("success") - currentUserService._loadProjects() + currentUserService.loadProjects() # FIXME: error handling? promise.then null, -> diff --git a/app/modules/services/current-user.service.coffee b/app/modules/services/current-user.service.coffee index 924ca587..a4301dae 100644 --- a/app/modules/services/current-user.service.coffee +++ b/app/modules/services/current-user.service.coffee @@ -43,9 +43,9 @@ class CurrentUserService bulkUpdateProjectsOrder: (sortData) -> @projectsService.bulkUpdateProjectsOrder(sortData).then () => - @._loadProjects() + @.loadProjects() - _loadProjects: () -> + loadProjects: () -> return @projectsService.getProjectsByUserId(@._user.get("id")) .then (projects) => @._projects = @._projects.set("all", projects) @@ -56,6 +56,6 @@ class CurrentUserService return @.projects _loadUserInfo: () -> - return @._loadProjects() + return @.loadProjects() angular.module("taigaCommon").service("tgCurrentUserService", CurrentUserService) diff --git a/app/modules/services/current-user.service.spec.coffee b/app/modules/services/current-user.service.spec.coffee index ab8ea8f5..e17e44e9 100644 --- a/app/modules/services/current-user.service.spec.coffee +++ b/app/modules/services/current-user.service.spec.coffee @@ -80,12 +80,12 @@ describe "tgCurrentUserService", -> it "bulkUpdateProjectsOrder and reload projects", (done) -> fakeData = [{id: 1, id: 2}] - currentUserService._loadProjects = sinon.spy() + currentUserService.loadProjects = sinon.spy() mocks.projectsService.bulkUpdateProjectsOrder.withArgs(fakeData).promise().resolve() currentUserService.bulkUpdateProjectsOrder(fakeData).then () -> - expect(currentUserService._loadProjects).to.be.callOnce + expect(currentUserService.loadProjects).to.be.callOnce done() From 4d17ebdc33ccbde521930ff309185c9bb58576b1 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 23 Jun 2015 11:05:06 +0200 Subject: [PATCH 021/403] Fixing custom field selector on creation --- .../includes/modules/admin/admin-custom-attributes.jade | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade index 4a05b853..9d4130b7 100644 --- a/app/partials/includes/modules/admin/admin-custom-attributes.jade +++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade @@ -55,7 +55,8 @@ section.custom-fields-table.basic-table ng-model="newAttr.description") fieldset.custom-field-type select(ng-model="newAttr.field_type", - ng-options="e.id as translate(e.name) for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") + ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") + fieldset.custom-options div.custom-options-wrapper a.js-create-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.SAVE_TITLE' | translate}}") From b8c4141c68ece3dc073d3c2239f425fe3ca56a23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 23 Jun 2015 19:10:32 +0200 Subject: [PATCH 022/403] Update CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd48e5d6..5e1bc71d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,9 @@ ## 1.9.0 ??? (unreleased) + ### Features -- ... +- Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool)) ### Misc - Lots of small and not so small bugfixes. From 7901b873339481cf4b32303c0a75f6fe92e8f583 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 24 Jun 2015 10:02:14 +0200 Subject: [PATCH 023/403] node 0.12.5 package format --- package.json | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index d9a1a4b2..38752212 100644 --- a/package.json +++ b/package.json @@ -10,12 +10,11 @@ "Github" ], "author": "Kaleidos OpenSource SL", - "licenses": [ - { - "type": "AGPL-3.0", - "url": "https://github.com/taigaio/taiga-front/blob/master/LICENSE" - } - ], + "license": "AGPL-3.0", + "repository": { + "type":"git", + "url":"https://github.com/taigaio/taiga-front.git" + }, "scripts": { "scss-lint": "gulp scss-lint --fail", "test": "./node_modules/karma/bin/karma start" From 0dcc6b92a4b6088a1bdaeb821e73130177755316 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 20 Jun 2015 22:15:32 +0200 Subject: [PATCH 024/403] Improve the tooltips of the burndown graph --- app/coffee/modules/backlog/main.coffee | 8 ++++---- app/locales/locale-en.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 845f33a7..bdafb0fd 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -995,16 +995,16 @@ BurndownBacklogGraphDirective = ($translate) -> tooltipOpts: { content: (label, xval, yval, flotItem) -> if flotItem.seriesIndex == 1 - ctx = {xval: xval, yval: yval} + ctx = {sprintName: dataToDraw.milestones[xval].name, value: Math.abs(yval)} return $translate.instant("BACKLOG.CHART.OPTIMAL", ctx) else if flotItem.seriesIndex == 2 - ctx = {xval: xval, yval: yval} + ctx = {sprintName: dataToDraw.milestones[xval].name, value: Math.abs(yval)} return $translate.instant("BACKLOG.CHART.REAL", ctx) else if flotItem.seriesIndex == 3 - ctx = {xval: xval, yval: Math.abs(yval)} + ctx = {sprintName: dataToDraw.milestones[xval].name, value: Math.abs(yval)} return $translate.instant("BACKLOG.CHART.INCREMENT_TEAM", ctx) else - ctx = {xval: xval, yval: Math.abs(yval)} + ctx = {sprintName: dataToDraw.milestones[xval].name, value: Math.abs(yval)} return $translate.instant("BACKLOG.CHART.INCREMENT_CLIENT", ctx) } } diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index c684c476..b619d1fc 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -894,10 +894,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Points", - "OPTIMAL": "Optimal pending points for sprint {{xval}} should be {{yval}}", - "REAL": "Real pending points for sprint {{xval}} is {{yval}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint {{xval}} is {{yval}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint {{xval}} is {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Toggle tags visibility", From a92a0bba519ea049cb6fde636e47dfea44fd8d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 23 Jun 2015 17:17:37 +0200 Subject: [PATCH 025/403] US #2911: Mixin 'users', 'members' and 'memberships' in ProjectDetailSerializer --- app/coffee/modules/backlog/main.coffee | 2 +- app/coffee/modules/common/components.coffee | 6 +++--- app/coffee/modules/controllerMixins.coffee | 4 ++-- app/coffee/modules/issues/detail.coffee | 3 +-- app/coffee/modules/issues/list.coffee | 3 +-- app/coffee/modules/kanban/main.coffee | 2 +- app/coffee/modules/search.coffee | 3 +-- app/coffee/modules/taskboard/main.coffee | 2 +- app/coffee/modules/tasks/detail.coffee | 3 +-- app/coffee/modules/team/main.coffee | 2 +- app/coffee/modules/userstories/detail.coffee | 3 +-- app/coffee/modules/wiki/main.coffee | 3 +-- app/modules/projects/project/project.jade | 7 +++++-- 13 files changed, 20 insertions(+), 23 deletions(-) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index bdafb0fd..3dac4387 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -243,7 +243,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F loadInitialData: -> promise = @.loadProject() promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.initializeSubscription() return promise.then(=> @.loadBacklog()) diff --git a/app/coffee/modules/common/components.coffee b/app/coffee/modules/common/components.coffee index 9de5b456..fe42c1d8 100644 --- a/app/coffee/modules/common/components.coffee +++ b/app/coffee/modules/common/components.coffee @@ -663,14 +663,14 @@ ListItemAssignedtoDirective = ($template) -> template = $template.get("common/components/list-item-assigned-to-avatar.html", true) link = ($scope, $el, $attrs) -> - bindOnce $scope, "membersById", (membersById) -> + bindOnce $scope, "usersById", (usersById) -> item = $scope.$eval($attrs.tgListitemAssignedto) ctx = {name: "Unassigned", imgurl: "/images/unnamed.png"} - member = membersById[item.assigned_to] + member = usersById[item.assigned_to] if member ctx.imgurl = member.photo - ctx.name = member.full_name + ctx.name = member.full_name_display $el.html(template(ctx)) diff --git a/app/coffee/modules/controllerMixins.coffee b/app/coffee/modules/controllerMixins.coffee index 34b5adb6..81d84536 100644 --- a/app/coffee/modules/controllerMixins.coffee +++ b/app/coffee/modules/controllerMixins.coffee @@ -41,9 +41,9 @@ class PageMixin @scope.usersById = groupBy(@scope.users, (e) -> e.id) @scope.roles = _.sortBy(roles, "order") - availableRoles = _(@scope.project.memberships).map("role").uniq().value() + computableRoles = _(@scope.project.members).map("role").uniq().value() @scope.computableRoles = _(roles).filter("computable") - .filter((x) -> _.contains(availableRoles, x.id)) + .filter((x) -> _.contains(computableRoles, x.id)) .value() loadUsersAndRoles: -> promise = @q.all([ diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index 36bb542e..7fd33d1a 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -120,7 +120,6 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.severityById = groupBy(project.severities, (x) -> x.id) @scope.priorityList = project.priorities @scope.priorityById = groupBy(project.priorities, (x) -> x.id) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) return project loadIssue: -> @@ -146,7 +145,7 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.loadIssue() diff --git a/app/coffee/modules/issues/list.coffee b/app/coffee/modules/issues/list.coffee index 607d2b29..d6fbf588 100644 --- a/app/coffee/modules/issues/list.coffee +++ b/app/coffee/modules/issues/list.coffee @@ -112,7 +112,6 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.issueTypes = _.sortBy(project.issue_types, "order") @scope.issueTypeById = groupBy(project.issue_types, (x) -> x.id) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) return project getUrlFilters: -> @@ -278,7 +277,7 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.initializeSubscription() return @q.all([@.loadFilters(), @.loadIssues()]) diff --git a/app/coffee/modules/kanban/main.coffee b/app/coffee/modules/kanban/main.coffee index 137521c6..66935eb8 100644 --- a/app/coffee/modules/kanban/main.coffee +++ b/app/coffee/modules/kanban/main.coffee @@ -209,7 +209,7 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.initializeSubscription() @.loadKanban().then( => @scope.$broadcast("redraw:wip")) diff --git a/app/coffee/modules/search.coffee b/app/coffee/modules/search.coffee index 91a974a5..71f2f311 100644 --- a/app/coffee/modules/search.coffee +++ b/app/coffee/modules/search.coffee @@ -84,7 +84,6 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) @scope.severityById = groupBy(project.severities, (x) -> x.id) @scope.priorityById = groupBy(project.priorities, (x) -> x.id) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) @scope.usStatusById = groupBy(project.us_statuses, (x) -> x.id) return project @@ -98,7 +97,7 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> return @.loadProject().then (project) => @scope.projectId = project.id - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) module.controller("SearchController", SearchController) diff --git a/app/coffee/modules/taskboard/main.coffee b/app/coffee/modules/taskboard/main.coffee index f4e82d92..b8a17671 100644 --- a/app/coffee/modules/taskboard/main.coffee +++ b/app/coffee/modules/taskboard/main.coffee @@ -135,7 +135,7 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.$emit('project:loaded', project) - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) return project diff --git a/app/coffee/modules/tasks/detail.coffee b/app/coffee/modules/tasks/detail.coffee index 228c4aff..5188f767 100644 --- a/app/coffee/modules/tasks/detail.coffee +++ b/app/coffee/modules/tasks/detail.coffee @@ -107,7 +107,6 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.$emit('project:loaded', project) @scope.statusList = project.task_statuses @scope.statusById = groupBy(project.task_statuses, (x) -> x.id) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) return project loadTask: -> @@ -146,7 +145,7 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.loadTask().then(=> @q.all([@.loadSprint(), @.loadUserStory()])) module.controller("TaskDetailController", TaskDetailController) diff --git a/app/coffee/modules/team/main.coffee b/app/coffee/modules/team/main.coffee index 6175b035..a66f60b9 100644 --- a/app/coffee/modules/team/main.coffee +++ b/app/coffee/modules/team/main.coffee @@ -138,7 +138,7 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.loadMembers() return @.loadMemberStats() diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 935f43f3..4e0725e8 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -123,7 +123,6 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.statusList = project.us_statuses @scope.statusById = groupBy(project.us_statuses, (x) -> x.id) @scope.taskStatusById = groupBy(project.task_statuses, (x) -> x.id) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) @scope.pointsList = _.sortBy(project.points, "order") @scope.pointsById = groupBy(@scope.pointsList, (e) -> e.id) return project @@ -188,7 +187,7 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @.loadUs().then(=> @q.all([@.loadSprint(), @.loadTasks()])) module.controller("UserStoryDetailController", UserStoryDetailController) diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 7316ba5c..2d2a203a 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -86,7 +86,6 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.projectId = project.id @scope.project = project @scope.$emit('project:loaded', project) - @scope.membersById = groupBy(project.memberships, (x) -> x.user) return project loadWiki: -> @@ -117,7 +116,7 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin) loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.users, project.roles) + @.fillUsersAndRoles(project.members, project.roles) @q.all([@.loadWikiLinks(), @.loadWiki()]).then () => diff --git a/app/modules/projects/project/project.jade b/app/modules/projects/project/project.jade index 9cf43a78..24017598 100644 --- a/app/modules/projects/project/project.jade +++ b/app/modules/projects/project/project.jade @@ -9,7 +9,8 @@ div.wrapper p.description {{vm.project.get('description')}} div.single-project-tags.tags-container(ng-if="::vm.project.get('tags').size") - span.tag(style='border-left: 5px solid {{::tag.get("color")}};', tg-repeat="tag in ::vm.project.get('colorized_tags')") + span.tag(style='border-left: 5px solid {{::tag.get("color")}};', + tg-repeat="tag in ::vm.project.get('colorized_tags')") span.tag-name {{::tag.get('name')}} div.project-data @@ -18,7 +19,9 @@ div.wrapper section.involved-data h2.title {{"PROJECT.SECTION.TEAM" | translate}} ul.involved-team - a(tg-nav="user-profile:username=member.get('username')", title="{{::member.get('full_name')}}", tg-repeat="member in ::vm.project.get('memberships')") + a(tg-repeat="member in ::vm.project.get('members')", + tg-nav="user-profile:username=member.get('username')", + title="{{::member.get('full_name')}}") img(ng-src="{{::member.get('photo')}}", alt="{{::member.get('full_name')}}") // h2.title Organizations From a6c0fa8adab1d66a3f59df1c36e292c80da90f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 23 Jun 2015 18:45:57 +0200 Subject: [PATCH 026/403] Refactor & fix TeamController --- app/coffee/modules/team/main.coffee | 37 ++++++------------- .../team/team-member-current-user.jade | 4 +- app/partials/team/team-members.jade | 5 ++- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/app/coffee/modules/team/main.coffee b/app/coffee/modules/team/main.coffee index a66f60b9..f4985c3a 100644 --- a/app/coffee/modules/team/main.coffee +++ b/app/coffee/modules/team/main.coffee @@ -70,30 +70,18 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.filtersRole = null loadMembers: -> - currentUser = @auth.getUser() - - if currentUser? and not currentUser.photo? - currentUser.photo = "/images/unnamed.png" - - memberships = @projectService.project.toJS().memberships - - @scope.currentUser = _.find memberships, (membership) => - return currentUser? and membership.user == currentUser.id + user = @auth.getUser() + # Calculate totals @scope.totals = {} + for member in @scope.activeUsers + @scope.totals[member.id] = 0 - _.forEach memberships, (membership) => - @scope.totals[membership.user] = 0 + # Get current user + @scope.currentUser = _.find(@scope.activeUsers, {id: user?.id}) - @scope.memberships = _.filter memberships, (membership) => - if membership.user && (not currentUser? or membership.user != currentUser.id) - return membership - - @scope.memberships = _.filter memberships, (membership) => return membership.is_active - - for membership in @scope.memberships - if not membership.photo? - membership.photo = "/images/unnamed.png" + # Get member list without current user + @scope.memberships = _.reject(@scope.activeUsers, {id: user?.id}) loadProject: -> return @rs.projects.getBySlug(@params.pslug).then (project) => @@ -115,10 +103,10 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) total = _.reduce(vals, (sum, el) -> sum + el) @scope.totals[userId] = total - @scope.stats = @.processStats(stats) + @scope.stats = @._processStats(stats) @scope.stats.totals = @scope.totals - processStat: (stat) -> + _processStat: (stat) -> max = _.max(stat) min = _.min(stat) singleStat = _.map stat, (value, key) -> @@ -130,9 +118,9 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) singleStat = _.object(singleStat) return singleStat - processStats: (stats) -> + _processStats: (stats) -> for key,value of stats - stats[key] = @.processStat(value) + stats[key] = @._processStat(value) return stats loadInitialData: -> @@ -140,7 +128,6 @@ class TeamController extends mixOf(taiga.Controller, taiga.PageMixin) return promise.then (project) => @.fillUsersAndRoles(project.members, project.roles) @.loadMembers() - return @.loadMemberStats() module.controller("TeamController", TeamController) diff --git a/app/partials/team/team-member-current-user.jade b/app/partials/team/team-member-current-user.jade index 698c2f7f..b5d81ce1 100644 --- a/app/partials/team/team-member-current-user.jade +++ b/app/partials/team/team-member-current-user.jade @@ -1,10 +1,10 @@ .row .username figure.avatar - img(tg-bo-src="currentUser.photo", tg-bo-alt="currentUser.full_name") + img(tg-bo-src="currentUser.photo", tg-bo-alt="currentUser.full_name_display") figcaption - span.name(tg-bo-bind="currentUser.full_name") + span.name(tg-bo-bind="currentUser.full_name_display") span.position(tg-bo-bind="currentUser.role_name") diff --git a/app/partials/team/team-members.jade b/app/partials/team/team-members.jade index b941b9d7..55df4055 100644 --- a/app/partials/team/team-members.jade +++ b/app/partials/team/team-members.jade @@ -1,10 +1,11 @@ .row.member(ng-repeat="user in memberships | membersFilter:filtersQ:filtersRole") .username figure.avatar - img(tg-bo-src="user.photo", tg-bo-alt="user.full_name") + img(tg-bo-src="user.photo", tg-bo-alt="user.full_name_display") figcaption - a.name(tg-nav="user-profile:username=user.username", title="{{::user.full_name }}") {{::user.full_name}} + a.name(tg-nav="user-profile:username=user.username", + title="{{::user.full_name_display}}") {{::user.full_name_display}} span.position {{::user.role_name}} .member-stats(tg-team-member-stats, stats="stats", From 10b74afba3f0b9ce9750c786de51aea150eae089 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Jun 2015 12:31:09 +0200 Subject: [PATCH 027/403] Fixing tasks order in user story detail --- app/coffee/modules/related-tasks.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/related-tasks.coffee b/app/coffee/modules/related-tasks.coffee index 2aaa96ea..4817d976 100644 --- a/app/coffee/modules/related-tasks.coffee +++ b/app/coffee/modules/related-tasks.coffee @@ -205,7 +205,7 @@ RelatedTasksDirective = ($repo, $rs, $rootscope) -> link = ($scope, $el, $attrs) -> loadTasks = -> return $rs.tasks.list($scope.projectId, null, $scope.usId).then (tasks) => - $scope.tasks = tasks + $scope.tasks = _.sortBy(tasks, 'ref') return tasks $scope.$on "related-tasks:add", -> From 0d9381291848770d3ddd231e5ebabeadfc373709 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 24 Jun 2015 14:49:17 +0200 Subject: [PATCH 028/403] Fixing the 'filtering users' text on watchers and assigned to lightboxes --- app/coffee/modules/common/lightboxes.coffee | 6 +++--- .../common/lightbox/lightbox-assigned-to-users.jade | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee index c48c7300..a5b5bff7 100644 --- a/app/coffee/modules/common/lightboxes.coffee +++ b/app/coffee/modules/common/lightboxes.coffee @@ -469,7 +469,6 @@ AssignedToLightboxDirective = (lightboxService, lightboxKeyboardNavigationServic } html = usersTemplate(ctx) - html = $compile(html)($scope) $el.find("div.watchers").html(html) @@ -537,7 +536,7 @@ module.directive("tgLbAssignedto", ["lightboxService", "lightboxKeyboardNavigati ## Watchers Lightbox directive ############################################################################# -WatchersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationService, $template) -> +WatchersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationService, $template, $compile) -> link = ($scope, $el, $attrs) -> selectedItem = null usersTemplate = $template.get("common/lightbox/lightbox-assigned-to-users.html", true) @@ -566,6 +565,7 @@ WatchersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationS } html = usersTemplate(ctx) + html = $compile(html)($scope) $el.find("div.watchers").html(html) closeLightbox = () -> @@ -616,4 +616,4 @@ WatchersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationS link:link } -module.directive("tgLbWatchers", ["$tgRepo", "lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", WatchersLightboxDirective]) +module.directive("tgLbWatchers", ["$tgRepo", "lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", "$compile", WatchersLightboxDirective]) diff --git a/app/partials/common/lightbox/lightbox-assigned-to-users.jade b/app/partials/common/lightbox/lightbox-assigned-to-users.jade index 792d4ec3..6dd8e65b 100644 --- a/app/partials/common/lightbox/lightbox-assigned-to-users.jade +++ b/app/partials/common/lightbox/lightbox-assigned-to-users.jade @@ -18,6 +18,6 @@ <% }) %> <% if (showMore) { %> -div(ng-show="filteringUsers", class="more-watchers") +div(class="more-watchers") span(translate="COMMON.ASSIGNED_TO.TOO_MANY") <% } %> From a75037605544ffaf1926c37ac678886ea8f89af4 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 24 Jun 2015 12:17:44 +0200 Subject: [PATCH 029/403] add the new field value in the the timeline --- app/locales/locale-en.json | 6 +- .../user-timeline-item-title.service.coffee | 5 ++ ...er-timeline-item-title.service.spec.coffee | 58 +++++++++++++++++++ .../user-timeline-item-type.service.coffee | 52 +++++++++++++++-- 4 files changed, 116 insertions(+), 5 deletions(-) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index b619d1fc..7bee2fed 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -1239,9 +1239,13 @@ "NEW_PROJECT": "{{username}} created the project {{project_name}}", "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} has updated the wiki page {{obj_name}}", "NEW_COMMENT_US": "{{username}} has commented in the US {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} has commented in the issue {{obj_name}}", diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee index f315fe7c..bc34c4b6 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee @@ -38,6 +38,11 @@ class UserTimelineItemTitle return @._getLink(url, timeline.data.project.name) + else if param == 'new_value' + field_name = Object.keys(timeline.data.values_diff)[0] + + return timeline.data.values_diff[field_name][1] + else if param == 'sprint_name' url = 'project-taskboard:project=vm.activity.project.slug,sprint=vm.activity.sprint.slug' diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee index 5bc7949d..36bc6f52 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee @@ -97,6 +97,30 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") + it "title with new value", () -> + timeline = { + data: { + values_diff: { + status: ['old', 'new'] + } + } + } + + event = {} + + type = { + key: 'NEW_VALUE', + translate_params: ['new_value'] + } + + mockTranslate.instant + .withArgs('NEW_VALUE', {new_value: 'new'}) + .returns('new_value_ok') + + title = mySvc.getTitle(timeline, event, type) + + expect(title).to.be.equal("new_value_ok") + it "title with project name", () -> timeline = { data: { @@ -277,3 +301,37 @@ describe "tgUserTimelineItemTitle", -> title = mySvc.getTitle(timeline, event, type) expect(title).to.be.equal("title_ok") + + it "task title with us_name", () -> + timeline = { + data: { + task: { + name: 'task_name', + userstory: { + ref: 2 + subject: 'subject' + } + } + } + } + + event = { + obj: 'task', + } + + type = { + key: 'TITLE_OBJ', + translate_params: ['us_name'] + } + + objparam = sinon.match ((value) -> + return value.us_name == '#2 subject' + ), "objparam" + + mockTranslate.instant + .withArgs('TITLE_OBJ', objparam) + .returns('title_ok') + + title = mySvc.getTitle(timeline, event, type) + + expect(title).to.be.equal("title_ok") diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee index 1b298aec..20d866a9 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee @@ -140,25 +140,69 @@ timelineType = (timeline, event) -> }, { # UsUpdated check: (timeline, event) -> - return event.obj == 'userstory' && event.type == 'change' + return event.obj == 'userstory' && + event.type == 'change' && + !timeline.data.values_diff.description_diff + key: 'TIMELINE.US_UPDATED_WITH_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'new_value'] + }, + { # UsUpdated description + check: (timeline, event) -> + return event.obj == 'userstory' && + event.type == 'change' && + timeline.data.values_diff.description_diff key: 'TIMELINE.US_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, { # IssueUpdated check: (timeline, event) -> - return event.obj == 'issue' && event.type == 'change' + return event.obj == 'issue' && + event.type == 'change' && + !timeline.data.values_diff.description_diff + key: 'TIMELINE.ISSUE_UPDATED_WITH_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'new_value'] + }, + { # IssueUpdated description + check: (timeline, event) -> + return event.obj == 'issue' && + event.type == 'change' && + timeline.data.values_diff.description_diff key: 'TIMELINE.ISSUE_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, { # TaskUpdated check: (timeline, event) -> - return event.obj == 'task' && event.type == 'change' && !timeline.data.task.userstory + return event.obj == 'task' && + event.type == 'change' && + !timeline.data.task.userstory && + !timeline.data.values_diff.description_diff + key: 'TIMELINE.TASK_UPDATED_WITH_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'new_value'] + }, + { # TaskUpdated description + check: (timeline, event) -> + return event.obj == 'task' && + event.type == 'change' && + !timeline.data.task.userstory && + timeline.data.values_diff.description_diff key: 'TIMELINE.TASK_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, { # TaskUpdated with US check: (timeline, event) -> - return event.obj == 'task' && event.type == 'change' && timeline.data.task.userstory + return event.obj == 'task' && + event.type == 'change' && + timeline.data.task.userstory && + !timeline.data.values_diff.description_diff + key: 'TIMELINE.TASK_UPDATED_WITH_US_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'us_name', 'new_value'] + }, + { # TaskUpdated with US description + check: (timeline, event) -> + return event.obj == 'task' && + event.type == 'change' && + timeline.data.task.userstory && + timeline.data.values_diff.description_diff key: 'TIMELINE.TASK_UPDATED_WITH_US', translate_params: ['username', 'field_name', 'obj_name', 'us_name'] }, From 27b00f365fed0e9952b2859415a5160b94e136c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Tue, 23 Jun 2015 19:21:35 +0200 Subject: [PATCH 030/403] Issue#2518: Allow to include anchor links in the wiki pages --- app/coffee/modules/common/components.coffee | 9 ++++++++- app/coffee/modules/common/history.coffee | 7 +++++++ app/coffee/modules/wiki/main.coffee | 7 +++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/coffee/modules/common/components.coffee b/app/coffee/modules/common/components.coffee index fe42c1d8..c96ae3ae 100644 --- a/app/coffee/modules/common/components.coffee +++ b/app/coffee/modules/common/components.coffee @@ -547,7 +547,7 @@ module.directive("tgEditableSubject", ["$rootScope", "$tgRepo", "$tgConfirm", "$ ############################################################################# -## Editable subject directive +## Editable description directive ############################################################################# EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, $selectedText, $qqueue, $template) -> @@ -593,6 +593,13 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, $el.find('.view-description').hide() $el.find('textarea').focus() + $el.on "click", "a", (event) -> + target = angular.element(event.target) + href = target.attr('href') + if href.indexOf("#") == 0 + event.preventDefault() + $('body').scrollTop($(href).offset().top) + $el.on "click", ".save", (e) -> e.preventDefault() diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index dc491dc4..1dd8e3d0 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -382,6 +382,13 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c target = angular.element(event.currentTarget) save(target) + $el.on "click", "a", (event) -> + target = angular.element(event.target) + href = target.attr('href') + if href.indexOf("#") == 0 + event.preventDefault() + $('body').scrollTop($(href).offset().top) + $el.on "click", ".show-more", (event) -> event.preventDefault() diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 2d2a203a..d9d2cd15 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -243,6 +243,13 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $ promise.finally -> $loading.finish($el.find('.save-container')) + $el.on "click", "a", (event) -> + target = angular.element(event.target) + href = target.attr('href') + if href.indexOf("#") == 0 + event.preventDefault() + $('body').scrollTop($(href).offset().top) + $el.on "mousedown", ".view-wiki-content", (event) -> target = angular.element(event.target) return if not isEditable() From d3986bc49df6274e6bde4b7e3253f71cd1ac60a8 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 25 Jun 2015 11:44:24 +0200 Subject: [PATCH 031/403] fix restore comment button --- app/coffee/modules/common/history.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index 1dd8e3d0..a3dbbc5f 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -385,7 +385,7 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c $el.on "click", "a", (event) -> target = angular.element(event.target) href = target.attr('href') - if href.indexOf("#") == 0 + if href && href.indexOf("#") == 0 event.preventDefault() $('body').scrollTop($(href).offset().top) From b7874214cbb68e829781209c250be4d6824a1207 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 25 Jun 2015 12:38:31 +0200 Subject: [PATCH 032/403] add loader in the search result page --- app/coffee/app.coffee | 3 ++- app/coffee/modules/common/loading.coffee | 14 ++++++++++++++ app/coffee/modules/search.coffee | 5 ++++- app/partials/includes/modules/search-in.jade | 3 ++- app/styles/modules/search/search-in.scss | 9 +++++++-- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index b6165763..a978156d 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -98,7 +98,8 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven { templateUrl: "search/search.html", reloadOnSearch: false, - section: "search" + section: "search", + loader: true } ) diff --git a/app/coffee/modules/common/loading.coffee b/app/coffee/modules/common/loading.coffee index 916fa044..bb92f178 100644 --- a/app/coffee/modules/common/loading.coffee +++ b/app/coffee/modules/common/loading.coffee @@ -36,3 +36,17 @@ class TgLoadingService extends taiga.Service target.removeClass('loading') module.service("$tgLoading", TgLoadingService) + +LoadingDirective = ($loading) -> + link = ($scope, $el, attr) -> + $scope.$watch attr.tgLoading, (showLoading) => + if showLoading + $loading.start($el) + else + $loading.finish($el) + + return { + link:link + } + +module.directive("tgLoading", ["$tgLoading", LoadingDirective]) diff --git a/app/coffee/modules/search.coffee b/app/coffee/modules/search.coffee index 71f2f311..661dedfd 100644 --- a/app/coffee/modules/search.coffee +++ b/app/coffee/modules/search.coffee @@ -69,7 +69,10 @@ class SearchController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.$watch "searchTerm", (term) => if term - loadSearchData(term) + @scope.loading = true + + @.loadSearchData(term).then () => + @scope.loading = false loadFilters: -> defered = @q.defer() diff --git a/app/partials/includes/modules/search-in.jade b/app/partials/includes/modules/search-in.jade index f121ff1e..e13718a3 100644 --- a/app/partials/includes/modules/search-in.jade +++ b/app/partials/includes/modules/search-in.jade @@ -2,4 +2,5 @@ section.search-in header fieldset input(type="text", placeholder="{{'SEARCH.PLACEHOLDER_SEARCH' | translate}}", ng-model="searchTerm") - a.icon.icon-search(href="", title="{{'SEARCH.TITLE_ACTION_SEARCH' | translate}}") + .icon-search-wrapper(tg-loading="loading") + a.icon.icon-search(href="", title="{{'SEARCH.TITLE_ACTION_SEARCH' | translate}}") diff --git a/app/styles/modules/search/search-in.scss b/app/styles/modules/search/search-in.scss index d66fdcf3..19eecf56 100644 --- a/app/styles/modules/search/search-in.scss +++ b/app/styles/modules/search/search-in.scss @@ -6,10 +6,15 @@ color: $gray-light; } } - .icon-search { - color: $gray-light; + .icon-search-wrapper { position: absolute; right: .7rem; top: .7rem; } + .icon-search { + color: $gray-light; + } + .loading-spinner { + margin-top: .1rem; + } } From 2041d84beb0effb58bf960c02eabcfd0b264710d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 25 Jun 2015 18:10:53 +0200 Subject: [PATCH 033/403] [i18n] Update locales --- app/locales/locale-de.json | 76 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 5d8a7417..ad5c2de0 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -105,12 +105,12 @@ "TASK": "Aufgabe", "ISSUE": "Ticket", "TAGS": { - "PLACEHOLDER": "Ich bin's! Kennzeichne mich...", + "PLACEHOLDER": "Schlagwort...", "DELETE": "Schlagwort löschen", "ADD": "Schlagwort hinzufügen" }, "DESCRIPTION": { - "EMPTY": "Leere ist so langweilig... werden Sie doch anschaulich...", + "EMPTY": "Bitte geben Sie eine Beschreibung ein...", "NO_DESCRIPTION": "Noch keine Beschreibung " }, "FIELDS": { @@ -170,29 +170,29 @@ }, "WYSIWYG": { "H1_BUTTON": "Überschrift 1", - "H1_SAMPLE_TEXT": "Geben Sie den Titel ein...", + "H1_SAMPLE_TEXT": "Titel...", "H2_BUTTON": "Überschrift 2", - "H2_SAMPLE_TEXT": "Geben Sie den Titel ein...", + "H2_SAMPLE_TEXT": "Titel...", "H3_BUTTON": "Überschrift 3", - "H3_SAMPLE_TEXT": "Geben Sie den Titel ein...", + "H3_SAMPLE_TEXT": "Titel...", "BOLD_BUTTON": "Fettschrift", - "BOLD_BUTTON_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "BOLD_BUTTON_SAMPLE_TEXT": "Text...", "ITALIC_BUTTON": "Kursivschrift", - "ITALIC_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "ITALIC_SAMPLE_TEXT": "Text...", "STRIKE_BUTTON": "Treffer", - "STRIKE_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "STRIKE_SAMPLE_TEXT": "Text...", "BULLETED_LIST_BUTTON": "Aufzählung", - "BULLETED_LIST_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "BULLETED_LIST_SAMPLE_TEXT": "Text...", "NUMERIC_LIST_BUTTON": "Numerische Liste", - "NUMERIC_LIST_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "NUMERIC_LIST_SAMPLE_TEXT": "Text...", "PICTURE_BUTTON": "Bild", - "PICTURE_SAMPLE_TEXT": "Geben Sie Ihren Alternativtext zum Bild ein...", + "PICTURE_SAMPLE_TEXT": "Alternativtext zum Bild...", "LINK_BUTTON": "Link", - "LINK_SAMPLE_TEXT": "Geben Sie Ihren Linktext ein...", + "LINK_SAMPLE_TEXT": "Linktext...", "QUOTE_BLOCK_BUTTON": "Blockzitat", - "QUOTE_BLOCK_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "QUOTE_BLOCK_SAMPLE_TEXT": "Text...", "CODE_BLOCK_BUTTON": "Kodeblock", - "CODE_BLOCK_SAMPLE_TEXT": "Geben Sie Ihren Text ein...", + "CODE_BLOCK_SAMPLE_TEXT": "Text...", "PREVIEW_BUTTON": "Vorschau", "EDIT_BUTTON": "Bearbeiten", "MARKDOWN_HELP": "Markdown syntax Hilfe" @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Ändern Sie Ihr Passwort - Taiga", - "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihr Taiga Benutzerkonto, und hey!, es empfiehlt sich, mehr eisenreiche Nahrung zu sich zu nehmen - die ist gut für's Gehirn :P", + "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihr Taiga Benutzerkonto.", "SECTION_NAME": "Passwort ändern", "FIELD_CURRENT_PASSWORD": "Aktuelles Passwort", "PLACEHOLDER_CURRENT_PASSWORD": "Ihr aktuelles Passwort (oder leer, wenn Sie noch kein Passwort haben)", @@ -423,9 +423,9 @@ "DELETE": "Dieses Projekt löschen" }, "REPORTS": { - "TITLE": "Reporte", + "TITLE": "Berichte", "SUBTITLE": "Exportieren Sie Ihre Projektdaten in CSV Format und erstellen Sie Ihre eigenen Berichte. ", - "DESCRIPTION": "Laden Sie eine CSV Datei herunter oder kopieren Sie die generierte URL und öffnen Sie sie in Ihrem bevorzugten Text-Editor oder in Ihrer Tabellenkalkulation, um Ihre eigenen Projektdaten-Reporte zu erstellen. So können Sie Ihre Daten leicht überblicken und analysieren.", + "DESCRIPTION": "Laden Sie eine CSV Datei herunter oder kopieren Sie die generierte URL und öffnen Sie sie in Ihrem bevorzugten Text-Editor oder in Ihrer Tabellenkalkulation, um Ihre eigenen Projektdaten-Berichte zu erstellen. So können Sie Ihre Daten leicht überblicken und analysieren.", "HELP": "Wie kann ich dies in meiner eigenen Tabellenkalkulation nutzen?", "REGENERATE_TITLE": "Die URL ändern", "REGENERATE_SUBTITLE": "Sie sind im Begriff, die CSV data access URL zu ändern. Die vorherige URL wird deaktiviert. Sind Sie sicher?" @@ -477,8 +477,8 @@ "TITLE": "Status", "SUBTITLE": "Spezifizieren Sie die Status, die Ihre User-Stories, Aufgaben und Tickets durchlaufen werden. ", "US_TITLE": "User-Story Status", - "TASK_TITLE": "Aufgabenstatus", - "ISSUE_TITLE": "Ticket Status" + "TASK_TITLE": "Aufgaben-Status", + "ISSUE_TITLE": "Ticket-Status" }, "PROJECT_VALUES_TYPES": { "TITLE": "Typen", @@ -489,7 +489,7 @@ "ROLES": { "PAGE_TITLE": "Rollen - {{projectName}}", "WARNING_NO_ROLE": "Beachten Sie, keine Rolle in Ihrem Projekt wird in der Lage sein, die Punktevergabe für User-Stories einzuschätzen. ", - "HELP_ROLE_ENABLED": "Wenn Sie dies freischalten, werden Mitglieder, denen diese Rolle zugewiesen ist, in der Lage sein, die Punktevergabe für User-Stories zu veranschlagen. ", + "HELP_ROLE_ENABLED": "Wenn Sie dies freischalten, werden Mitglieder, denen diese Rolle zugewiesen ist, in der Lage sein, die Punktevergabe für User-Stories vorzunehmen. ", "COUNT_MEMBERS": "{{ role.members_count }} Mitglieder mit dieser Rolle", "TITLE_DELETE_ROLE": "Rolle löschen", "REPLACEMENT_ROLE": "Alle Benutzer mit dieser Rolle werden verschoben nach ", @@ -521,9 +521,9 @@ "SECTION_NAME": "Webhooks", "SUBTITLE": "Webhooks meldet externe Dienste über Ereignisse in Taiga, wie Kommentare, User-Stories...", "ADD_NEW": "Fügen Sie ein neues Webhook hinzu", - "TYPE_NAME": "Geben Sie den Namen des Services ein", + "TYPE_NAME": "Servicename...", "TYPE_PAYLOAD_URL": "Geben Sie die Service Payload URL ein", - "TYPE_SERVICE_SECRET": "Geben Sie den Service Sicherheitsschlüssel ein", + "TYPE_SERVICE_SECRET": "Sicherheitsschlüssel...", "SAVE": "Webhook sichern ", "CANCEL": "Webhook beenden", "SHOW_HISTORY": "(Chronik anzeigen)", @@ -571,11 +571,11 @@ "DEFAULT_VALUES": { "LABEL_POINTS": "Vorgegebener Wert für Punkteauswahl", "LABEL_US": "Vorgegebener Wert für User-Story-Status Auswahl ", - "LABEL_TASK_STATUS": "Vorgegebener Wert für Aufgabenstatusauswahl ", + "LABEL_TASK_STATUS": "Vorgegebene Auswahl für den Aufgaben-Status", "LABEL_PRIORITY": "Vorgegebener Wert für Prioritätsauswahl", "LABEL_SEVERITY": "Vorgegebener Wert für Gewichtungsauswahl", "LABEL_ISSUE_TYPE": "Vorgegebener Wert für Ticketartauswahl ", - "LABEL_ISSUE_STATUS": "Vorgegebener Wert für Ticketstatusauswahl " + "LABEL_ISSUE_STATUS": "Vorgegebene Auswahl für den Ticket-Status" }, "STATUS": { "PLACEHOLDER_WRITE_STATUS_NAME": "Benennen Sie den neuen Status" @@ -642,7 +642,7 @@ "PROFILE_SIDEBAR": { "TITLE": "Ihr Profil", "DESCRIPTION": "Da andere Mitglieder sehen, dass sie ebenfalls an einem Projekt arbeiten wäre es schön, wenn Sie ein paar Informationen zu Ihrer Person angeben.", - "ADD_INFO": "Bearbeiten Sie Ihre Bio" + "ADD_INFO": "Bio bearbeiten" } }, "PROJECT": { @@ -682,11 +682,11 @@ "HELP": "Hilfe", "FEEDBACK_TITLE": "Feedback senden", "FEEDBACK": "Feedback", - "NOTIFICATIONS_TITLE": "Bearbeiten Sie Ihre Benachrichtigungseinstellungen", + "NOTIFICATIONS_TITLE": "Benachrichtigungseinstellungen bearbeiten", "NOTIFICATIONS": "Benachrichtigungen", - "ORGANIZATIONS_TITLE": "Bearbeiten Sie Ihre Organisationen", + "ORGANIZATIONS_TITLE": "Organisationen bearbeiten", "ORGANIZATIONS": "Organisationen bearbeiten", - "SETTINGS_TITLE": "Bearbeiten Sie Ihre Einstellungen", + "SETTINGS_TITLE": "Einstellungen bearbeiten", "SETTINGS": "Einstellungen", "VIEW_PROFILE_TITLE": "Profil ansehen", "VIEW_PROFILE": "Profil ansehen", @@ -715,7 +715,7 @@ }, "LIGHTBOX": { "DELETE_ACCOUNT": { - "SECTION_NAME": "Taiga Benutzerkonto löschen", + "SECTION_NAME": "Ihr Taiga Benutzerkonto löschen", "CONFIRM": "Sind Sie sicher, dass Sie Ihr Taiga Benutzerkonto löschen wollen?", "SUBTITLE": "Wir werden Sie vermissen! :-(", "NEWSLETTER_LABEL_TEXT": "Ich möchte keinen Newsletter mehr erhalten" @@ -758,7 +758,7 @@ "CREATE_EDIT_TASK": { "TITLE": "Neue Aufgabe", "PLACEHOLDER_SUBJECT": "Aufgaben Betreff", - "PLACEHOLDER_STATUS": "Aufgabenstatus", + "PLACEHOLDER_STATUS": "Aufgaben-Status", "OPTION_UNASSIGNED": "Nicht zugeordnet", "PLACEHOLDER_SHORT_DESCRIPTION": "Geben Sie eine kurze Beschreibung ein", "ACTION_EDIT": "Aufgabe bearbeiten" @@ -797,7 +797,7 @@ "LIGHTBOX_TITLE_BLOKING_US": "Blockiert uns", "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} Aufgaben fertiggestellt", "ASSIGN": "Zugeordnete User-Story", - "NOT_ESTIMATED": "Nicht abgeschätzt", + "NOT_ESTIMATED": "Nicht eingeschätzt", "TOTAL_US_POINTS": "User-Story-Punkte insgesamt", "FIELDS": { "TEAM_REQUIREMENT": "Team Anforderung", @@ -841,7 +841,7 @@ "STATUS": "Status", "IS_CLOSED": "ist geschlossen", "FINISH_DATE": "Endtermin", - "TYPE": "typen", + "TYPE": "Typen", "PRIORITY": "Priorität", "SEVERITY": "Gewichtung", "ASSIGNED_TO": "zugewiesen an", @@ -978,7 +978,7 @@ "SECTION_NAME": "Aufgabendetails", "LINK_TASKBOARD": "Taskboard", "TITLE_LINK_TASKBOARD": "Zu Taskboard wechseln", - "PLACEHOLDER_SUBJECT": "Geben Sie den neuen Aufgaben Betreff ein", + "PLACEHOLDER_SUBJECT": "Betreff...", "TITLE_SELECT_STATUS": "Status Bezeichnung", "OWNER_US": "Diese Aufgabe gehört zu ", "TITLE_LINK_GO_OWNER": "Zur User-Story wechseln", @@ -1039,7 +1039,7 @@ "FIELDS": { "PRIORITY": "Priorität", "SEVERITY": "Gewichtung", - "TYPE": "Typen" + "TYPE": "Arten" }, "CONFIRM_PROMOTE": { "TITLE": "Dieses Problem zur User-Story aufwerten", @@ -1053,7 +1053,7 @@ "BREADCRUMB": "Filter", "TITLE_BREADCRUMB": "Filter", "CATEGORIES": { - "TYPE": "Typen", + "TYPE": "Arten", "STATUS": "Status", "SEVERITY": "Gewichtung", "PRIORITIES": "Prioritäten", @@ -1069,7 +1069,7 @@ }, "TABLE": { "COLUMNS": { - "TYPE": "Typen", + "TYPE": "Arten", "SEVERITY": "Gewichtung", "PRIORITY": "Priorität", "SUBJECT": "Thema", @@ -1171,7 +1171,7 @@ "IMAGE_HELP": "Das Bild wird auf 80x80px skaliert.
", "ACTION_CHANGE_IMAGE": "Ändern", "ACTION_USE_GRAVATAR": "Gravatar verwenden", - "ACTION_DELETE_ACCOUNT": "Taiga Benutzerkonto löschen", + "ACTION_DELETE_ACCOUNT": "Ihr Taiga Benutzerkonto löschen", "CHANGE_EMAIL_SUCCESS": "Sehen Sie in Ihren Posteingang!
Wir haben eine E-Mail an Ihr Konto gesendet
mit der Anleitung, wie Sie Ihre neue Adresse anlegen", "CHANGE_PHOTO": "Foto ändern", "FIELD": { @@ -1212,7 +1212,7 @@ }, "HINTS": { "SECTION_NAME": "Hinweis", - "LINK": "Wenn Sie wissen möchten, wie sie es benutzen können, besuchen Sie unsere Support Seite ", + "LINK": "Mehr dazu auf unserer Support Seite ", "LINK_TITLE": "Besuchen Sie unsere Support Seite", "HINT1_TITLE": "Wussten Sie, dass Sie Projekte importieren und exportieren?", "HINT1_TEXT": "Dies erlaubt Ihnen, alle Ihre Daten zu extrahieren und sie von einer Taiga zur nächsten zu transportieren", From 3c8e3e85a4d42b6fb58c26de142130cdd49a40aa Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 26 Jun 2015 07:51:55 +0200 Subject: [PATCH 034/403] Fixing i18n for import project href titles --- .../dropdown-project-list/dropdown-project-list.jade | 2 +- app/modules/projects/listing/projects-listing.jade | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade index 46a3e9e9..37b5800d 100644 --- a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade +++ b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade @@ -21,6 +21,6 @@ div.navbar-dropdown.dropdown-project-list translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT") span(tg-import-project-button) - a.button-blackish.import-project-button(href="", title="{{'PROJECT.NAVIGATION.TITLE_ACTION_IMPORT' | translate}}") + a.button-blackish.import-project-button(href="", title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}") span.icon.icon-upload input.import-file.hidden(type="file") diff --git a/app/modules/projects/listing/projects-listing.jade b/app/modules/projects/listing/projects-listing.jade index 8cfcf2fa..f4760ff1 100644 --- a/app/modules/projects/listing/projects-listing.jade +++ b/app/modules/projects/listing/projects-listing.jade @@ -4,7 +4,7 @@ div.project-list-wrapper.centered div.create-options a.create-project-btn.button-green(href="#", ng-click="vm.newProject()", title="{{'PROJECT.NAVIGATION.ACTION_CREATE_PROJECT' | translate}}", translate="PROJECT.NAVIGATION.ACTION_CREATE_PROJECT") span(tg-import-project-button) - a.button-blackish.import-project-button(href="", title="{{'PROJECT.NAVIGATION.TITLE_ACTION_IMPORT' | translate}}") + a.button-blackish.import-project-button(href="", title="{{'PROJECT.NAVIGATION.TITLE_IMPORT_PROJECT' | translate}}") span.icon.icon-upload input.import-file.hidden(type="file") From ddb0ac3a05bddef70460cb863b3f491c040c3b70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Fri, 26 Jun 2015 08:19:52 +0200 Subject: [PATCH 035/403] Add username to profile view --- app/modules/profile/profile-bar/profile-bar.jade | 1 + app/modules/profile/styles/profile-bar.scss | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/modules/profile/profile-bar/profile-bar.jade b/app/modules/profile/profile-bar/profile-bar.jade index a0c0017d..3c16c794 100644 --- a/app/modules/profile/profile-bar/profile-bar.jade +++ b/app/modules/profile/profile-bar/profile-bar.jade @@ -6,6 +6,7 @@ section.profile-bar // span(translate="USER.PROFILE.FOLLOW") div.profile-data h1(ng-class="{'not-full-name': !vm.user.get('full_name')}") {{::vm.user.get("full_name_display")}} + .username @{{::vm.user.get("username")}} h2 {{::vm.stats.get('roles').join(", ")}} // div.location // include ../../../svg/location.svg diff --git a/app/modules/profile/styles/profile-bar.scss b/app/modules/profile/styles/profile-bar.scss index 2915ebcf..200fcad0 100644 --- a/app/modules/profile/styles/profile-bar.scss +++ b/app/modules/profile/styles/profile-bar.scss @@ -66,8 +66,8 @@ h1 { @extend %bold; @extend %xlarge; - line-height: 1; - margin-bottom: .5rem; + line-height: 1.2; + margin-bottom: .25rem; text-transform: none; } .not-full-name { @@ -80,6 +80,12 @@ line-height: 1.2; margin-bottom: 1rem; } + .username { + @extend %light; + @extend %large; + color: $gray-light; + margin-bottom: 1rem; + } .location { color: $gray-light; margin-bottom: 1rem; From 1a83d4754e4b37daf2c2e427fda4e39d979d38ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Fri, 26 Jun 2015 08:50:34 +0200 Subject: [PATCH 036/403] Added Opensans Light Mising Font --- app/fonts/OpenSans-Light.woff | 811 ++++++++++++++++++++++++++++++++++ 1 file changed, 811 insertions(+) create mode 100644 app/fonts/OpenSans-Light.woff diff --git a/app/fonts/OpenSans-Light.woff b/app/fonts/OpenSans-Light.woff new file mode 100644 index 00000000..d50b69a1 --- /dev/null +++ b/app/fonts/OpenSans-Light.woff @@ -0,0 +1,811 @@ + + + + + + + + + + + + open-sans/OpenSans-Light.woff at gh-pages · FontFaceKit/open-sans + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content +
+ + + + + + + + + + + + +
+
+
+ +
+
+
+ + +
    + +
  • +
    + +
    + + + + Watch + + + + +
    + +
    +
    +
    +
  • + +
  • + +
    + +
    + + +
    +
    + + +
    + +
  • + +
  • + + + Fork + + + + +
  • + +
+ +

+ + /open-sans + + + + + +

+
+
+ +
+
+
+ + + +
+ +
+

HTTPS clone URL

+
+ + + + +
+
+ + +
+

SSH clone URL

+
+ + + + +
+
+ + +
+

Subversion checkout URL

+
+ + + + +
+
+ + + +
You can clone with +
,
, or
. + + + +
+ + + + + + + Download ZIP + +
+
+ +
+ + + + + + + +
+ +
+ + + branch: + gh-pages + + + +
+ +
+ + + + +
+ + +
+ + +
+
+ + Martin Domke + + +
+ + + +
+ +
+
+
+ +
+ Raw + History +
+ + + +
+ +
+ +
+ 62.844 kB +
+
+ +
+
+ View Raw +
+
+ +
+ +Jump to Line + + +
+ +
+ +
+
+ + +
+ +
+ +
+ + +
+
+
+ +
+
+
+
+
+ +
+ + + + + + +
+ + + Something went wrong with that request. Please try again. +
+ + + + + + + + + From 03632901738ca1bca8159500aa3ab34d953e5acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 25 Jun 2015 17:31:05 +0200 Subject: [PATCH 037/403] Fix user mentions in activity and comments tab --- app/coffee/modules/common/history.coffee | 19 ++++++------------- .../common/history/history-activity.jade | 4 ++-- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index a3dbbc5f..90bf4521 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -68,7 +68,7 @@ class HistoryController extends taiga.Controller return @rs.history.undeleteComment(type, objectId, activityId).then => @.loadHistory(type, objectId) -HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $compile) -> +HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $compile, $navUrls) -> templateChangeDiff = $template.get("common/history/history-change-diff.html", true) templateChangePoints = $template.get("common/history/history-change-points.html", true) templateChangeGeneric = $template.get("common/history/history-change-generic.html", true) @@ -136,15 +136,6 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c return humanizedFieldNames[field] or field - getUserFullName = (userId) -> - return $scope.usersById[userId]?.full_name_display - - getUserAvatar = (userId) -> - if $scope.usersById[userId]? - return $scope.usersById[userId].photo - else - return "/images/unnamed.png" - countChanges = (comment) -> return _.keys(comment.values_diff).length @@ -286,8 +277,9 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c return html[0].outerHTML html = templateActivity({ - avatar: getUserAvatar(comment.user.pk) + avatar: comment.user.photo userFullName: comment.user.name + userProfileUrl: if comment.user.is_active then $navUrls.resolve("user-profile", {username: comment.user.username}) else "" creationDate: moment(comment.created_at).format(getPrettyDateFormat()) comment: comment.comment_html changesText: renderChangesHelperText(comment) @@ -305,8 +297,9 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c renderChange = (change) -> return templateActivity({ - avatar: getUserAvatar(change.user.pk) + avatar: change.user.photo userFullName: change.user.name + userProfileUrl: if change.user.is_active then $navUrls.resolve("user-profile", {username: change.user.username}) else "" creationDate: moment(change.created_at).format(getPrettyDateFormat()) comment: change.comment_html changes: renderChangeEntries(change) @@ -458,4 +451,4 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", "$translate", - "$compile", HistoryDirective]) + "$compile", "$tgNavUrls", HistoryDirective]) diff --git a/app/partials/common/history/history-activity.jade b/app/partials/common/history/history-activity.jade index 89ed64fd..85f069f4 100644 --- a/app/partials/common/history/history-activity.jade +++ b/app/partials/common/history/history-activity.jade @@ -1,10 +1,10 @@ div(class!="activity-single <%- mode %>") .activity-user - a.avatar(href="" title!="<%- userFullName %>") + a.avatar(href!="<%- userProfileUrl %>", title!="<%- userFullName %>") img(src!="<%- avatar %>", alt!="<%- userFullName %>") .activity-content .activity-username - a.username(href="", title!="<%- userFullName %>") + a.username(href!="<%- userProfileUrl %>", title!="<%- userFullName %>") | <%- userFullName %> span.date | <%- creationDate %> From 9fb03994a959952446c6bc81dc3ca5c763bd63e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Fri, 26 Jun 2015 13:09:34 +0200 Subject: [PATCH 038/403] Fix some problems between non-photo image and unassigned image --- app/coffee/modules/wiki/main.coffee | 2 +- app/images/user-noimage.png | Bin 0 -> 6240 bytes .../user-timeline-item/user-timeline-item.jade | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 app/images/user-noimage.png diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index d9d2cd15..4a2b87d4 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -155,7 +155,7 @@ WikiSummaryDirective = ($log, $template, $compile, $translate) -> user = $scope.usersById[wiki.last_modifier] if user is undefined - user = {name: "unknown", imgUrl: "/images/unnamed.png"} + user = {name: "unknown", imgUrl: "/images/user-noimage.png"} else user = {name: user.full_name_display, imgUrl: user.photo} diff --git a/app/images/user-noimage.png b/app/images/user-noimage.png new file mode 100644 index 0000000000000000000000000000000000000000..d779bbd4d88f785d5792eb98a16b83746425dfe1 GIT binary patch literal 6240 zcmV-m7@y~fP)|5+8}KapePd8mK{r$E!&bTTiVr1 zdvm#5-sF(OIr_tp6n8ls&T!t4d-MYcq{x{!Z}~p&d%f@bKJwh(kLdV+>}W89?!X|y zvwrZbf6(0+ICeA%K5^nZ_{53t47wWw2RG;r3<}5hK7|J+o&W$WtX;+R`CkpVM}xzT zlmsJ@12}*DTh0HUKmIL@L=FtFM}x(VBZ0t)c;@U6!7)PfGma7P%-J78;KTv;Y;f3d zBzWS)a~KNV*Y^2P@IE|o;<*9zXz`##&p9&HZn7!r&| z4&m_!zuEP=#~=JAMk9y%(4)(dNRoC&B5-XK{G^QOEZk9)A?4C!h78N1G4ZngnCfqj>Cr zZ}fcsV-I`-W6`4&d$c*RZAswcLwNe37r-)n&uy>_kEb7c0X{xNv1gkP+m-~MKJ|S> z#c|i|M8$D@`qcL+^l0;9Taw`HfiK|T*g0zL9UMD{vj@IFt-Z~LZAXILLl5H7V_&D< z?xV-Pj@?5KQg3%NU|W&E&xi5!*%!bN`ir9s;qdg?7vSf^)Y~33whajg2tITAd4&DD zJbOmizYCu^{X7VWXU`Y}whaj$KKMoKAN{cB&)GlvVLW{Bi=IEHpP(u?A36MGundp9 zw1QkYfxMJJL0W~X$uu9+hKcxboICn8PoL3>b4S01rOb6KrmuVY9F7$b5yub_#}Nq_ zuRcD6Utjwxy3e86Sim>bHXC*5C|5JcmlJhjte_yRATJs371bR^m*A0Rgq^L`eI#CRQR4t!JK=9<5=MnOc(EKxOA><#ylV_gCFE0HVbXX^B3!G>S zusGJ7(T!J8h&p<1-sCrS3#uf@OU^pjN|5o`18v_+a(12cxTj*0kQE6ZI`k#%8+n*k z_Z?&3$iw*1p)cXm^gqJK1re^#;;1-|NON|N!7oIpJ#+JufN}>#AqG*1VLW!M?K_6B z*b_eiO;@05HE3E5s%E^`b&YC28X$xL%kVA#I6Qgg&v9zs>8nt+TF-xz zU3l>uQzbz~&O=rtj}tZtMx%#15&$ry1VdQxjIa5bRLi4OS+n&79~VN<7q{Ibj^QyH zJ%r`V`#=}_z%9H`2h`&P1rNkkD~5s-5P4_D6aYu7iM^~mihLA9!3oFrIYG5ngshaQ zw@aM_W*!19h(Z*x9)D=oK`5DFdJ~Yb;Dlpq-wC`@x711Ch2a7ivvV|ZsOONaF|hXT z?KKC1fM7Io$W;!56}(UdfF~sIqN4<((ZjBOTmk~t&I~8S)dCdD@EDCAhF!ur!PX&x z2OS*>-3O6(?`zu;^DN<951+_KFcfOv;NlirMjg=ZXh4V|7NBEr*^wl)M0qSQfq)RB z(pCdrsaonJXt;^A5b(#T3D$m+fWYWGO>7x;0MK<4(}h{o)C!fh?AQdodIlR&Q!7Xp zW~sCV0F_$76Za7Chy*mB?nA*W>5nAPpc#GERo87b;FT%>JR$+@4$Ddz zYlXY6+p%RBQXs)v;V$)A>y;`1JR<@94i}^(3YC zM*@#JoGQ#fR^1t$Rx_Pt+_{IcDj`*vanV9&c)2*|jZNTDhjm>;(xrW1O@iK4fd->* zUM*v9Ih%mCo7f6jk+7D()ARjS9)cSZtmW@`_BR7tP#pmF+(aKALM%ApI6tsZSw*3; z+Ec%*JcM4|!(RHsGCYRE`)mc2ymSu%4@=nP$_WgICp&yg5D`Za^bZ3tib!Nji;n)# zRN)SMd=LWbte6CCbs(!{qzcX?lb;VG7Tg0uSO{DY0v|-KyxdWhcqs({4<$h-4}oQP zjD#nf1ZaFV9Nvde%V*u7>l#+FQ;vOctJ&_91e&g5B|Bx?4j>?ih~pRv?FDI(exeY? zNcaFa)@OR3m-YbQDGAy;?&rf8i5viLnt4PJ7RL||-EUhx)KtmwEbQziI(H9Kg*&L( z^i~X_Pa@bMl+3XLM#2Y7)6BQ7Bv{vRf`~YVq0rv01MK5N*cCZwyJk?al5#v#%x1h( z_b@N5plCC0;pfBH)sg)7KnOuJup6=91PHk|G+yU!dPagq$IZll*G@59T|L;_Pq0>; zMb&{lVNL@3s-UWru~zK9EU>U*I3@`^lSRAdZ z2Wv6ij33yv56s*|yCl$b)mA*9DgGTKtggGC6)+s$kAQDzYpMf=usF5vbBF}S9L)eT z80z6bSM^X+D_G6ji`JRBiFVz?)%;A?RZTx1!LG=`9?5?Xgb;*$!#KPD_c|JlG(g=& z4Eo}DWcYv}&n`OVu^xq;S_VHB58XH>?2NmL$kY36!dx)7A~~ zKZZb$v)>G|Dq-*NX~cr};nLJkktr=uYr6rel3*f!0#BTL4)Ne#0H7S;XsCyMmg*s0 zoJCbBS+>O1lTL@j`!F2d2Y_@XK~*UsZD9wnjDX?DeyRij(2PQc{UbPk{M$G<{!yy! z1C&U>5Dup&e+TD|d=&zFPXu}qM)mPQOZA}Zde^ml0)mmqBt#(!QHWwVY)!02PJ^zS zZ!8goh++G9aEeN;Wg@YJ!`aE-#Yc|(A=PKOCPB~_$NA&m!r}49+P9R`a(_cSsX7T)O+#xpXvPwrYA`{3Jek^1B$SOI){b z)$@t?34HS8cbnpWBit_gT7w`g?lRPaiBVUorje7D+ddb#KnL%DGbKV!T1KgwZu^{T zivRZD4o!5LNR7#NsE2B;8_^R97{cMqn`630wfGt{|D4T33LgQ$)`z*quZZ@e_FB#B+#; zdQ%UM{t`nM{b@(>Z-$zOYwQ~l5_e&EgL+W48VF$=EfX^g2SS*2Tg{EwzW3t46;38l z&=<$~4}2R(c0ca;Ikrf^5DsVdH>^@;K?^U}!ObAl)q{@$04|#i^fS&Bopb_9LGU{6(iP_YR-N$Bum+K^G!W)oM^x88uac zsw*JG=EhJLARq|&hvDPfjYX&6SRXi6@La9wx&~P(qf*NoE2HIQ6e_Dd8`eB4V&CWo zp=nCjO)#dCpb`9`StNS>QyB=XA3PU;z=;sJ0C-M>z>0>&O?uDyB_Ig;hpAicHMN3L zWvy$aGAlF&T2>^~lrm&hLQRn%E9I`0+T36{`yO7O{-=(rxs3#F#lLGb2_iz^M1v@- zK@^VlgIEy6D*`lNhX}f^Laq<2F~AaJ)p+maKzBn~&eqk#-L~)6kznu089cQA_Z=I5 zeFGujS^ql8(Mpt%IO=)dYibpRasskiZVt9FvyH)4T^8r`5*jpIpZgVVE&cC0B6EPT z_I-NtSsWOBWKjLH2VF<4{)4xIAuNtge4;Ppp;`vC?FPTv0vc0~^2 z^7PM}3vEo$7stns|Hv^8XZY@n z(0pyg@iV0b)5EZ7B2!ubAq;j8JqTUbplC7_wR-Qh{(dtWh@D);HW$(J7(pixQXkmH zKsN^2FvRSZt_%8yJtIPY+K%8)h>r)XybQSN+{wIEW^Cz}eal5YMXu5*8?*0PF{4_pz z@DCh^WI49`arLxOs;*%%eGQ5#qpFnf;NDL=E{Cf_$Bp^_#$x&!2w^ZDJLb93xe><1 zafVVgjf+!1b>#NjUd~%gUqiOE*xXZK`vHA)Id$kruB^flvux`yS<4V0^C>>m0+-_Bcd`r9pK-mQy&hj|E2E-qEmc=7s=FqL@O_B|Za z9}*~P6|<{vwCzIj@gY=|B9=1m!d`Gk$5Q59NOG<%izru4U}ohaDzyT=j$6Pk2~=Id z+q1vKt2ckrQ<}eJK7ko@Xh>vlB3E9*SnOEWO&hV`9?uVxELPSqmwK~p(+SIP7>OJN zLs(R51=N%Z!s0G;mIykQ((fW$UIJk3Ca%bNX!^Z1eO0R=TV4Xk3J@utZDa;Q7!<3i zj{6+|V`9GY{@*sGRxfZ&f(8mw5({f@BOabaphJy+mK8ibu~dhS)!a0evo}l@a|lMl z`@wVfY#5{LO9c^ABIsC5zl&U*0DzHL>f=KwS2I{IMRXJ^tEeg^g#06(CY?%huH&&f zi|K24<>rr3v>ChTgq}$N7)2sxSKk1~3Z|uL1YYcUS8g{bY8CTqZy{H1-&+6}X>DfD zuGWbV7I!rzlwOwrtpsR*WjJt*07=f7v{gi2T0y`!d|cAMr$F7Aq;trmjHlu;0iq73_{1 zxsPv5|Fe<$*5P`d6QOD~)2bv5^}sT`C#Rm&)C#ICv4UcC4X?cSV=QIpoz6-v*>5>> z1OIdFFY(CXFJm~g&uE;oduZ$-qFMc;oiJP|r}Js?5sO3|@TqN4UBC zB6R3fMPyB_U^aQ#k^lhdxGk*}a?J>!%%!eiE_DR}x>hU!{`pN}*%WxBy^*4s@f5BOqTOYIrz;e9Nuy|d1}bc$R#f!WnJY!}Gt6`qm6 zFGQefHOwY2_mqH9QzhI@UbeOQ!mtCJY>jK5_1y|vv?3aquvLmCFRkEq59*;2pZ+-KO1OcD1^{cTdbS`zpSSGarL;PQ~bu2xpR~&J&*U&7g=487ZA;j48Xu|-k zDNl``%mFRd#}<7V@Z9e7BB^*(yBk}~vqHPi8)hP!D;{5KE@>^9w&ZUwUe zuPKscWNsrk)@OUE+E5QSF~9b&Hz4!d6?OKa~5oMi8wyOtS*RYhifyMMS(=_%itPadO z-thHjQ*SoaLqST`#eaKLt`j&$z)xjRJL+8V~aQfCwiKf;Ry-+Ld3Jg3#WQ`Bdpay?*%nPA?oRhsh4(vCnWHy!@bV9 zR#>Y8cU4skPo*~r)eT;H2wR2(hHpOUTEbWjv{N^6BM7O-EIg2cjkt>!@P-5)ShIGc zbXMr(9yY)4!A;xGvX_Vsi3-;GB?7~Yo(GwET zWUUdIqm$|_tKHWJ?5rl*K{PN9pTkI|6}FUNXxBZo3nPb*j*his_|Yr5N2p2zqg;FDIbdTzKjREBCN@4J8t2x{7RhkxE+)c;z8bCjo7-rRgfx3bU@P_6GVX z2{OfbD3o^}dlfm{^dta`f$5Z0?5G`!Xki0x-9*4xF?F&IVi#VyiS$X}kri94th)MP zHC;i?Mt+`KH&Ir~$n_8kw}UOC4!rbd-H2E_?qT!V9^FJuSCKBvx+-{Sg{>nAJalC= zT}8Usn|)x%J#1dvqnns1&e_hM>IGg+FsdY=?H-!Jun(Mz+o}!Epm}W%Bq&I$R8!5( z;FX(5HJ`xC)x%a4D=GN+AjA#!hoZ_Yl}1Y~)kaHDY^JLLK)N`GTxkgcAArCHoAsBC zf5Enakd+b@!_^J~!VvWnQ>l`m9|uCnN*U#928rxVjK_`v#25s*R)*>#y?Y~6U4bO$ zA)$SCvxIAsf@L@?Wo|&=LJBDy=lB4n7FGQLI@xo1{N`mF=4J@RuHfOe* zEm%%)C;1ve{y6*|dnOGiN(EDi3smC)ny#Q&NttdrV+aRPh#=^TuPeGi3v@}4d5>mu zwxMbYZY{lp=ya*G8WdZde;7+u&qb{0C$p?AXR(c4&MniMZ(nb1#Hzb z4y>^4NTBHoZY{q=_l#y;$JFu#(^56t0o#rQfKm2sX5}Ka_U6~#MqWx#Yj3k*Tao|( zQiT~LbGKZ#lPfK`DipaDux&{I0C$s@E$bn4gIp_PD&f9T`ew(rCV{4_xV7{Wv|gf< zx{j&D%L6^ovR~NNBmjU)EsxtPuQ|SNE_KB;{=Xfu?MVOtYlXX5$=wS0C!g}+d9Nbu9Yyo;$6+a&4?XC0$tZ|YxyP1lgJv^>;yZY6+4CmfKiqFw#6); zOTFoN;mFO19Yq2FNEhd^oVj80`P{%(K?jW;M*_gG{2S*414ill+lk)}ut$T%jwFGu zYnWO#VgS0X;@0xZ)Hc0tMR=Tnv3XHdO1PbP6#^Huee~^i#s2}S@wjrP;n$V`0000< KMNUMnLSTX)HmZRD literal 0 HcmV?d00001 diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade index b021cb68..3b26c847 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade @@ -3,7 +3,7 @@ div.activity-item div.activity-info div.profile-contact-picture a(tg-nav="user-profile:username=vm.activity.user.username", title="{{::vm.activity.user.name }}") - img(ng-src="{{::vm.activity.user.photo || '/images/unnamed.png'}}", alt="{{::vm.activity.user.name}}") + img(ng-src="{{::vm.activity.user.photo || '/images/user-noimage.png'}}", alt="{{::vm.activity.user.name}}") p(tg-compile-html="vm.activity.title") From 01c8e530263bf2ba6ed1732786e39d970d965f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Fri, 26 Jun 2015 13:10:08 +0200 Subject: [PATCH 039/403] Fix created by section --- app/coffee/modules/common/components.coffee | 10 ++++++---- app/partials/common/components/created-by.jade | 6 ++++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/coffee/modules/common/components.coffee b/app/coffee/modules/common/components.coffee index c96ae3ae..a57a5972 100644 --- a/app/coffee/modules/common/components.coffee +++ b/app/coffee/modules/common/components.coffee @@ -152,7 +152,7 @@ module.directive("tgSprintProgressbar", SprintProgressBarDirective) ## Created-by display directive ############################################################################# -CreatedByDisplayDirective = ($template, $compile, $translate)-> +CreatedByDisplayDirective = ($template, $compile, $translate, $navUrls)-> # Display the owner information (full name and photo) and the date of # creation of an object (like USs, tasks and issues). # @@ -168,13 +168,14 @@ CreatedByDisplayDirective = ($template, $compile, $translate)-> link = ($scope, $el, $attrs) -> render = (model) -> - owner = $scope.usersById?[model.owner] or { + owner = model.owner_extra_info or { full_name_display: $translate.instant("COMMON.EXTERNAL_USER") - photo: "/images/unnamed.png" + photo: "/images/user-noimage.png" } html = template({ owner: owner + url: if owner?.is_active then $navUrls.resolve("user-profile", {username: owner.username}) else "" date: moment(model.created_date).format($translate.instant("COMMON.DATETIME")) }) @@ -194,7 +195,8 @@ CreatedByDisplayDirective = ($template, $compile, $translate)-> require: "ngModel" } -module.directive("tgCreatedByDisplay", ["$tgTemplate", "$compile", "$translate", CreatedByDisplayDirective]) +module.directive("tgCreatedByDisplay", ["$tgTemplate", "$compile", "$translate", "$tgNavUrls", + CreatedByDisplayDirective]) ############################################################################# diff --git a/app/partials/common/components/created-by.jade b/app/partials/common/components/created-by.jade index e9f74f06..03ed8980 100644 --- a/app/partials/common/components/created-by.jade +++ b/app/partials/common/components/created-by.jade @@ -1,7 +1,9 @@ .user-avatar - img(src!="<%- owner.photo %>", alt!="<%- owner.full_name_display %>") + a(href!="<%- url %>", title!="<%- owner.full_name_display %>") + img(src!="<%- owner.photo %>", alt!="<%- owner.full_name_display %>") .created-by - span.created-title(translate="COMMON.CREATED_BY", translate-values!="{ 'fullDisplayName': '<%- owner.full_name_display %>'}") + a(href!="<%- url %>", title!="<%- owner.full_name_display %>") + span.created-title(translate="COMMON.CREATED_BY", translate-values!="{ 'fullDisplayName': '<%- owner.full_name_display %>'}") span.created-date | <%- date %> From 5b692571094e81d3aa9434cf6da8d196845b5d49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Mon, 29 Jun 2015 12:37:18 +0200 Subject: [PATCH 040/403] Issue#2600: Fix history/comment tab buttons --- app/coffee/modules/common/history.coffee | 9 +++++++-- app/partials/common/history/history-base.jade | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index 90bf4521..7f17687d 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -416,8 +416,13 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c $(this).addClass('active') $el.on "click", ".history-tabs li a", (event) -> - $el.find(".history-tabs li a").toggleClass("active") - $el.find(".history section").toggleClass("hidden") + target = angular.element(event.currentTarget) + + $el.find(".history-tabs li a").removeClass("active") + target.addClass("active") + + $el.find(".history section").addClass("hidden") + $el.find(".history section.#{target.data('section-class')}").removeClass("hidden") $el.on "click", ".comment-delete", debounce 2000, (event) -> event.preventDefault() diff --git a/app/partials/common/history/history-base.jade b/app/partials/common/history/history-base.jade index ff6b9052..f9450728 100644 --- a/app/partials/common/history/history-base.jade +++ b/app/partials/common/history/history-base.jade @@ -1,11 +1,11 @@ section.history ul.history-tabs li - a(href="#", class="active") + a(href="#", class="active", data-section-class="history-comments") span.icon.icon-comment span.tab-title(translate="COMMENTS.TITLE") li - a(href="#") + a(href="#", data-section-class="history-activity") span.icon.icon-issues span.tab-title(translate="ACTIVITY.TITLE") section.history-comments From 55a0a5ffed5b15904e699120d14db436292dab89 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 29 Jun 2015 13:57:32 +0200 Subject: [PATCH 041/403] disable projects pagination by default --- app/modules/projects/projects.service.coffee | 4 ++-- app/modules/resources/projects-resource.service.coffee | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/modules/projects/projects.service.coffee b/app/modules/projects/projects.service.coffee index 066352e2..bbedc8c4 100644 --- a/app/modules/projects/projects.service.coffee +++ b/app/modules/projects/projects.service.coffee @@ -14,8 +14,8 @@ class ProjectsService extends taiga.Service getProjectStats: (projectId) -> return @rs.projects.getProjectStats(projectId) - getProjectsByUserId: (userId) -> - return @rs.projects.getProjectsByUserId(userId) + getProjectsByUserId: (userId, paginate) -> + return @rs.projects.getProjectsByUserId(userId, paginate) .then (projects) => return projects.map @._decorate.bind(@) diff --git a/app/modules/resources/projects-resource.service.coffee b/app/modules/resources/projects-resource.service.coffee index 1c46c0a9..806bc550 100644 --- a/app/modules/resources/projects-resource.service.coffee +++ b/app/modules/resources/projects-resource.service.coffee @@ -12,12 +12,18 @@ Resource = (urlsService, http, paginateResponseService) -> .then (result) -> return Immutable.fromJS(result.data) - service.getProjectsByUserId = (userId) -> + service.getProjectsByUserId = (userId, paginate=false) -> url = urlsService.resolve("projects") + httpOptions = {} + + if !paginate + httpOptions.headers = { + "x-disable-pagination": "1" + } params = {"member": userId, "order_by": "memberships__user_order"} - return http.get(url, params) + return http.get(url, params, httpOptions) .then (result) -> return Immutable.fromJS(result.data) From de253d7a2b90a84eb8b98287eb86f2b94d5443ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 29 Jun 2015 14:43:33 +0200 Subject: [PATCH 042/403] [i18n] Update locales --- app/locales/locale-zh-hant.json | 232 ++++++++++++++++---------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 1decf09a..c4d753da 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -100,10 +100,10 @@ "SAT": "週六" } }, - "SEE_USER_PROFILE": "See {{username }} profile", + "SEE_USER_PROFILE": "觀看 {{username }} 個人資訊", "USER_STORY": "使用者故事", - "TASK": "Task", - "ISSUE": "Issue", + "TASK": "任務", + "ISSUE": "問題", "TAGS": { "PLACEHOLDER": "我在這裏,請標注我", "DELETE": "刪除Tag", @@ -239,12 +239,12 @@ }, "META": { "PAGE_TITLE": "Taiga", - "PAGE_DESCRIPTION": "Taiga is a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_DESCRIPTION": "Taiga是一個給新創團隊與敏捷開發者設計師使用的專案管理平台。Taiga是一個簡易輕鬆美觀的工具,讓工作變成樂趣。" } }, "LOGIN": { - "PAGE_TITLE": "Login - Taiga", - "PAGE_DESCRIPTION": "Logging in to Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "登入 - Taiga", + "PAGE_DESCRIPTION": "登入Taig,它是一個給新創團隊與敏捷開發者設計師使用的專案管理平台。Taiga是一個簡易輕鬆美觀的工具,讓工作變成樂趣。" }, "AUTH": { "INVITED_YOU": "已邀請您加入此專案", @@ -266,8 +266,8 @@ "SUCCESS": "我們系統歡迎你加入Taiga" }, "REGISTER": { - "PAGE_TITLE": "Register - Taiga", - "PAGE_DESCRIPTION": "Create your account in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "註冊 - Taiga", + "PAGE_DESCRIPTION": "在Taiga創建一個帳號,它是一個給新創團隊與敏捷開發者設計師使用的專案管理平台。Taiga是一個簡易輕鬆美觀的工具,讓工作變成樂趣。" }, "REGISTER_FORM": { "TITLE": "註冊一個新的Taiga帳戶(免費 )", @@ -280,8 +280,8 @@ "LINK_LOGIN": "你是否已註冊? 登入" }, "FORGOT_PASSWORD": { - "PAGE_TITLE": "Forgot password - Taiga", - "PAGE_DESCRIPTION": "Enter your username or email to get a new password and you can access to Taiga again." + "PAGE_TITLE": "忘記密碼 - Taiga", + "PAGE_DESCRIPTION": "輸入用戶名稍或電子郵件以獲取新密碼,可以再重新登入Taiga權限" }, "FORGOT_PASSWORD_FORM": { "TITLE": "你是否忘了密碼嗎", @@ -293,8 +293,8 @@ "ERROR": "按我們的記錄,你尚未註冊" }, "CHANGE_PASSWORD": { - "PAGE_TITLE": "Change you password - Taiga", - "PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_TITLE": "變更密碼 - Taiga", + "PAGE_DESCRIPTION": "設定Taiga 帳戶密碼! 你也許該吃點鐵質豐富的食物,它對你的大腦有益處:p", "SECTION_NAME": "改變密碼 ", "FIELD_CURRENT_PASSWORD": "現用密碼 ", "PLACEHOLDER_CURRENT_PASSWORD": "你目前的密碼(如果你未有密碼,此處請空白)", @@ -316,8 +316,8 @@ "SUCCESS": "系統已儲存你的新密碼
試試 用它登入 " }, "INVITATION": { - "PAGE_TITLE": "Invitation acceptance - Taiga", - "PAGE_DESCRIPTION": "Accept the invitation to join a project in Taiga, a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable." + "PAGE_TITLE": "接受邀請- Taiga", + "PAGE_DESCRIPTION": "接受邀請加入Taiga上的專案,它是一個給新創團隊與敏捷開發者設計師使用的專案管理平台。Taiga是一個簡易輕鬆美觀的工具,讓工作變成樂趣。" }, "INVITATION_LOGIN_FORM": { "NOT_FOUND": "Ooops, 有點問題
我們的系統無法找到你的邀請信", @@ -325,17 +325,17 @@ "ERROR": "按我們的記錄,你尚未註冊或是未輸入有效的密碼 " }, "HOME": { - "PAGE_TITLE": "Home - Taiga", - "PAGE_DESCRIPTION": "The Taiga home page with your main projects and all your assigned and watched user stories, tasks and issues", - "EMPTY_WATCHING": "Follow the projects, User Stories, Tasks, Issues... that you want to know about :)", - "EMPTY_PROJECT_LIST": "You don't have any projects yet", - "WORKING_ON_SECTION": "Working on", - "WATCHING_SECTION": "Watching" + "PAGE_TITLE": "首頁 - Taiga", + "PAGE_DESCRIPTION": "Taiga 首頁,你的主要專案以及任命,觀看使用者故事,任務與問題。", + "EMPTY_WATCHING": "追踪 專案, 使用者故事, 任務, 問題......任何你想知道的資訊 :)", + "EMPTY_PROJECT_LIST": "你尚無任何專案", + "WORKING_ON_SECTION": "進行中", + "WATCHING_SECTION": "觀看中" }, "PROJECTS": { - "PAGE_TITLE": "My projects - Taiga", - "PAGE_DESCRIPTION": "A list with all your projects, you can reorder or create a new one.", - "MY_PROJECTS": "My projects" + "PAGE_TITLE": "我的專案 - Taiga", + "PAGE_DESCRIPTION": "你的專案列表,你可以記錄或創建新專案。", + "MY_PROJECTS": "我的專案" }, "ATTACHMENT": { "SECTION_NAME": "附件", @@ -374,7 +374,7 @@ }, "MEMBERSHIPS": { "TITLE": "管理成員", - "PAGE_TITLE": "Memberships - {{projectName}}", + "PAGE_TITLE": "成員資格 - {{projectName}}", "ADD_BUTTON": "+ 新成員", "ADD_BUTTON_TITLE": "增加新成員" }, @@ -451,14 +451,14 @@ "ISSUE_ADD": "在問題中加入客制欄位" }, "PROJECT_VALUES": { - "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - 專案數值 - {{projectName}}", "REPLACEMENT": "所有此數值物品將改成", "ERROR_DELETE_ALL": "你不能刪除所有數值" }, "PROJECT_VALUES_POINTS": { "TITLE": "點數", "SUBTITLE": "指定你的使用者故事點數可能預估為", - "US_TITLE": "US points", + "US_TITLE": "使用者故事點數", "ACTION_ADD": "增加點數" }, "PROJECT_VALUES_PRIORITIES": { @@ -543,7 +543,7 @@ "WEBHOOK_NAME": "網頁觸發 '{{name}}'" }, "CUSTOM_ATTRIBUTES": { - "PAGE_TITLE": "{{sectionName}} - Custom Attributes - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - 個人化屬性 - {{projectName}}", "ADD": "加入客製化欄位", "EDIT": "編輯客製化欄位", "DELETE": "刪除客製欄位", @@ -624,32 +624,32 @@ "USER": { "PROFILE": { "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", - "EDIT": "Edit profile", - "FOLLOW": "Follow", + "EDIT": "編輯個人資料", + "FOLLOW": "追踪", "PROJECTS": "專案", - "CLOSED_US": "Closed US", - "CONTACTS": "Contacts", - "REPORT": "Report Abuse", - "ACTIVITY_TAB": "Activity Tab", - "PROJECTS_TAB": "Projects Tab", - "CONTACTS_TAB": "Contacts Tab", - "FAVORITES_TAB": "Favorites Tab", - "CONTACTS_EMPTY": "{{username}} doesn't have contacts yet", - "CURRENT_USER_CONTACTS_EMPTY": "You don't have contacts yet", - "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "The people with whom you work at Taiga will be your contacts automatically", - "PROJECTS_EMPTY": "{{username}} doesn't' have projects yet" + "CLOSED_US": "閞閉使用者故事", + "CONTACTS": "聯絡人", + "REPORT": "回報濫用", + "ACTIVITY_TAB": "活動分頁", + "PROJECTS_TAB": "專案分頁", + "CONTACTS_TAB": "聯絡人分頁", + "FAVORITES_TAB": "快速分頁", + "CONTACTS_EMPTY": "{{username}} 尚無聯絡人", + "CURRENT_USER_CONTACTS_EMPTY": "您尚無任何聯絡人", + "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "你在Taiga一同工作的伙伴將自動成為你的聯絡人", + "PROJECTS_EMPTY": "{{username}} 尚無專案" }, "PROFILE_SIDEBAR": { - "TITLE": "Your profile", - "DESCRIPTION": "People can see everything you do and what are you working on. Add a nice bio to give an enhanced version of your information.", - "ADD_INFO": "Edit your bio" + "TITLE": "個人資訊", + "DESCRIPTION": "人們可以看到你做的成果以及其進度。加入一段描述介紹以強化你的資料。", + "ADD_INFO": "編輯個人介紹" } }, "PROJECT": { "PAGE_TITLE": "{{projectName}}", "WELCOME": "歡迎", "SECTION_PROJECTS": "專案", - "HELP": "Reorder your projects to set in the top the most used ones.
The top 10 projects will appear in the top navigation bar project list", + "HELP": "記錄你的專案在上方常用欄位
前十個專案將會顯示在上方導覽處。", "PRIVATE": "不公開專案", "STATS": { "PROJECT": "專案
點數", @@ -659,7 +659,7 @@ }, "SECTION": { "SEARCH": "搜尋", - "TIMELINE": "Timeline", + "TIMELINE": "時間表", "BACKLOG": "待辦任務優先表", "KANBAN": "Kanban(看板)", "ISSUES": "問題 ", @@ -673,31 +673,31 @@ "PLACEHOLDER_SEARCH": "搜尋", "ACTION_CREATE_PROJECT": "創建專案", "ACTION_IMPORT_PROJECT": "滙入專案", - "SEE_MORE_PROJECTS": "See more projects", + "SEE_MORE_PROJECTS": "觀看更多專案", "TITLE_CREATE_PROJECT": "創建專案", "TITLE_IMPORT_PROJECT": "滙入專案", "TITLE_PRVIOUS_PROJECT": "顯示過去專案", "TITLE_NEXT_PROJECT": "顯示下一個任務", - "HELP_TITLE": "Taiga Support Page", - "HELP": "Help", + "HELP_TITLE": "Taiga支援頁", + "HELP": "幫助", "FEEDBACK_TITLE": "送出回饋 ", "FEEDBACK": "回饋 ", - "NOTIFICATIONS_TITLE": "Edit your notification settings", + "NOTIFICATIONS_TITLE": "編輯個人通知設定", "NOTIFICATIONS": "通知", - "ORGANIZATIONS_TITLE": "Edit your organizations", - "ORGANIZATIONS": "Edit organizations", - "SETTINGS_TITLE": "Edit your settings", - "SETTINGS": "Settings", - "VIEW_PROFILE_TITLE": "View Profile", - "VIEW_PROFILE": "View Profile", - "EDIT_PROFILE_TITLE": "Edit your profile", - "EDIT_PROFILE": "Edit Profile", + "ORGANIZATIONS_TITLE": "編輯您的組織資料", + "ORGANIZATIONS": "編輯組織資料", + "SETTINGS_TITLE": "編輯個人設定", + "SETTINGS": "設定", + "VIEW_PROFILE_TITLE": "檢視個人資料", + "VIEW_PROFILE": "檢視個人資料", + "EDIT_PROFILE_TITLE": "編輯你的個人資料", + "EDIT_PROFILE": "編輯個人資料", "CHANGE_PASSWORD_TITLE": "更換密碼 ", "CHANGE_PASSWORD": "更換密碼 ", - "DASHBOARD_TITLE": "Dashboard", - "DISCOVER_TITLE": "Discover trending projects", - "DISCOVER": "Discover", - "ACTION_REORDER": "Drag & drop to reorder" + "DASHBOARD_TITLE": "控制台", + "DISCOVER_TITLE": "發現流行專案", + "DISCOVER": "發現", + "ACTION_REORDER": "拖移 & 丟到來記錄" }, "IMPORT": { "TITLE": "滙入專案中", @@ -778,8 +778,8 @@ } }, "US": { - "PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Completed {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). Points: {{userStoryPoints}}. Description: {{userStoryDescription}}", + "PAGE_TITLE": "{{userStorySubject}} - 使用者故事 {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "狀態: {{userStoryStatus }}.已完成 {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). 點數: {{userStoryPoints}}. 描述: {{userStoryDescription}}", "SECTION_NAME": "使用者故事細節", "LINK_TASKBOARD": "任務板", "TITLE_LINK_TASKBOARD": "到任務板去", @@ -867,8 +867,8 @@ } }, "BACKLOG": { - "PAGE_TITLE": "Backlog - {{projectName}}", - "PAGE_DESCRIPTION": "The backlog panel, with user stories and sprints of the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "待辦任務優先表 - {{projectName}}", + "PAGE_DESCRIPTION": "待辦任務優先表面板 {{projectName}}(專案的使用者故事與衝刺任務): {{projectDescription}}", "SECTION_NAME": "待辦任務優先表", "MOVE_US_TO_CURRENT_SPRINT": "移到目前的 Sprint", "SHOW_FILTERS": "顯示過濾器", @@ -948,8 +948,8 @@ "VERSION_ERROR": "Taiga某人之前更改了這個,而我們的工程師無法再做改變。請重新載入頁面來使用你的更新(之前設定將消失)" }, "TASKBOARD": { - "PAGE_TITLE": "{{sprintName}} - Sprint taskboard - {{projectName}}", - "PAGE_DESCRIPTION": "Sprint {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. Completed {{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} opened tasks of {{totalTasks}}.", + "PAGE_TITLE": "{{sprintName}} - 衝刺任務看板 - {{projectName}}", + "PAGE_DESCRIPTION": "衝刺任務 {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. 完成{{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} 開啟任務 {{totalTasks}}.", "SECTION_NAME": "任務板", "TITLE_ACTION_ADD": "增加新任務 ", "TITLE_ACTION_ADD_BULK": "批次加入新任務 ", @@ -973,8 +973,8 @@ } }, "TASK": { - "PAGE_TITLE": "{{taskSubject}} - Task {{taskRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{taskStatus }}. Description: {{taskDescription}}", + "PAGE_TITLE": "{{taskSubject}} - 任務 {{taskRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "狀態: {{taskStatus }}.描述: {{taskDescription}}", "SECTION_NAME": "任務細節", "LINK_TASKBOARD": "任務板", "TITLE_LINK_TASKBOARD": "到任務板去", @@ -1021,8 +1021,8 @@ "SUCCESS": "我們系統已更新你的電子郵件" }, "ISSUES": { - "PAGE_TITLE": "Issues - {{projectName}}", - "PAGE_DESCRIPTION": "The issues list panel of the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "問題 - {{projectName}}", + "PAGE_DESCRIPTION": " {{projectName}}的問題清單看版: {{projectDescription}}", "LIST_SECTION_NAME": "問題 ", "SECTION_NAME": "問題細節", "ACTION_NEW_ISSUE": "+ 新問題 ", @@ -1087,12 +1087,12 @@ } }, "ISSUE": { - "PAGE_TITLE": "{{issueSubject}} - Issue {{issueRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priority: {{issuePriority}}. Severity: {{issueSeverity}}. Description: {{issueDescription}}" + "PAGE_TITLE": "{{issueSubject}} - 問題 {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "狀態: {{issueStatus }}. 類型: {{issueType}}, 優先性: {{issuePriority}}. 急迫性: {{issueSeverity}}. Description: {{issueDescription}}" }, "KANBAN": { - "PAGE_TITLE": "Kanban - {{projectName}}", - "PAGE_DESCRIPTION": "The kanban panel, with user stories of the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "看板 - {{projectName}}", + "PAGE_DESCRIPTION": "看板面板 上有專案的使用者故事 {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Kanban(看板)", "TITLE_ACTION_FOLD": "隱藏欄位", "TITLE_ACTION_UNFOLD": "未隱藏欄位", @@ -1107,8 +1107,8 @@ "UNDO_ARCHIVED": "拖移 & 丟到未做" }, "SEARCH": { - "PAGE_TITLE": "Search - {{projectName}}", - "PAGE_DESCRIPTION": "Search anything, user stories, issues, tasks or wiki pages, in the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "搜尋 - {{projectName}}", + "PAGE_DESCRIPTION": "專案搜尋(使用者故事, 問題, 任務或維基頁等資訊) {{projectName}}: {{projectDescription}}", "FILTER_USER_STORIES": "使用者故事", "FILTER_ISSUES": "問題 ", "FILTER_TASKS": "任務 ", @@ -1119,8 +1119,8 @@ "EMPTY_DESCRIPTION": "請試試上方某一個分頁或再搜尋一次" }, "TEAM": { - "PAGE_TITLE": "Team - {{projectName}}", - "PAGE_DESCRIPTION": "The team panel to show all the members of the project {{projectName}}: {{projectDescription}}", + "PAGE_TITLE": "團隊- {{projectName}}", + "PAGE_DESCRIPTION": "團隊面版可顯示專案中所有成員{{projectName}}: {{projectDescription}}", "SECTION_NAME": "團隊", "APP_TITLE": "團隊- {{projectName}}", "PLACEHOLDER_INPUT_SEARCH": "以全名搜尋", @@ -1179,7 +1179,7 @@ "EMAIL": "電子郵件", "FULL_NAME": "全名", "PLACEHOLDER_FULL_NAME": "你的全名", - "BIO": "Bio (max. 210 chars)", + "BIO": "自介(最多210字)", "PLACEHOLDER_BIO": "請自我介紹", "LANGUAGE": "語言", "LANGUAGE_DEFAULT": "-- 使用設預語言 -- " @@ -1194,8 +1194,8 @@ "PROGRESS_NAME_DESCRIPTION": "名稱與描述" }, "WIKI": { - "PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}", - "PAGE_DESCRIPTION": "Last edition on {{lastModifiedDate}} ({{totalEditions}} editions in total) Content: {{ wikiPageContent }}", + "PAGE_TITLE": "{{wikiPageName}} - 維基 - {{projectName}}", + "PAGE_DESCRIPTION": "上回編輯{{lastModifiedDate}} ({{totalEditions}} editions in total) 內容: {{ wikiPageContent }}", "DATETIME": "DD MMM YYYY HH:mm", "PLACEHOLDER_PAGE": "編寫你的維基頁", "REMOVE": "移除此維基頁 ", @@ -1211,41 +1211,41 @@ } }, "HINTS": { - "SECTION_NAME": "Hint", - "LINK": "If you want to know how to use it visit our support page", - "LINK_TITLE": "Visit our support page", - "HINT1_TITLE": "Did you know you can import and export projects?", - "HINT1_TEXT": "This allow you to extract all your data from one Taiga and move it to another one.", - "HINT2_TITLE": "Did you know you can create custom fields?", - "HINT2_TEXT": "Teams can now create custom fields as a flexible means to enter specific data useful for their particular workflow", - "HINT3_TITLE": "Reorder your projects to feature those most relevant to you", - "HINT3_TEXT": "The top 10 project will be in your top bar direct access", - "HINT4_TITLE": "Did you forgot what were you working on?", - "HINT4_TEXT": "Don't worry, on your dashboard you'll find your open tasks, issues, and user stories in the order you worked on them." + "SECTION_NAME": "提示", + "LINK": "如果想知道如何使用,可以到我們的支援頁面了解詳情。", + "LINK_TITLE": "造訪我們的支援頁面", + "HINT1_TITLE": "你知道可以滙入與滙出專案嗎?", + "HINT1_TEXT": "可以從 Taiga提取所有個人資料記錄,移入其它地方。", + "HINT2_TITLE": "你知道可以創建個人化欄位嗎", + "HINT2_TEXT": "團隊可以創建客製欄位,以彈性的方式來輸入特殊資料,有利於其特別的工作流程需求。", + "HINT3_TITLE": "記錄你的專案並突顯其中最相關者", + "HINT3_TEXT": "前十個專案將展示在你的上方欄位以便直接連結。", + "HINT4_TITLE": "你是否曾忘了自己要做什麼?", + "HINT4_TEXT": "別憺心,在控制台可以找到你的公開任務、問題以及使用者故事的工作次序。" }, "TIMELINE": { - "UPLOAD_ATTACHMENT": "{{username}} has uploaded a new attachment in {{obj_name}}", - "US_CREATED": "{{username}} has created a new US {{obj_name}} in {{project_name}}", - "ISSUE_CREATED": "{{username}} has created a new issue {{obj_name}} in {{project_name}}", - "TASK_CREATED": "{{username}} has created a new task {{obj_name}} in {{project_name}}", - "TASK_CREATED_WITH_US": "{{username}} has created a new task {{obj_name}} in {{project_name}} which belongs to the US {{us_name}}", - "WIKI_CREATED": "{{username}} has created a new wiki page {{obj_name}} in {{project_name}}", - "MILESTONE_CREATED": "{{username}} has created a new sprint {{obj_name}} in {{project_name}}", - "NEW_PROJECT": "{{username}} created the project {{project_name}}", - "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", - "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", - "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}}", - "TASK_UPDATED_WITH_US": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}}", - "WIKI_UPDATED": "{{username}} has updated the wiki page {{obj_name}}", - "NEW_COMMENT_US": "{{username}} has commented in the US {{obj_name}}", - "NEW_COMMENT_ISSUE": "{{username}} has commented in the issue {{obj_name}}", - "NEW_COMMENT_TASK": "{{username}} has commented in the task {{obj_name}}", - "NEW_MEMBER": "{{project_name}} has a new member", - "US_ADDED_MILESTONE": "{{username}} has added the US {{obj_name}} to {{sprint_name}}", - "US_REMOVED_FROM_MILESTONE": "{{username}} has added the US {{obj_name}} to the backlog", - "BLOCKED": "{{username}} has blocked {{obj_name}}", - "UNBLOCKED": "{{username}} has unblocked {{obj_name}}", - "NEW_USER": "{{username}} has joined Taiga" + "UPLOAD_ATTACHMENT": "{{username}} 上傳新附件檔案 {{obj_name}}", + "US_CREATED": "{{username}} 創建新的使用者故事 {{obj_name}} 於 {{project_name}}", + "ISSUE_CREATED": "{{username}} 提出了新問題 {{obj_name}} in {{project_name}}", + "TASK_CREATED": "{{username}} 創建新任務 {{obj_name}} 於 {{project_name}}", + "TASK_CREATED_WITH_US": "{{username}} 創建新任務 {{obj_name}} 於 {{project_name}} ,其為{{us_name}}之使用者故事", + "WIKI_CREATED": "{{username}} 創建新維基頁 {{obj_name}} 於 {{project_name}}", + "MILESTONE_CREATED": "{{username}} 創建新衝刺任務 {{obj_name}} 於 {{project_name}}", + "NEW_PROJECT": "{{username}} 創建專案 {{project_name}}", + "MILESTONE_UPDATED": "{{username}}更新衝刺任務 {{obj_name}} ", + "US_UPDATED": "{{username}} 已更新 {{obj_name}}使用者故事之 \"{{field_name}}\"屬性。", + "ISSUE_UPDATED": "{{username}} 更新了{{obj_name}}問題的 \"{{field_name}}\" 屬性", + "TASK_UPDATED": "{{username}}更新了任務 {{obj_name}}之 \"{{field_name}}\" 屬性", + "TASK_UPDATED_WITH_US": "{{username}} 更新了 {{obj_name}} 任務之\"{{field_name}}\" 屬性,其為 {{us_name}} 之使用者故事", + "WIKI_UPDATED": "\n{{username}} 更新了維基頁{{obj_name}}", + "NEW_COMMENT_US": "{{username}} 評論了 {{obj_name}}使用者故事", + "NEW_COMMENT_ISSUE": "{{username}}評論了此問題 {{obj_name}}", + "NEW_COMMENT_TASK": "{{username}} 評論了此任務{{obj_name}}", + "NEW_MEMBER": "{{project_name}} 有新成員", + "US_ADDED_MILESTONE": "{{username}} 增加使用者故事 {{obj_name}} 給 {{sprint_name}}", + "US_REMOVED_FROM_MILESTONE": "{{username}} 新增使用者故事 {{obj_name}} 到待辦工作優先列表", + "BLOCKED": "{{username}} 封鎖了 {{obj_name}}", + "UNBLOCKED": "{{username}} 解除了封鎖 {{obj_name}}", + "NEW_USER": "{{username}} 已加入 Taiga" } } \ No newline at end of file From 16993004f2fb4142ab8ff1f2256253ebcf5d5b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Wed, 1 Jul 2015 10:03:36 +0200 Subject: [PATCH 043/403] Issue#2993: Fix problem when upload a 0-bytes file --- app/coffee/modules/resources/attachments.coffee | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/coffee/modules/resources/attachments.coffee b/app/coffee/modules/resources/attachments.coffee index 327d10a4..af639ccd 100644 --- a/app/coffee/modules/resources/attachments.coffee +++ b/app/coffee/modules/resources/attachments.coffee @@ -48,6 +48,8 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> defered.reject(response) return defered.promise + xhr = new XMLHttpRequest() + uploadProgress = (evt) => $rootScope.$apply => file.status = "in-progress" @@ -64,7 +66,14 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> data = {} model = $model.make_model(urlName, data) - defered.resolve(model) + if xhr.status >= 200 and xhr.status < 400 + defered.resolve(model) + else + response = { + status: xhr.status, + data: {_error_message: JSON.parse(xhr.response)['attached_file']?[0]} + } + defered.reject(response) uploadFailed = (evt) => $rootScope.$apply -> @@ -76,7 +85,6 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> 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) From e2b6e6d481127788b6ea7937d640ca243dda1e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Wed, 1 Jul 2015 10:50:51 +0200 Subject: [PATCH 044/403] Issue#2994: genreate valid jitsi urls --- .../components/project-menu/project-menu.controller.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/modules/components/project-menu/project-menu.controller.coffee b/app/modules/components/project-menu/project-menu.controller.coffee index 665df226..335ce2dc 100644 --- a/app/modules/components/project-menu/project-menu.controller.coffee +++ b/app/modules/components/project-menu/project-menu.controller.coffee @@ -81,6 +81,9 @@ class ProjectMenuController baseUrl = "https://talky.io/" else if @.project.get("videoconferences") == "jitsi" baseUrl = "https://meet.jit.si/" + url = @.project.get("slug") + "-" + taiga.slugify(@.project.get("videoconferences_salt")) + url = url.replace(/-/g, "") + return baseUrl + url else return "" From e2b527bf11960493a9513fc8055b3ead50a4ce0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Wed, 1 Jul 2015 16:12:34 +0200 Subject: [PATCH 045/403] An small refactor --- app/coffee/modules/resources/attachments.coffee | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/coffee/modules/resources/attachments.coffee b/app/coffee/modules/resources/attachments.coffee index af639ccd..ef30ebd5 100644 --- a/app/coffee/modules/resources/attachments.coffee +++ b/app/coffee/modules/resources/attachments.coffee @@ -48,8 +48,6 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> defered.reject(response) return defered.promise - xhr = new XMLHttpRequest() - uploadProgress = (evt) => $rootScope.$apply => file.status = "in-progress" @@ -60,18 +58,20 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> uploadComplete = (evt) => $rootScope.$apply -> file.status = "done" + + status = evt.target.status try data = JSON.parse(evt.target.responseText) catch data = {} - model = $model.make_model(urlName, data) - if xhr.status >= 200 and xhr.status < 400 + if status >= 200 and status < 400 + model = $model.make_model(urlName, data) defered.resolve(model) else response = { - status: xhr.status, - data: {_error_message: JSON.parse(xhr.response)['attached_file']?[0]} + status: status, + data: {_error_message: data['attached_file']?[0]} } defered.reject(response) @@ -85,6 +85,7 @@ resourceProvider = ($rootScope, $config, $urls, $model, $repo, $auth, $q) -> 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) From ac3c116754b995354f425f0ce80eac5c7718c6ed Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 2 Jul 2015 09:09:51 +0200 Subject: [PATCH 046/403] fix issue #2956 - fix infinite loading spinner in the contacts tab with anonymous users --- .../profile-contacts/profile-contacts.controller.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/modules/profile/profile-contacts/profile-contacts.controller.coffee b/app/modules/profile/profile-contacts/profile-contacts.controller.coffee index cae24b1c..b06f4768 100644 --- a/app/modules/profile/profile-contacts/profile-contacts.controller.coffee +++ b/app/modules/profile/profile-contacts/profile-contacts.controller.coffee @@ -5,15 +5,14 @@ class ProfileContactsController ] constructor: (@userService, @currentUserService) -> - - loadContacts: () -> @.currentUser = @currentUserService.getUser() @.isCurrentUser = false - if @.currentUser.get("id") == @.user.get("id") + if @.currentUser && @.currentUser.get("id") == @.user.get("id") @.isCurrentUser = true + loadContacts: () -> @userService.getContacts(@.user.get("id")) .then (contacts) => @.contacts = contacts From 8fa46c0ec4861c02015f583c9e6281982cfa25d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 2 Jul 2015 11:42:33 +0200 Subject: [PATCH 047/403] [i18n] Update locales --- app/locales/locale-fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 0a965d76..2ddd3a25 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -1024,7 +1024,7 @@ "PAGE_TITLE": "Problèmes - {{projectName}}", "PAGE_DESCRIPTION": "Le panneau de la liste des problèmes du projet {{projectName}} : {{projectDescription}}", "LIST_SECTION_NAME": "Problèmes", - "SECTION_NAME": "Detalhes do problema", + "SECTION_NAME": "Détails du problème", "ACTION_NEW_ISSUE": "+ NOUVEAU PROBLÈME", "ACTION_PROMOTE_TO_US": "Transformer en User Story", "PLACEHOLDER_FILTER_NAME": "Écrivez le nom du filtre et appuyez sur \"Entrée\"", From 56854504235422f7fcc6a173dc6133b1fd4cabd4 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 2 Jul 2015 14:42:04 +0200 Subject: [PATCH 048/403] add missing li --- .../dropdown-project-list/dropdown-project-list.jade | 5 ++--- app/modules/projects/project/project.jade | 4 ++-- app/styles/modules/home-project.scss | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade index 37b5800d..234a4ba2 100644 --- a/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade +++ b/app/modules/navigation-bar/dropdown-project-list/dropdown-project-list.jade @@ -3,9 +3,8 @@ a(href="", title="Projects", tg-nav="projects") div.navbar-dropdown.dropdown-project-list ul - a(href="#", - tg-repeat="project in vm.projects track by project.get('id')", - tg-nav="project:project=project.get('slug')") {{::project.get("name")}} + li(tg-repeat="project in vm.projects track by project.get('id')") + a(href="#", tg-nav="project:project=project.get('slug')") {{::project.get("name")}} a.see-more-projects-btn.button-gray( href="#", diff --git a/app/modules/projects/project/project.jade b/app/modules/projects/project/project.jade index 24017598..64f69b1a 100644 --- a/app/modules/projects/project/project.jade +++ b/app/modules/projects/project/project.jade @@ -19,8 +19,8 @@ div.wrapper section.involved-data h2.title {{"PROJECT.SECTION.TEAM" | translate}} ul.involved-team - a(tg-repeat="member in ::vm.project.get('members')", - tg-nav="user-profile:username=member.get('username')", + li(tg-repeat="member in ::vm.project.get('members')") + a(tg-nav="user-profile:username=member.get('username')", title="{{::member.get('full_name')}}") img(ng-src="{{::member.get('photo')}}", alt="{{::member.get('full_name')}}") diff --git a/app/styles/modules/home-project.scss b/app/styles/modules/home-project.scss index 233e2170..a2b8c816 100644 --- a/app/styles/modules/home-project.scss +++ b/app/styles/modules/home-project.scss @@ -51,6 +51,8 @@ margin-bottom: 1rem; a { display: block; + } + li { margin-right: .14rem; width: 24%; &:nth-child(4n) { From cea5ed0e731c62b22c801006b28c4867dddb8bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Mon, 29 Jun 2015 16:06:16 +0200 Subject: [PATCH 049/403] Issue#2884: Crop images for the timeline --- .../user-timeline-attachment-image.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade index 6a5c2c16..d82cc411 100644 --- a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade +++ b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade @@ -2,4 +2,4 @@ div.activity-image-attachment blockquote a(href="{{::attachment.url}}", title="See {{::attachment.filename}}", target="_blank") - img(ng-src="{{::attachment.url}}", alt="{{::attachment.filename}}") + img(ng-src="{{::attachment.thumb_url || attachment.url}}", alt="{{::attachment.filename}}") From b45cf0a14dfb50d4534922fb9d6677eb5817f737 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 2 Jul 2015 18:24:10 +0200 Subject: [PATCH 050/403] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e1bc71d..d82d87ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool)) ### Misc +- Improve performance: Show cropped images in timelines. - Lots of small and not so small bugfixes. From d6bfc7370868fecb855ac41374516a3c41a5fcf4 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 2 Jul 2015 09:22:39 +0200 Subject: [PATCH 051/403] update watchers after new comment --- app/coffee/modules/common/history.coffee | 6 ++++-- app/coffee/modules/issues/detail.coffee | 3 +++ app/coffee/modules/tasks/detail.coffee | 2 ++ app/coffee/modules/userstories/detail.coffee | 3 +++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index 7f17687d..d056cc6c 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -68,7 +68,7 @@ class HistoryController extends taiga.Controller return @rs.history.undeleteComment(type, objectId, activityId).then => @.loadHistory(type, objectId) -HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $compile, $navUrls) -> +HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $compile, $navUrls, $rootScope) -> templateChangeDiff = $template.get("common/history/history-change-diff.html", true) templateChangePoints = $template.get("common/history/history-change-points.html", true) templateChangeGeneric = $template.get("common/history/history-change-generic.html", true) @@ -348,6 +348,8 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c $el.find(".comment-list").addClass("activeanimation") onSuccess = -> + $rootScope.$broadcast("comment:new") + $ctrl.loadHistory(type, objectId).finally -> $loading.finish(target) @@ -456,4 +458,4 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c module.directive("tgHistory", ["$log", "$tgLoading", "$tgQqueue", "$tgTemplate", "$tgConfirm", "$translate", - "$compile", "$tgNavUrls", HistoryDirective]) + "$compile", "$tgNavUrls", "$rootScope", HistoryDirective]) diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index 7fd33d1a..6dda40b4 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -97,6 +97,9 @@ class IssueDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @rootscope.$broadcast("object:updated") @.loadIssue() + @scope.$on "comment:new", => + @.loadIssue() + @scope.$on "custom-attributes-values:edit", => @rootscope.$broadcast("object:updated") diff --git a/app/coffee/modules/tasks/detail.coffee b/app/coffee/modules/tasks/detail.coffee index 5188f767..d9864bbf 100644 --- a/app/coffee/modules/tasks/detail.coffee +++ b/app/coffee/modules/tasks/detail.coffee @@ -84,6 +84,8 @@ class TaskDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @rootscope.$broadcast("object:updated") @scope.$on "custom-attributes-values:edit", => @rootscope.$broadcast("object:updated") + @scope.$on "comment:new", => + @.loadTask() initializeOnDeleteGoToUrl: -> ctx = {project: @scope.project.slug} diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 4e0725e8..c4a5dfa7 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -103,6 +103,9 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) @scope.$on "custom-attributes-values:edit", => @rootscope.$broadcast("object:updated") + @scope.$on "comment:new", => + @.loadUs() + initializeOnDeleteGoToUrl: -> ctx = {project: @scope.project.slug} @scope.onDeleteGoToUrl = @navUrls.resolve("project", ctx) From e4bb92c7a7cf4d0a9f208b30d9e559eb96b2b0e8 Mon Sep 17 00:00:00 2001 From: Julien Dubois Date: Thu, 18 Jun 2015 13:47:55 +0200 Subject: [PATCH 052/403] Fix typo --- app/locales/locale-en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index 7bee2fed..ff9c64ef 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Change you password - Taiga", - "PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Change password", "FIELD_CURRENT_PASSWORD": "Current password", "PLACEHOLDER_CURRENT_PASSWORD": "Your current password (or empty if you have no password yet)", From 13b23197b8bed91570a0a1617cac87f005a66f71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Wed, 1 Jul 2015 11:12:45 +0200 Subject: [PATCH 053/403] Issue#2995: Add custom video conference system --- CHANGELOG.md | 1 + app/coffee/modules/admin/project-profile.coffee | 5 +++-- app/locales/locale-en.json | 7 ++++++- .../project-menu/project-menu.controller.coffee | 8 +++++--- .../project-menu/project-menu.controller.spec.coffee | 2 +- app/partials/admin/admin-project-modules.jade | 12 ++++++++++-- 6 files changed, 26 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d82d87ba..1f1b6e58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features - Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool)) +- Add custom videoconference system. ### Misc - Improve performance: Show cropped images in timelines. diff --git a/app/coffee/modules/admin/project-profile.coffee b/app/coffee/modules/admin/project-profile.coffee index 9c6acc07..97e9d1ac 100644 --- a/app/coffee/modules/admin/project-profile.coffee +++ b/app/coffee/modules/admin/project-profile.coffee @@ -189,9 +189,10 @@ module.directive("tgProjectDefaultValues", ["$tgRepo", "$tgConfirm", "$tgLoading ProjectModulesDirective = ($repo, $confirm, $loading, projectService) -> link = ($scope, $el, $attrs) -> - form = $el.find("form").checksley() submit = => + form = $el.find("form").checksley() return if not form.validate() + target = angular.element(".admin-functionalities a.button-green") $loading.start(target) @@ -221,7 +222,7 @@ ProjectModulesDirective = ($repo, $confirm, $loading, projectService) -> else $el.find(".videoconference-attributes").addClass("hidden") $scope.project.videoconferences = null - $scope.project.videoconferences_salt = "" + $scope.project.videoconferences_extra_data = "" $scope.$watch "project", (project) -> if project.videoconferences? diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index ff9c64ef..e9a008c2 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -407,7 +407,12 @@ "MEETUP": "Meet Up", "MEETUP_DESCRIPTION": "Choose your videoconference system. Even developers need face to face contact.", "SELECT_VIDEOCONFERENCE": "Select a videoconference system", - "SALT_CHAT_ROOM": "If you want you can append a salt code to the name of the chat room" + "SALT_CHAT_ROOM": "If you want you can append a salt code to the name of the chat room", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Project profile - {{projectName}}", diff --git a/app/modules/components/project-menu/project-menu.controller.coffee b/app/modules/components/project-menu/project-menu.controller.coffee index 335ce2dc..fd8ae203 100644 --- a/app/modules/components/project-menu/project-menu.controller.coffee +++ b/app/modules/components/project-menu/project-menu.controller.coffee @@ -81,14 +81,16 @@ class ProjectMenuController baseUrl = "https://talky.io/" else if @.project.get("videoconferences") == "jitsi" baseUrl = "https://meet.jit.si/" - url = @.project.get("slug") + "-" + taiga.slugify(@.project.get("videoconferences_salt")) + url = @.project.get("slug") + "-" + taiga.slugify(@.project.get("videoconferences_extra_data")) url = url.replace(/-/g, "") return baseUrl + url + else if @.project.get("videoconferences") == "custom" + return @.project.get("videoconferences_extra_data") else return "" - if @.project.get("videoconferences_salt") - url = @.project.get("slug") + "-" + @.project.get("videoconferences_salt") + if @.project.get("videoconferences_extra_data") + url = @.project.get("slug") + "-" + @.project.get("videoconferences_extra_data") else url = @.project.get("slug") diff --git a/app/modules/components/project-menu/project-menu.controller.spec.coffee b/app/modules/components/project-menu/project-menu.controller.spec.coffee index 89f1f650..fb9cdf36 100644 --- a/app/modules/components/project-menu/project-menu.controller.spec.coffee +++ b/app/modules/components/project-menu/project-menu.controller.spec.coffee @@ -63,7 +63,7 @@ describe "ProjectMenu", -> it "videoconference url", () -> project = Immutable.fromJS({ "videoconferences": "appear-in", - "videoconferences_salt": "123", + "videoconferences_extra_data": "123", "slug": "project-slug" }) diff --git a/app/partials/admin/admin-project-modules.jade b/app/partials/admin/admin-project-modules.jade index 5cb45cd3..babcac99 100644 --- a/app/partials/admin/admin-project-modules.jade +++ b/app/partials/admin/admin-project-modules.jade @@ -86,8 +86,16 @@ div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl" div.videoconference-attributes.hidden select(ng-model="project.videoconferences", - ng-options="e.id as e.name for e in [{'id':'appear-in', 'name':'AppearIn'},{'id':'jitsi', 'name': 'Jitsi'},{'id':'talky', 'name': 'Talky'}]") + ng-options="e.id as e.name|translate for e in [{'id':'appear-in', 'name':'ADMIN.MODULES.APPEARIN_CHAT_ROOM'},{'id':'jitsi', 'name': 'ADMIN.MODULES.JITSI_CHAT_ROOM'},{'id':'talky', 'name': 'ADMIN.MODULES.TALKY_CHAT_ROOM'},{'id':'custom', 'name': 'ADMIN.MODULES.CUSTOM_CHAT_ROOM'}]") option(value="", translate="ADMIN.MODULES.SELECT_VIDEOCONFERENCE") - input(type="text", ng-model="project.videoconferences_salt", + input(ng-if="project.videoconferences && project.videoconferences != 'custom'", + type="text", + ng-model="project.videoconferences_extra_data", + data-maxlength="255", placeholder="{{'ADMIN.MODULES.SALT_CHAT_ROOM' | translate}}") + input(ng-if="project.videoconferences == 'custom'", + type="text", + ng-model="project.videoconferences_extra_data", + data-maxlength="255", + placeholder="{{'ADMIN.MODULES.URL_CHAT_ROOM' | translate}}") button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE") From 1be8bf2b435cd11550a30ac17aed7240b0278c4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sun, 5 Jul 2015 11:21:44 +0200 Subject: [PATCH 054/403] [i18n] Update locales --- app/locales/locale-ca.json | 27 +++++++++++++++++++-------- app/locales/locale-de.json | 27 +++++++++++++++++++-------- app/locales/locale-es.json | 27 +++++++++++++++++++-------- app/locales/locale-fi.json | 27 +++++++++++++++++++-------- app/locales/locale-fr.json | 27 +++++++++++++++++++-------- app/locales/locale-nl.json | 27 +++++++++++++++++++-------- app/locales/locale-zh-hant.json | 27 +++++++++++++++++++-------- 7 files changed, 133 insertions(+), 56 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index af5b4123..8e74b459 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Canvi de contrasenya - Taiga", - "PAGE_DESCRIPTION": "Crea un nou password per Taiga i... hey! Menja un poc més de ferro, es bo pel cervell :P ", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Canvi de contrasenya", "FIELD_CURRENT_PASSWORD": "Contrasenya actual", "PLACEHOLDER_CURRENT_PASSWORD": "La teua contrasenya actua (buit si no tens contrasenya encara)", @@ -407,7 +407,12 @@ "MEETUP": "Trobar-se", "MEETUP_DESCRIPTION": "Tria el teu sistema de videonconferéncia. Inclosos els desenvolupadors necessitan contacte cara a cara", "SELECT_VIDEOCONFERENCE": "Selecciona un sistema de videconferència", - "SALT_CHAT_ROOM": "Pots afegir un code salt a la sala de xat" + "SALT_CHAT_ROOM": "Pots afegir un code salt a la sala de xat", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Project profile - {{projectName}}", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Camps personalitzats de tasques", "TASK_ADD": "Afegix camps personalitzats en tasques", "ISSUE_DESCRIPTION": "Camps personalitzats d'incidències", - "ISSUE_ADD": "Afegix camps personalitzats en incidències" + "ISSUE_ADD": "Afegix camps personalitzats en incidències", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punts", - "OPTIMAL": "Punts pendent òptims per sprint {{xval}} deuría ser {{yval}}", - "REAL": "Punts pendent reals per sprint {{xval}} es {{yval}}", - "INCREMENT_TEAM": "Punts incrementats per requeriment de l'equip per sprint {{xval}} és {{yval}}", - "INCREMENT_CLIENT": "Punts incrementat per requeriment de client {{xval}} és {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Toggle tags visibility", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} created the project {{project_name}}", "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} has updated the wiki page {{obj_name}}", "NEW_COMMENT_US": "{{username}} has commented in the US {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} has commented in the issue {{obj_name}}", diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index ad5c2de0..53968b63 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Ändern Sie Ihr Passwort - Taiga", - "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihr Taiga Benutzerkonto.", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Passwort ändern", "FIELD_CURRENT_PASSWORD": "Aktuelles Passwort", "PLACEHOLDER_CURRENT_PASSWORD": "Ihr aktuelles Passwort (oder leer, wenn Sie noch kein Passwort haben)", @@ -407,7 +407,12 @@ "MEETUP": "Zusammentreffen", "MEETUP_DESCRIPTION": "Wählen Sie Ihr Videokonferenzsystem. Auch Entwickler brauchen Kontakt von Angesicht zu Angesicht. ", "SELECT_VIDEOCONFERENCE": "Wählen Sie ein Videokonferenzsystem", - "SALT_CHAT_ROOM": "Wenn Sie möchten, können Sie einen Salt Code zum Namen des Chatrooms hinzufügen" + "SALT_CHAT_ROOM": "Wenn Sie möchten, können Sie einen Salt Code zum Namen des Chatrooms hinzufügen", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "Erscheint in", + "TALKY_CHAT_ROOM": "Gesprächig", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Projekt Profil - {{projectName}}", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Aufgaben benutzerdefinierte Felder", "TASK_ADD": "Fügen Sie ein benutzerdefiniertes Feld bei Aufgaben hinzu", "ISSUE_DESCRIPTION": "Tickets benutzerdefinierte Felder", - "ISSUE_ADD": "Fügen Sie den Tickets ein benutzerdefiniertes Feld hinzu " + "ISSUE_ADD": "Fügen Sie den Tickets ein benutzerdefiniertes Feld hinzu ", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Projekt Werte - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punkte", - "OPTIMAL": "Optimale unerledigte Punkte für Sprint {{xval}} sollten sein {{yval}}", - "REAL": "Tatsächliche Anzahl unerledigter Punkte für Sprint {{xval}} ist {{yval}}", - "INCREMENT_TEAM": "Erhöhte Punkteanzahl von Team Anfragen für Sprint {{xval}} ist {{yval}}", - "INCREMENT_CLIENT": "Erhöhte Punkteanzahl von Kundenanfragen für Sprint {{xval}} ist {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Sichtbarkeit des Schlagwortes umschalten", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} erstellte das Projekt {{project_name}}", "MILESTONE_UPDATED": "{{username}} aktualisierte den Sprint {{obj_name}}", "US_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}}", - "TASK_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} von User-Story {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} aktualisierte die WIKI Seite {{obj_name}}", "NEW_COMMENT_US": "{{username}} schrieb einen Kommentar in der User-Story {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} schrieb einen Kommentar im Ticket {{obj_name}}", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 3c2f0211..00ed064f 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Cambia tu contraseña - Taiga", - "PAGE_DESCRIPTION": "Indica una nueva contraseña para tu cuenta en Taiga y bueno, es posible que necesites comer un poco más de alimentos ricos en hierro, son buenos para tu cerebro :P", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Cambiar contraseña", "FIELD_CURRENT_PASSWORD": "Contraseña actual", "PLACEHOLDER_CURRENT_PASSWORD": "Tu contraseña actual (o déjalo vacío si todavía no tienes contraseña)", @@ -407,7 +407,12 @@ "MEETUP": "Meet Up", "MEETUP_DESCRIPTION": "Elige tu sistema de videoconferencia. Incluso los desarrolladores necesitan el contacto cara a cara.", "SELECT_VIDEOCONFERENCE": "Elige un sistema de videoconferencia", - "SALT_CHAT_ROOM": "Puedes añadirle un código salt al nombre del chat room" + "SALT_CHAT_ROOM": "Puedes añadirle un código salt al nombre del chat room", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Personalizado", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Perfil de Proyecto - {{projectName}}\n", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Atributos personalizados de tareas", "TASK_ADD": "Añadir un atributo personalizado en las tareas", "ISSUE_DESCRIPTION": "Atributos personalizados de peticiones", - "ISSUE_ADD": "Añadir un atributo personalizado en las peticiones" + "ISSUE_ADD": "Añadir un atributo personalizado en las peticiones", + "FIELD_TYPE_TEXT": "Texto", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Valores del Proyectos - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Puntos", - "OPTIMAL": "El número de puntos óptimos pendientes para el sprint {{xval}} debería ser de {{yval}}", - "REAL": "El número real de puntos pendientes para el sprint {{xval}} es de {{yval}}", - "INCREMENT_TEAM": "El número de puntos incrementados por requerimientos del equipo para el sprint {{xval}} es de {{yval}}", - "INCREMENT_CLIENT": "El número de puntos incrementados por requerimientos del cliente para el sprint {{xval}} es de {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Cambia la visibilidad de los tags", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} creó el proyecto {{project_name}}", "MILESTONE_UPDATED": "{{username}} ha actualizado el sprint {{obj_name}}", "US_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}}", - "TASK_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} que proviene de la historia {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} ha actualizado la página del wiki {{obj_name}}", "NEW_COMMENT_US": "{{username}} ha añadido un comentado en la historia {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} ha añadido un comentado en la petición {{obj_name}}", diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index 85bf6a4c..e3b747ea 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Change you password - Taiga", - "PAGE_DESCRIPTION": "Set a new passoword for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Muuta salasanaa", "FIELD_CURRENT_PASSWORD": "Nykyinen salasana", "PLACEHOLDER_CURRENT_PASSWORD": "Nykyinen salasanasi (tai on tyhjä jos sinulla ei vielä ole)", @@ -407,7 +407,12 @@ "MEETUP": "Tapaa", "MEETUP_DESCRIPTION": "Valitse videoneuvottelu- järjestelmä. Jopa kehittäjät tarvitsevat katsekontaktia.", "SELECT_VIDEOCONFERENCE": "Valitse videoconferenssi-järjestelmä", - "SALT_CHAT_ROOM": "Voit halutessasi lisätä suolaan chat-huoneen nimeen" + "SALT_CHAT_ROOM": "Voit halutessasi lisätä suolaan chat-huoneen nimeen", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Projektin profiili - {{projectName}}", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Tehtävien omat kentät", "TASK_ADD": "Lisää omia kenttiä tehtäviin", "ISSUE_DESCRIPTION": "Pyyntöjen omat kentät", - "ISSUE_ADD": "Lisää oma kenttä pyynnöille" + "ISSUE_ADD": "Lisää oma kenttä pyynnöille", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Kierrokset", "YAXIS_LABEL": "Pisteet", - "OPTIMAL": "Optimaaliset odottavat pisteet kierokselle {{xval}} ovat {{yval}}", - "REAL": "Todelliset odottavat pisteet kierrokselle {{xval}} ovat {{yval}}", - "INCREMENT_TEAM": "Lisätyt tiimin vaatimat pisteet kierrokselle {{xval}} ovat {{yval}}", - "INCREMENT_CLIENT": "Lisätyt asiakkaan vaatimat pisteet kierrokselle {{xval}} ovat {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Vaihda avainsanojen näkyvyyttä", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} created the project {{project_name}}", "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} has updated the wiki page {{obj_name}}", "NEW_COMMENT_US": "{{username}} has commented in the US {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} has commented in the issue {{obj_name}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 2ddd3a25..df2297e2 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Modifier votre mot de passe - Taiga", - "PAGE_DESCRIPTION": "Paramètrez un nouveau mot de passe pour votre compte Taiga et, au fait, vous devriez manger de la nourriture plus riche en fer, c'est bon pour votre cerveau :P", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Modifier le mot de passe", "FIELD_CURRENT_PASSWORD": "Mot de passe courant", "PLACEHOLDER_CURRENT_PASSWORD": "Votre mot de passe courant (ne rien saisir si vous ne possédez pas encore de mot de passe)", @@ -407,7 +407,12 @@ "MEETUP": "Meet Up", "MEETUP_DESCRIPTION": "Choisissez votre système de vidéoconférence. Même les développeurs ont besoin de contact en face à face.", "SELECT_VIDEOCONFERENCE": "Choisissez un système de vidéoconférence", - "SALT_CHAT_ROOM": "Si vous le souhaitez vous pouvez ajouter un code de salage au nom du salon de discussion" + "SALT_CHAT_ROOM": "Si vous le souhaitez vous pouvez ajouter un code de salage au nom du salon de discussion", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Profil projet - {{projectName}}\n", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Champs personnalisés de tâches", "TASK_ADD": "Ajouter un champ personnalisé dans les tâches", "ISSUE_DESCRIPTION": "Champs personnalisés des problèmes", - "ISSUE_ADD": "Ajouter un champ personnalisé dans les problèmes" + "ISSUE_ADD": "Ajouter un champ personnalisé dans les problèmes", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Valeurs du projet - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Points", - "OPTIMAL": "Le nombre optimal de points en attente pour le sprint {{xval}} devrait être {{yval}}", - "REAL": "Le nombre réel de points pour le sprint {{xval}} est {{yval}}", - "INCREMENT_TEAM": "Le nombre de points ajoutés par les exigences de l'équipe pour le sprint {{xval}} est {{yval}}", - "INCREMENT_CLIENT": "Le nombre de points ajoutés par les exigences du client pour le sprint {{xval}} est {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Afficher/Cacher les tags", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} a créé le projet {{project_name}}", "MILESTONE_UPDATED": "{{username}} a mis à jour le sprint {{obj_name}}", "US_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du récit utilisateur {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du suivi de problème {{obj_name}}", - "TASK_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» de la tâche {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} a mis à jour l'attribut «{{field_name}}» de la tâche {{obj_name}} qui appartient au récit utilisateur {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} a mis à jour la page wiki {{obj_name}}", "NEW_COMMENT_US": "{{username}} a commenté le récit utilisateur {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} a commenté le suivi de problème {{obj_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 02baf2ab..78bcbce2 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Verander je wachtwoord - Taiga", - "PAGE_DESCRIPTION": "Zet een nieuw wachtwoord voor je Taiga account. Hey! Je kan best wat ijzerrijk voedsel eten, dat is goed voor de hersenen :P", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "Wachtwoord wijzigen", "FIELD_CURRENT_PASSWORD": "Huidig wachtwoord", "PLACEHOLDER_CURRENT_PASSWORD": "Je huidige wachtwoord (of leeg als je nog geen wachtwoord hebt)", @@ -407,7 +407,12 @@ "MEETUP": "Meet Up", "MEETUP_DESCRIPTION": "Kies je videoconference systeem. Zelfs programmeurs hebben face-to-face contact nodig.", "SELECT_VIDEOCONFERENCE": "Kies een videoconference systeem", - "SALT_CHAT_ROOM": "Als je wil kan je een salt code aan de naam van de chatroom toevoegen" + "SALT_CHAT_ROOM": "Als je wil kan je een salt code aan de naam van de chatroom toevoegen", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Project profiel - {{projectName}}", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "Eigen velden taken", "TASK_ADD": "Voeg een aangepast veld toe in taken", "ISSUE_DESCRIPTION": "Issues aangepaste velden", - "ISSUE_ADD": "Voeg een aangepast veld toe in issues" + "ISSUE_ADD": "Voeg een aangepast veld toe in issues", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project waardes - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punten", - "OPTIMAL": "Optimale aantal resterende punten voor sprint {{xval}} zou {{yval}} zijn", - "REAL": "Werkelijk aantal resterende punten voor sprint {{xval}} is {{yval}}", - "INCREMENT_TEAM": "Aantal toegevoegde punten door requirements van het team voor sprint {{xval}} is {{yval}}", - "INCREMENT_CLIENT": "Aantal toegevoegde punten door requirements van de klant voor sprint {{xval}} is {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "Zet de tag zichtbaarheid aan of af", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} heeft een nieuw project aangemaakt {{project_name}}", "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", - "TASK_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de taak {{obj_name}} bijgewerkt", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} heeft de eigenschap \"{{field_name}}\" van de taak {{obj_name}} die behoort tot de US {{us_name}} bijgewerkt", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "{{username}} heeft de wiki pagina {{obj_name}} bijgewerkt", "NEW_COMMENT_US": "{{username}} heeft gereageerd op de US {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} heeft gereageerd op het issue {{obj_name}}", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index c4d753da..ae4dae34 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "變更密碼 - Taiga", - "PAGE_DESCRIPTION": "設定Taiga 帳戶密碼! 你也許該吃點鐵質豐富的食物,它對你的大腦有益處:p", + "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", "SECTION_NAME": "改變密碼 ", "FIELD_CURRENT_PASSWORD": "現用密碼 ", "PLACEHOLDER_CURRENT_PASSWORD": "你目前的密碼(如果你未有密碼,此處請空白)", @@ -407,7 +407,12 @@ "MEETUP": "符合", "MEETUP_DESCRIPTION": "選擇你的視訊系統。有些開發者需要面對面接觸", "SELECT_VIDEOCONFERENCE": "選擇一個視訊會議系統 ", - "SALT_CHAT_ROOM": "你可以把聊天室名稱加上salt code亂數密碼 " + "SALT_CHAT_ROOM": "你可以把聊天室名稱加上salt code亂數密碼 ", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Custom", + "URL_CHAT_ROOM": "URL of your chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - 專案檔案 - {{projectName}}", @@ -448,7 +453,9 @@ "TASK_DESCRIPTION": "任務客製化欄位", "TASK_ADD": "在任務中加入客制欄位", "ISSUE_DESCRIPTION": "問題客製化欄位", - "ISSUE_ADD": "在問題中加入客制欄位" + "ISSUE_ADD": "在問題中加入客制欄位", + "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - 專案數值 - {{projectName}}", @@ -889,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "衝刺任務", "YAXIS_LABEL": "點數", - "OPTIMAL": "最佳給衝刺任務待辦點數 {{xval}} 應是 {{yval}}", - "REAL": "任務衝刺實際待辦點數 {{xval}} 為 {{yval}}", - "INCREMENT_TEAM": "團隊要求的任務衝刺逐步新增點數 {{xval}} 為 {{yval}}", - "INCREMENT_CLIENT": "客戶要求的任務衝刺逐步新增點數 {{xval}} 為 {{yval}}" + "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { "TOGGLE": "切換標籤可見度", @@ -1234,9 +1241,13 @@ "NEW_PROJECT": "{{username}} 創建專案 {{project_name}}", "MILESTONE_UPDATED": "{{username}}更新衝刺任務 {{obj_name}} ", "US_UPDATED": "{{username}} 已更新 {{obj_name}}使用者故事之 \"{{field_name}}\"屬性。", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} 更新了{{obj_name}}問題的 \"{{field_name}}\" 屬性", - "TASK_UPDATED": "{{username}}更新了任務 {{obj_name}}之 \"{{field_name}}\" 屬性", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} 更新了 {{obj_name}} 任務之\"{{field_name}}\" 屬性,其為 {{us_name}} 之使用者故事", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", "WIKI_UPDATED": "\n{{username}} 更新了維基頁{{obj_name}}", "NEW_COMMENT_US": "{{username}} 評論了 {{obj_name}}使用者故事", "NEW_COMMENT_ISSUE": "{{username}}評論了此問題 {{obj_name}}", From acbc43ba3d38aea663e9b3a91f3024bbbf26408c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 6 Jul 2015 17:19:49 +0200 Subject: [PATCH 055/403] [i18n] Update locales --- app/locales/locale-de.json | 2 +- app/locales/locale-es.json | 24 ++++++++++++------------ app/locales/locale-fr.json | 2 +- app/locales/locale-nl.json | 2 +- app/locales/locale-zh-hant.json | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 53968b63..cd71532c 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Ändern Sie Ihr Passwort - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Setzen Sie ein neues Passwort für Ihr Taiga Benutzerkonto.", "SECTION_NAME": "Passwort ändern", "FIELD_CURRENT_PASSWORD": "Aktuelles Passwort", "PLACEHOLDER_CURRENT_PASSWORD": "Ihr aktuelles Passwort (oder leer, wenn Sie noch kein Passwort haben)", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 00ed064f..57497f91 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Cambia tu contraseña - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Indica una nueva contraseña para tu cuenta en Taiga y bueno, es posible que necesites comer un poco más de alimentos ricos en hierro, son buenos para tu cerebro :P", "SECTION_NAME": "Cambiar contraseña", "FIELD_CURRENT_PASSWORD": "Contraseña actual", "PLACEHOLDER_CURRENT_PASSWORD": "Tu contraseña actual (o déjalo vacío si todavía no tienes contraseña)", @@ -412,7 +412,7 @@ "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", "CUSTOM_CHAT_ROOM": "Personalizado", - "URL_CHAT_ROOM": "URL of your chat room" + "URL_CHAT_ROOM": "URL de tu chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Perfil de Proyecto - {{projectName}}\n", @@ -455,7 +455,7 @@ "ISSUE_DESCRIPTION": "Atributos personalizados de peticiones", "ISSUE_ADD": "Añadir un atributo personalizado en las peticiones", "FIELD_TYPE_TEXT": "Texto", - "FIELD_TYPE_MULTI": "Multi-line" + "FIELD_TYPE_MULTI": "Multilínea" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Valores del Proyectos - {{projectName}}", @@ -896,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Puntos", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", - "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" + "OPTIMAL": "El número de puntos óptimos pendientes para el sprint \"{{sprintName}}\" debería ser de {{value}}", + "REAL": "El número real de puntos pendientes para el sprint \"{{sprintName}}\" es de {{value}}", + "INCREMENT_TEAM": "El número de puntos incrementados por requerimientos del equipo para el sprint \"{{sprintName}}\" es de {{value}}", + "INCREMENT_CLIENT": "El número de puntos incrementados por requerimientos del cliente para el sprint \"{{sprintName}}\" es de {{value}}" }, "TAGS": { "TOGGLE": "Cambia la visibilidad de los tags", @@ -1241,13 +1241,13 @@ "NEW_PROJECT": "{{username}} creó el proyecto {{project_name}}", "MILESTONE_UPDATED": "{{username}} ha actualizado el sprint {{obj_name}}", "US_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}}", - "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}} a {{new_value}}", "ISSUE_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}}", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", - "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}} a {{new_value}}", + "TASK_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} a {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} a {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} que proviene de la historia {{us_name}}", - "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} que pertenece a la historia {{us_name}} a {{new_value}}", "WIKI_UPDATED": "{{username}} ha actualizado la página del wiki {{obj_name}}", "NEW_COMMENT_US": "{{username}} ha añadido un comentado en la historia {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} ha añadido un comentado en la petición {{obj_name}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index df2297e2..73262e56 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Modifier votre mot de passe - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Paramètrez un nouveau mot de passe pour votre compte Taiga et, au fait, vous devriez manger de la nourriture plus riche en fer, c'est bon pour votre cerveau :P", "SECTION_NAME": "Modifier le mot de passe", "FIELD_CURRENT_PASSWORD": "Mot de passe courant", "PLACEHOLDER_CURRENT_PASSWORD": "Votre mot de passe courant (ne rien saisir si vous ne possédez pas encore de mot de passe)", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 78bcbce2..33a01064 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Verander je wachtwoord - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Zet een nieuw wachtwoord voor je Taiga account. Hey! Je kan best wat ijzerrijk voedsel eten, dat is goed voor de hersenen :P", "SECTION_NAME": "Wachtwoord wijzigen", "FIELD_CURRENT_PASSWORD": "Huidig wachtwoord", "PLACEHOLDER_CURRENT_PASSWORD": "Je huidige wachtwoord (of leeg als je nog geen wachtwoord hebt)", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index ae4dae34..8393fff4 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -294,7 +294,7 @@ }, "CHANGE_PASSWORD": { "PAGE_TITLE": "變更密碼 - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "設定Taiga 帳戶密碼! 你也許該吃點鐵質豐富的食物,它對你的大腦有益處:p", "SECTION_NAME": "改變密碼 ", "FIELD_CURRENT_PASSWORD": "現用密碼 ", "PLACEHOLDER_CURRENT_PASSWORD": "你目前的密碼(如果你未有密碼,此處請空白)", From 40d5336522067bb7357a95272d9801a31170c00e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 30 Jun 2015 16:44:06 +0200 Subject: [PATCH 056/403] Make burndown chart collapsible at the backlog panel --- CHANGELOG.md | 1 + app/coffee/modules/backlog/main.coffee | 37 +++++++++++++++++- app/locales/locale-en.json | 3 +- app/partials/backlog/backlog.jade | 14 ++++--- app/partials/includes/components/summary.jade | 4 ++ app/styles/components/summary.scss | 39 +++++++++---------- 6 files changed, 68 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f1b6e58..159fcbae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### Features - Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool)) - Add custom videoconference system. +- Make burndown chart collapsible at the backlog panel. ### Misc - Improve performance: Show cropped images in timelines. diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 3dac4387..86fe61b5 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -28,6 +28,7 @@ bindOnce = @.taiga.bindOnce groupBy = @.taiga.groupBy timeout = @.taiga.timeout bindMethods = @.taiga.bindMethods +generateHash = @.taiga.generateHash module = angular.module("taigaBacklog") @@ -644,7 +645,7 @@ BacklogDirective = ($repo, $rootscope, $translate) -> _.map elements, (elm) -> input = $(elm).find("input:checkbox") - input.prop('checked', true); + input.prop('checked', true) checkSelected(input) target = angular.element(event.currentTarget) @@ -724,7 +725,6 @@ BacklogDirective = ($repo, $rootscope, $translate) -> $el.find(".backlog-table-body").disableSelection() filters = $ctrl.getUrlFilters() - if filters.statuses || filters.tags || filters.q @@ -903,6 +903,39 @@ UsPointsDirective = ($tgEstimationsService, $repo, $tgTemplate) -> module.directive("tgBacklogUsPoints", ["$tgEstimationsService", "$tgRepo", "$tgTemplate", UsPointsDirective]) +############################################################################# +## Burndown graph directive +############################################################################# +ToggleBurndownVisibility = ($storage) -> + link = ($scope, $el, $attrs) -> + hash = generateHash(["is-burndown-grpahs-collapsed"]) + toggleGraph = -> + if $scope.isBurndownGraphCollapsed + $(".js-toggle-burndown-visibility-button").removeClass("active") + $(".js-burndown-graph").removeClass("open") + else + $(".js-toggle-burndown-visibility-button").addClass("active") + $(".js-burndown-graph").addClass("open") + + $scope.isBurndownGraphCollapsed = $storage.get(hash) or false + toggleGraph() + + $el.on "click", ".js-toggle-burndown-visibility-button", -> + $scope.isBurndownGraphCollapsed = !$scope.isBurndownGraphCollapsed + $storage.set(hash, $scope.isBurndownGraphCollapsed) + toggleGraph() + + $scope.$on "$destroy", -> + $el.off() + + return { + scope: {} + link: link + } + +module.directive("tgToggleBurndownVisibility", ["$tgStorage", ToggleBurndownVisibility]) + + ############################################################################# ## Burndown graph directive ############################################################################# diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index e9a008c2..2a06e9de 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -919,7 +919,8 @@ "OPEN_TASKS": "open
tasks", "CLOSED_TASKS": "closed
tasks", "IOCAINE_DOSES": "iocaine
doses", - "SHOW_STATISTICS_TITLE": "Show statistics" + "SHOW_STATISTICS_TITLE": "Show statistics", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "project
points", diff --git a/app/partials/backlog/backlog.jade b/app/partials/backlog/backlog.jade index 8741c465..a4862387 100644 --- a/app/partials/backlog/backlog.jade +++ b/app/partials/backlog/backlog.jade @@ -7,17 +7,19 @@ div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl", include ../includes/modules/backlog-filters section.main.backlog include ../includes/components/mainTitle - include ../includes/components/summary - div.graphics-container.burndown-container - div.burndown(tg-burndown-backlog-graph) - include ../includes/modules/burndown + div.backlog-summary(tg-toggle-burndown-visibility) + include ../includes/components/summary + + div.graphics-container.burndown-container.js-burndown-graph + div.burndown(tg-burndown-backlog-graph) + include ../includes/modules/burndown div.backlog-menu div.backlog-table-options a.trans-button.move-to-current-sprint(href="", - title="{{'BACKLOG.MOVE_US_TO_CURRENT_SPRINT' | translate}}", - id="move-to-current-sprint") + title="{{'BACKLOG.MOVE_US_TO_CURRENT_SPRINT' | translate}}", + id="move-to-current-sprint") span.icon.icon-move span.text(translate="BACKLOG.MOVE_US_TO_CURRENT_SPRINT") a.trans-button(href="", diff --git a/app/partials/includes/components/summary.jade b/app/partials/includes/components/summary.jade index 1b29810d..849ec856 100644 --- a/app/partials/includes/components/summary.jade +++ b/app/partials/includes/components/summary.jade @@ -16,3 +16,7 @@ div.summary div.summary-stats span.number(ng-bind="stats.speed | number:0") -- span.description(translate="BACKLOG.SUMMARY.POINTS_PER_SPRINT") + + a.icon.icon-stats.js-toggle-burndown-visibility-button(href="", + title="{{'BACKLOG.SPRINT_SUMMARY.TOGGLE_BAKLOG_GRAPH' | translate}}") + diff --git a/app/styles/components/summary.scss b/app/styles/components/summary.scss index ded4538b..d2120143 100644 --- a/app/styles/components/summary.scss +++ b/app/styles/components/summary.scss @@ -17,7 +17,24 @@ } } .icon { - @extend %large; + font-size: 1.4rem; + margin-right: .4rem; + &.icon-stats { + color: $gray; + float: right; + transition: color .3s linear; + &:hover { + color: $fresh-taiga; + transition: color .3s linear; + } + &.active { + color: $fresh-taiga; + } + &.active:hover { + color: $gray; + transition: color .3s linear; + } + } } .number { @extend %xlarge; @@ -88,24 +105,4 @@ .summary-stats-divider { margin-right: 2rem; } - .icon { - font-size: 1.4rem; - margin-right: .4rem; - &.icon-stats { - color: $gray; - float: right; - transition: color .3s linear; - &:hover { - color: $fresh-taiga; - transition: color .3s linear; - } - &.active { - color: $fresh-taiga; - } - &.active:hover { - color: $gray; - transition: color .3s linear; - } - } - } } From 66f46868477fa704a029b0dd3fc4b1a9d7ec36a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 7 Jul 2015 15:38:17 +0200 Subject: [PATCH 057/403] Backlog graph show/hide refactor --- .../includes/components/sprint-summary.jade | 5 +- app/partials/includes/components/summary.jade | 6 +- app/styles/components/summary.scss | 89 ++++++++++++++----- app/svg/graph.svg | 8 ++ 4 files changed, 82 insertions(+), 26 deletions(-) create mode 100644 app/svg/graph.svg diff --git a/app/partials/includes/components/sprint-summary.jade b/app/partials/includes/components/sprint-summary.jade index caa16ba2..5fbe8e4e 100644 --- a/app/partials/includes/components/sprint-summary.jade +++ b/app/partials/includes/components/sprint-summary.jade @@ -24,5 +24,6 @@ div.summary.large-summary span.icon.icon-iocaine span.number(ng-bind="stats.iocaine_doses|default:'--'") span.description(translate="BACKLOG.SPRINT_SUMMARY.IOCAINE_DOSES") - - a.icon.icon-stats.toggle-analytics-visibility(href="", title="{{'BACKLOG.SPRINT_SUMMARY.SHOW_STATISTICS_TITLE' | translate}}") + + div.stats.toggle-analytics-visibility(title="{{'BACKLOG.SPRINT_SUMMARY.SHOW_STATISTICS_TITLE' | translate}}") + include ../../../svg/graph.svg diff --git a/app/partials/includes/components/summary.jade b/app/partials/includes/components/summary.jade index 849ec856..0b8ac558 100644 --- a/app/partials/includes/components/summary.jade +++ b/app/partials/includes/components/summary.jade @@ -17,6 +17,6 @@ div.summary span.number(ng-bind="stats.speed | number:0") -- span.description(translate="BACKLOG.SUMMARY.POINTS_PER_SPRINT") - a.icon.icon-stats.js-toggle-burndown-visibility-button(href="", - title="{{'BACKLOG.SPRINT_SUMMARY.TOGGLE_BAKLOG_GRAPH' | translate}}") - + + div.stats.js-toggle-burndown-visibility-button(title="{{'BACKLOG.SPRINT_SUMMARY.TOGGLE_BAKLOG_GRAPH' | translate}}") + include ../../../svg/graph.svg diff --git a/app/styles/components/summary.scss b/app/styles/components/summary.scss index d2120143..8137273b 100644 --- a/app/styles/components/summary.scss +++ b/app/styles/components/summary.scss @@ -1,6 +1,8 @@ +$summary-background: $grayer; + .summary { align-content: center; - background: $grayer; + background: $summary-background; color: $white; display: flex; flex-wrap: wrap; @@ -16,26 +18,6 @@ color: $fresh-taiga; } } - .icon { - font-size: 1.4rem; - margin-right: .4rem; - &.icon-stats { - color: $gray; - float: right; - transition: color .3s linear; - &:hover { - color: $fresh-taiga; - transition: color .3s linear; - } - &.active { - color: $fresh-taiga; - } - &.active:hover { - color: $gray; - transition: color .3s linear; - } - } - } .number { @extend %xlarge; @extend %bold; @@ -48,6 +30,47 @@ @extend %light; line-height: 1; } + .stats { + cursor: pointer; + height: 2rem; + margin-left: auto; + width: 2rem; + path { + opacity: 1; + } + &:hover { + .graph, + .color-line { + fill: $fresh-taiga; + transition: fill .2s; + } + } + &.active { + .white-line, + .color-line { + display: none; + } + .graph { + fill: $green-taiga; + } + } + svg { + height: 100%; + width: 100%; + } + .graph, + .color-line { + fill: darken($gray-light, 20%); + transition: fill .2s; + } + .white-line { + fill: $summary-background; + } + .white-line, + .color-line { + display: block; + } + } } .summary-progress-bar { @@ -105,4 +128,28 @@ .summary-stats-divider { margin-right: 2rem; } + .icon { + font-size: 1.4rem; + margin-right: .4rem; + &.icon-stats { + color: $green-taiga; + float: right; + transition: color .3s linear; + &:hover { + color: $fresh-taiga; + transition: color .3s linear; + } + &.active { + color: $fresh-taiga; + } + &.active:hover { + color: $green-taiga; + transition: color .3s linear; + } + } + } +} + +.graphics-container { + @include slide(300px, hidden, 0); } diff --git a/app/svg/graph.svg b/app/svg/graph.svg new file mode 100644 index 00000000..4563bf70 --- /dev/null +++ b/app/svg/graph.svg @@ -0,0 +1,8 @@ + + + + + + + + From a1488d60c82b61ca3af5b8f3868b2f982421273d Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 22 May 2015 14:39:08 +0200 Subject: [PATCH 058/403] Add taiga theme and a gulp task to compile themes --- app/index.jade | 2 +- app/styles/extras/dependencies.scss | 2 +- app/themes/taiga/custom.scss | 0 .../taiga/variables.scss} | 1 - gulp-utils.js | 74 ++++++++++++ gulpfile.js | 107 +++++++++++++++--- package.json | 1 + 7 files changed, 167 insertions(+), 20 deletions(-) create mode 100644 app/themes/taiga/custom.scss rename app/{styles/dependencies/colors.scss => themes/taiga/variables.scss} (99%) create mode 100644 gulp-utils.js diff --git a/app/index.jade b/app/index.jade index 105ca868..e50edda1 100644 --- a/app/index.jade +++ b/app/index.jade @@ -10,7 +10,7 @@ html(lang="en") meta(name="description", content="Taiga is a project management platform for startups and agile developers & designers who want a simple, beautiful tool that makes work truly enjoyable.") meta(name="keywords", content="agile, scrum, taiga, management, project, developer, designer, user experience") //-meta(name="viewport", content="width=device-width, user-scalable=no") - link(rel="stylesheet", href="/styles/main.css") + link(rel="stylesheet", href="/styles/theme-taiga.css") link(rel="icon", type="image/png", href="/images/favicon.png") //- PRERENDER SERVICE: This is to know when the page is completely loaded. diff --git a/app/styles/extras/dependencies.scss b/app/styles/extras/dependencies.scss index 6d90bfb8..f09f0308 100644 --- a/app/styles/extras/dependencies.scss +++ b/app/styles/extras/dependencies.scss @@ -10,7 +10,7 @@ $prefix-for-mozilla: true; // dependencies //################################################# -@import '../dependencies/colors'; +@import "variables"; @import '../dependencies/mixins'; @import '../dependencies/helpers'; @import '../dependencies/responsive'; diff --git a/app/themes/taiga/custom.scss b/app/themes/taiga/custom.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/styles/dependencies/colors.scss b/app/themes/taiga/variables.scss similarity index 99% rename from app/styles/dependencies/colors.scss rename to app/themes/taiga/variables.scss index e5b28c0d..8db5386a 100755 --- a/app/styles/dependencies/colors.scss +++ b/app/themes/taiga/variables.scss @@ -8,7 +8,6 @@ $gray-light: #b8b8b8; $whitish: #f5f5f5; $white: #fff; - $green-taiga: #72a114; $fresh-taiga: #9dce0a; $dark-taiga: #879b89; diff --git a/gulp-utils.js b/gulp-utils.js new file mode 100644 index 00000000..bfefee28 --- /dev/null +++ b/gulp-utils.js @@ -0,0 +1,74 @@ +var exports = module.exports = {}; +var fs = require("fs"); + +var Theme = function() { + var defaultTheme = "taiga"; + + var themesPath = "app/themes"; + var tmpThemesPath = "tmp/themes"; + + var themesSequenceIndex = 0; + var themesSequence = []; + + var searchIndex = function(name) { + for(var i = 0; i < themesSequence.length; i++) { + if (themesSequence[i].name === name) { + return i; + } + } + }; + + var initThemes = function () { + var availableThemes = {}; + var files = fs.readdirSync(themesPath); + + files.forEach(function(file) { + var path = themesPath + '/' + file; + var tmpPath = tmpThemesPath + '/' + file; + + if (fs.statSync(path).isDirectory()) { + availableThemes[file] = { + name: file, + path: path, + customVariables: path + "/variables.scss", + customScss: path + "/custom.scss", + customCss: tmpPath + "/custom.css", + }; + } + }); + + themesSequence.push(availableThemes[defaultTheme]); + + for (var theme in availableThemes) { + if (theme !== defaultTheme) { + themesSequence.push(availableThemes[theme]); + } + } + }; + + initThemes(); + + var obj = {}; + + obj.next = function() { + themesSequenceIndex++; + }; + + obj.set = function(name) { + themesSequenceIndex = searchIndex(name); + }; + + Object.defineProperty(obj, "current", { + get: function() { + return themesSequence[themesSequenceIndex]; + } + }); + + return obj; +}; + +exports.themes = { + sequence: function() { + return Theme(); + } +}; diff --git a/gulpfile.js b/gulpfile.js index 06eee914..c923045c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -27,6 +27,16 @@ var gulp = require("gulp"), del = require("del"), coffeelint = require('gulp-coffeelint'); +var argv = require('minimist')(process.argv.slice(2)); + +var utils = require("./gulp-utils"); + +var themes = utils.themes.sequence(); + +if (argv.theme) { + themes.set(argv.theme); +} + var paths = {}; paths.app = "app/"; paths.dist = "dist/"; @@ -55,10 +65,16 @@ paths.sass = [ paths.app + "**/*.scss", "!" + paths.app + "/styles/bourbon/**/*.scss", "!" + paths.app + "/styles/dependencies/**/*.scss", - "!" + paths.app + "/styles/extras/**/*.scss" + "!" + paths.app + "/styles/extras/**/*.scss", + "!" + paths.app + "/themes/**/variables.scss", ]; -paths.styles_dependencies = paths.app + "/styles/dependencies/**/*.scss"; +paths.sass_watch = paths.sass.concat(themes.current.customScss); + +paths.styles_dependencies = [ + paths.app + "/styles/dependencies/**/*.scss", + themes.current.customVariables +]; paths.css = [ paths.tmp + "styles/**/*.css", @@ -79,7 +95,8 @@ paths.css_order = [ paths.tmp + "styles/modules/**/*.css", paths.tmp + "modules/**/*.css", paths.tmp + "styles/shame/*.css", - paths.tmp + "plugins/**/*.css" + paths.tmp + "plugins/**/*.css", + paths.tmp + "themes/**/*.css" ]; paths.coffee = [ @@ -153,7 +170,7 @@ paths.libs = [ paths.app + "js/sha1-custom.js" ]; -var isDeploy = process.argv[process.argv.length - 1] == "deploy"; +var isDeploy = argv["_"].indexOf("deploy") !== -1; /* ############################################################################ @@ -213,7 +230,9 @@ gulp.task("scss-lint", [], function() { var fail = process.argv.indexOf("--fail") !== -1; - return gulp.src(paths.sass.concat(ignore)) + var sassFiles = paths.sass.concat(themes.current.customScss, ignore); + + return gulp.src(sassFiles) .pipe(gulpif(!isDeploy, cache(scsslint({endless: true, sync: true, config: "scsslint.yml"}), { success: function(scsslintFile) { return scsslintFile.scsslint.success; @@ -232,20 +251,25 @@ gulp.task("clear-sass-cache", function() { }); gulp.task("sass-compile", [], function() { - return gulp.src(paths.sass) + var sassFiles = paths.sass.concat(themes.current.customScss); + + return gulp.src(sassFiles) .pipe(plumber()) .pipe(insert.prepend('@import "dependencies";')) .pipe(cached("sass")) .pipe(sass({ includePaths: [ - paths.app + "styles/extras/" + paths.app + "styles/extras/", + themes.current.path ] })) .pipe(gulp.dest(paths.tmp)); }); gulp.task("css-lint-app", function() { - return gulp.src(paths.css) + var cssFiles = paths.css.concat(themes.current.customCss); + + return gulp.src(cssFiles) .pipe(gulpif(!isDeploy, cache(csslint("csslintrc.json"), { success: function(csslintFile) { return csslintFile.csslint.success; @@ -260,9 +284,11 @@ gulp.task("css-lint-app", function() { }); gulp.task("app-css", function() { - return gulp.src(paths.css) + var cssFiles = paths.css.concat(themes.current.customCss); + + return gulp.src(cssFiles) .pipe(order(paths.css_order, {base: '.'})) - .pipe(concat("app.css")) + .pipe(concat("theme-" + themes.current.name + ".css")) .pipe(autoprefixer({ cascade: false })) @@ -278,15 +304,37 @@ gulp.task("vendor-css", function() { gulp.task("main-css", function() { var _paths = [ paths.tmp + "vendor.css", - paths.tmp + "app.css" + paths.tmp + "theme-" + themes.current.name + ".css" ]; return gulp.src(_paths) - .pipe(concat("main.css")) + .pipe(concat("theme-" + themes.current.name + ".css")) .pipe(gulpif(isDeploy, minifyCSS({noAdvanced: true}))) .pipe(gulp.dest(paths.dist + "styles/")) }); +var compileThemes = function (cb) { + return runSequence("clear", + "scss-lint", + "sass-compile", + "css-lint-app", + ["app-css", "vendor-css"], + "main-css", + function() { + themes.next() + + if (themes.current) { + compileThemes(cb); + } else { + cb(); + } + }); +}; + +gulp.task("compile-themes", function(cb) { + compileThemes(cb); +}); + gulp.task("styles", function(cb) { return runSequence("scss-lint", "sass-compile", @@ -294,7 +342,6 @@ gulp.task("styles", function(cb) { ["app-css", "vendor-css"], "main-css", cb); - }); gulp.task("styles-dependencies", function(cb) { @@ -396,7 +443,7 @@ gulp.task("app-deploy", ["coffee", "conf", "locales", "app-loader"], function() # Common tasks ############################################################################## */ -gulp.task("clear", function(done) { +gulp.task("clear", ["clear-sass-cache"], function(done) { return cache.clearAll(done); }); @@ -406,17 +453,33 @@ gulp.task("copy-svg", function() { .pipe(gulp.dest(paths.dist + "/svg/")); }); +gulp.task("copy-theme-svg", function() { + return gulp.src(themes.current.path + "/svg/**/*") + .pipe(gulp.dest(paths.dist + "/svg/" + themes.current.name)); +}); + gulp.task("copy-fonts", function() { return gulp.src(paths.app + "/fonts/*") .pipe(gulp.dest(paths.dist + "/fonts/")); }); +gulp.task("copy-theme-fonts", function() { + return gulp.src(themes.current.path + "/fonts/*") + .pipe(gulp.dest(paths.dist + "/fonts/" + themes.current.name)); +}); + gulp.task("copy-images", function() { return gulp.src(paths.app + "/images/**/*") .pipe(gulpif(isDeploy, imagemin({progressive: true}))) .pipe(gulp.dest(paths.dist + "/images/")); }); +gulp.task("copy-theme-images", function() { + return gulp.src(themes.current.path + "/images/**/*") + .pipe(gulpif(isDeploy, imagemin({progressive: true}))) + .pipe(gulp.dest(paths.dist + "/images/" + themes.current.name)); +}); + gulp.task("copy-images-plugins", function() { return gulp.src(paths.app + "/plugins/**/images/*") .pipe(flatten()) @@ -433,7 +496,17 @@ gulp.task("copy-extras", function() { .pipe(gulp.dest(paths.dist + "/")); }); -gulp.task("copy", ["copy-fonts", "copy-images", "copy-images-plugins", "copy-plugin-templates", "copy-svg", "copy-extras"]); +gulp.task("copy", [ + "copy-fonts", + "copy-theme-fonts", + "copy-images", + "copy-theme-images", + "copy-images-plugins", + "copy-plugin-templates", + "copy-svg", + "copy-theme-svg", + "copy-extras" +]); gulp.task("delete-tmp", function() { del.sync(paths.tmp); @@ -464,7 +537,7 @@ gulp.task("express", function() { //Rerun the task when a file changes gulp.task("watch", function() { gulp.watch(paths.jade, ["jade-watch"]); - gulp.watch(paths.sass, ["styles"]); + gulp.watch(paths.sass_watch, ["styles"]); gulp.watch(paths.styles_dependencies, ["styles-dependencies"]); gulp.watch(paths.svg, ["copy-svg"]); gulp.watch(paths.coffee, ["app-watch"]); @@ -480,7 +553,7 @@ gulp.task("deploy", function(cb) { "jade-deploy", "app-deploy", "jslibs-deploy", - "styles" + "compile-themes" ], cb); }); //The default task (called when you run gulp from cli) diff --git a/package.json b/package.json index 38752212..eb64c67d 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "karma-sinon": "^1.0.4", "karma-sinon-chai": "^0.3.0", "karma-sourcemap-loader": "^0.3.4", + "minimist": "^1.1.1", "mocha": "^2.2.4", "pre-commit": "^1.0.5", "readable-stream": "~1.0.33", From 6d202e923e763e2a4f497c2976a642d5ad43f13f Mon Sep 17 00:00:00 2001 From: Andrea Stagi Date: Mon, 1 Jun 2015 20:04:02 +0200 Subject: [PATCH 059/403] Add theme selector to the user profile form --- CHANGELOG.md | 1 + app-loader/app-loader.coffee | 2 ++ app/coffee/modules/auth.coffee | 18 ++++++++++++++---- app/coffee/modules/user-settings/main.coffee | 9 +++++++++ app/locales/locale-en.json | 4 +++- app/modules/services/theme.service.coffee | 15 +++++++++++++++ app/modules/services/theme.service.spec.coffee | 17 +++++++++++++++++ app/partials/user/user-profile.jade | 15 +++++++++++---- conf/conf.example.json | 2 ++ 9 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 app/modules/services/theme.service.coffee create mode 100644 app/modules/services/theme.service.spec.coffee diff --git a/CHANGELOG.md b/CHANGELOG.md index 159fcbae..31470c2a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - Ability to create single-line or multi-line custom fields. (thanks to [@artlepool](https://github.com/artlepool)) - Add custom videoconference system. - Make burndown chart collapsible at the backlog panel. +- Ability to choose a theme (thanks to [@astagi](https://github.com/astagi)) ### Misc - Improve performance: Show cropped images in timelines. diff --git a/app-loader/app-loader.coffee b/app-loader/app-loader.coffee index fba45384..02f5ad87 100644 --- a/app-loader/app-loader.coffee +++ b/app-loader/app-loader.coffee @@ -4,6 +4,8 @@ window.taigaConfig = { "eventsUrl": null, "debug": true, "defaultLanguage": "en", + "themes": ["taiga"], + "defaultTheme": "taiga", "publicRegisterEnabled": true, "feedbackEnabled": true, "privacyPolicyUrl": null, diff --git a/app/coffee/modules/auth.coffee b/app/coffee/modules/auth.coffee index 17c13a4a..55e7ea9a 100644 --- a/app/coffee/modules/auth.coffee +++ b/app/coffee/modules/auth.coffee @@ -37,9 +37,11 @@ class AuthService extends taiga.Service "$tgUrls", "$tgConfig", "$translate", - "tgCurrentUserService"] + "tgCurrentUserService", + "tgThemeService"] - constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService) -> + constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService, + @themeService) -> super() userModel = @.getUser() @.setUserdata(userModel) @@ -51,9 +53,12 @@ class AuthService extends taiga.Service else @.userData = null + _setTheme: -> + theme = @rootscope.user?.theme || @config.get("defaultTheme") || "taiga" + @themeService.use(theme) _setLocales: -> - lang = @rootscope.user.lang || @config.get("defaultLanguage") || "en" + lang = @rootscope.user?.lang || @config.get("defaultLanguage") || "en" @translate.preferredLanguage(lang) # Needed for calls to the api in the correct language @translate.use(lang) # Needed for change the interface in runtime @@ -66,6 +71,7 @@ class AuthService extends taiga.Service user = @model.make_model("users", userData) @rootscope.user = user @._setLocales() + @._setTheme() return user return null @@ -78,6 +84,7 @@ class AuthService extends taiga.Service @.setUserdata(user) @._setLocales() + @._setTheme() clear: -> @rootscope.auth = null @@ -117,9 +124,12 @@ class AuthService extends taiga.Service logout: -> @.removeToken() @.clear() - @currentUserService.removeUser() + @._setTheme() + @._setLocales() + + register: (data, type, existing) -> url = @urls.resolve("auth-register") diff --git a/app/coffee/modules/user-settings/main.coffee b/app/coffee/modules/user-settings/main.coffee index 151cc2dc..8d67c99e 100644 --- a/app/coffee/modules/user-settings/main.coffee +++ b/app/coffee/modules/user-settings/main.coffee @@ -57,6 +57,7 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin) @location.replace() @scope.lang = @getLan() + @scope.theme = @getTheme() maxFileSize = @config.get("maxUploadFileSize", null) if maxFileSize @@ -68,6 +69,8 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin) promise.then null, @.onInitialDataError.bind(@) loadInitialData: -> + @scope.availableThemes = @config.get("themes", []) + return @rs.locales.list().then (locales) => @scope.locales = locales return locales @@ -79,6 +82,11 @@ class UserSettingsController extends mixOf(taiga.Controller, taiga.PageMixin) return @scope.user.lang || @translate.preferredLanguage() + getTheme: -> + return @scope.user.theme || + @config.get("defaultTheme") || + "taiga" + module.controller("UserSettingsController", UserSettingsController) @@ -96,6 +104,7 @@ UserProfileDirective = ($confirm, $auth, $repo, $translate) -> changeEmail = $scope.user.isAttributeModified("email") $scope.user.lang = $scope.lang + $scope.user.theme = $scope.theme onSuccess = (data) => $auth.setUser(data) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index 2a06e9de..b2ca0d4c 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -1193,7 +1193,9 @@ "BIO": "Bio (max. 210 chars)", "PLACEHOLDER_BIO": "Tell us something about you", "LANGUAGE": "Language", - "LANGUAGE_DEFAULT": "-- use default language --" + "LANGUAGE_DEFAULT": "-- use default language --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/modules/services/theme.service.coffee b/app/modules/services/theme.service.coffee new file mode 100644 index 00000000..4e5733ce --- /dev/null +++ b/app/modules/services/theme.service.coffee @@ -0,0 +1,15 @@ +taiga = @.taiga + + +class ThemeService extends taiga.Service = -> + use: (themeName) -> + stylesheetEl = $("link[rel='stylesheet']") + + if stylesheetEl.length == 0 + stylesheetEl = $("") + $("head").append(stylesheetEl) + + stylesheetEl.attr("href", "/styles/theme-#{themeName}.css") + + +angular.module("taigaCommon").service("tgThemeService", ThemeService) diff --git a/app/modules/services/theme.service.spec.coffee b/app/modules/services/theme.service.spec.coffee new file mode 100644 index 00000000..17a208f0 --- /dev/null +++ b/app/modules/services/theme.service.spec.coffee @@ -0,0 +1,17 @@ +describe "ThemeService", -> + themeService = null + data = { + theme: "testTheme" + } + + _inject = () -> + inject (_tgThemeService_) -> + themeService = _tgThemeService_ + + beforeEach -> + module "taigaCommon" + _inject() + + it "use a test theme", () -> + themeService.use(data.theme) + expect($("link[rel='stylesheet']")).to.have.attr("href", "/styles/theme-#{data.theme}.css") diff --git a/app/partials/user/user-profile.jade b/app/partials/user/user-profile.jade index 872b6e79..dd94f565 100644 --- a/app/partials/user/user-profile.jade +++ b/app/partials/user/user-profile.jade @@ -30,7 +30,7 @@ div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl", div.data fieldset - label(for="email", translate="USER_PROFILE.FIELD.USERNAME") + label(for="username", translate="USER_PROFILE.FIELD.USERNAME") input(type="text", name="username", id="username", placeholder="{{'USER_PROFILE.FIELD.USERNAME' | translate}}", ng-model="user.username", data-required="true", data-maxlength="255", @@ -51,16 +51,23 @@ div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl", data-maxlength="256") fieldset - label(for="full-name", translate="USER_PROFILE.FIELD.LANGUAGE") - select(ng-model="lang", + label(for="lang", translate="USER_PROFILE.FIELD.LANGUAGE") + select(name="lang", id="lang", ng-model="lang", ng-options="locale.code as locale.name for locale in locales") option(value="", translate="USER_PROFILE.FIELD.LANGUAGE_DEFAULT") + fieldset + label(for="theme", translate="USER_PROFILE.FIELD.THEME") + select(name="theme", id="theme", ng-model="theme", + ng-options="availableTheme for availableTheme in availableThemes") + option(value="", translate="USER_PROFILE.FIELD.THEME_DEFAULT") + fieldset label(for="bio", translate="USER_PROFILE.FIELD.BIO") textarea(name="bio", id="bio", ng-model="user.bio", - ng-attr-placeholder="{{'USER_PROFILE.FIELD.PLACEHOLDER_BIO' | translate}}", ng-maxlength="210", maxlength="210") + ng-attr-placeholder="{{'USER_PROFILE.FIELD.PLACEHOLDER_BIO' | translate}}", + ng-maxlength="210", maxlength="210") fieldset.submit button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", diff --git a/conf/conf.example.json b/conf/conf.example.json index 2a78a5ea..d039bb77 100644 --- a/conf/conf.example.json +++ b/conf/conf.example.json @@ -4,6 +4,8 @@ "debug": true, "debugInfo": false, "defaultLanguage": "en", + "themes": ["taiga"], + "defaultTheme": "taiga", "publicRegisterEnabled": true, "feedbackEnabled": true, "privacyPolicyUrl": null, From ac8894e62d3268867ac4c4038adf64696ac3fba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Fri, 19 Jun 2015 15:35:32 +0200 Subject: [PATCH 060/403] Create sample themes: meterial-design, high-contrast --- app-loader/app-loader.coffee | 2 +- .../home/projects/home-project-list.scss | 2 +- .../navigation-bar/navigation-bar.scss | 16 +- .../profile/styles/profile-contacts.scss | 2 +- .../profile/styles/profile-content-tabs.scss | 2 +- .../profile/styles/profile-favorites.scss | 2 +- .../profile/styles/profile-sidebar.scss | 2 +- .../projects/listing/projects-listing.scss | 2 +- .../projects/listing/styles/project-list.scss | 2 +- .../user-timeline/user-timeline.scss | 4 +- app/styles/components/buttons.scss | 12 +- app/styles/components/check.scss | 2 +- app/styles/components/created-by.scss | 2 +- app/styles/components/kanban-task.scss | 20 +- app/styles/components/markdown-help.scss | 2 +- .../components/notification-message.scss | 2 +- app/styles/components/paginator.scss | 2 +- app/styles/components/summary.scss | 10 +- app/styles/components/tag.scss | 4 +- app/styles/components/taskboard-task.scss | 20 +- app/styles/components/wysiwyg.scss | 4 +- app/styles/core/base.scss | 19 -- app/styles/core/elements.scss | 13 +- app/styles/core/forms.scss | 10 +- app/styles/core/typography.scss | 4 +- app/styles/dependencies/helpers.scss | 12 - app/styles/dependencies/mixins.scss | 2 +- app/styles/layout/admin-project-values.scss | 5 - app/styles/layout/invitation.scss | 2 +- app/styles/layout/login.scss | 8 +- app/styles/layout/not-found.scss | 4 +- app/styles/layout/team.scss | 2 +- app/styles/layout/us-detail.scss | 12 +- .../admin/admin-custom-attributes.scss | 4 +- .../modules/admin/admin-functionalities.scss | 2 +- .../modules/admin/admin-membership-table.scss | 3 - .../modules/admin/admin-project-profile.scss | 4 +- app/styles/modules/admin/admin-roles.scss | 2 +- app/styles/modules/admin/admin-submenu.scss | 4 +- .../admin/admin-third-parties-webhooks.scss | 12 +- app/styles/modules/admin/project-values.scss | 4 +- app/styles/modules/backlog/backlog-table.scss | 12 +- app/styles/modules/backlog/sprints.scss | 8 +- .../modules/backlog/taskboard-table.scss | 9 +- app/styles/modules/common/assigned-to.scss | 2 +- app/styles/modules/common/attachments.scss | 12 +- .../modules/common/category-config.scss | 2 +- app/styles/modules/common/colors-table.scss | 6 +- app/styles/modules/common/custom-fields.scss | 2 +- .../modules/common/external-reference.scss | 2 +- app/styles/modules/common/history.scss | 18 +- app/styles/modules/common/lightbox.scss | 12 +- app/styles/modules/common/nav.scss | 9 +- app/styles/modules/common/projects-nav.scss | 141 ---------- app/styles/modules/common/related-tasks.scss | 4 +- app/styles/modules/common/wizard.scss | 12 +- app/styles/modules/create-project.scss | 2 +- app/styles/modules/filters/filters.scss | 4 +- app/styles/modules/home-project.scss | 6 +- app/styles/modules/issues/issues-table.scss | 4 +- app/styles/modules/kanban/kanban-table.scss | 2 +- .../modules/search/search-result-table.scss | 5 +- app/styles/modules/team/team-filters.scss | 2 +- app/styles/modules/team/team-table.scss | 2 +- .../mail-notifications-table.scss | 4 +- app/styles/modules/wiki/wiki-summary.scss | 2 +- app/themes/high-contrast/custom.scss | 117 +++++++++ app/themes/high-contrast/variables.scss | 237 +++++++++++++++++ app/themes/material-design/custom.scss | 5 + app/themes/material-design/variables.scss | 246 ++++++++++++++++++ app/themes/taiga/custom.scss | 5 + app/themes/taiga/variables.scss | 226 +++++++++++++++- 72 files changed, 984 insertions(+), 380 deletions(-) delete mode 100644 app/styles/modules/common/projects-nav.scss create mode 100644 app/themes/high-contrast/custom.scss create mode 100755 app/themes/high-contrast/variables.scss create mode 100644 app/themes/material-design/custom.scss create mode 100755 app/themes/material-design/variables.scss diff --git a/app-loader/app-loader.coffee b/app-loader/app-loader.coffee index 02f5ad87..47f6b4c4 100644 --- a/app-loader/app-loader.coffee +++ b/app-loader/app-loader.coffee @@ -4,7 +4,7 @@ window.taigaConfig = { "eventsUrl": null, "debug": true, "defaultLanguage": "en", - "themes": ["taiga"], + "themes": ["taiga", "material-design", "high-contrast"], "defaultTheme": "taiga", "publicRegisterEnabled": true, "feedbackEnabled": true, diff --git a/app/modules/home/projects/home-project-list.scss b/app/modules/home/projects/home-project-list.scss index 3b322609..abdaed0d 100644 --- a/app/modules/home/projects/home-project-list.scss +++ b/app/modules/home/projects/home-project-list.scss @@ -7,7 +7,7 @@ padding: 1rem; text-overflow: ellipsis; &:hover { - border-color: $fresh-taiga; + border-color: $primary-light; transition: all .3s linear; p { color: $gray; diff --git a/app/modules/navigation-bar/navigation-bar.scss b/app/modules/navigation-bar/navigation-bar.scss index c00e7f68..13702f76 100644 --- a/app/modules/navigation-bar/navigation-bar.scss +++ b/app/modules/navigation-bar/navigation-bar.scss @@ -1,11 +1,11 @@ +$dropdown-width: 350px; + .navbar { - background: rgba($black, .5); display: flex; height: $navbar; justify-content: space-between; position: relative; &:after { - background: url('../images/menu-vert.png') repeat top left; background-size: 200%; bottom: 0; content: ''; @@ -24,6 +24,7 @@ } .nav-left { >a { + color: $white; padding: .5rem 1.5rem; &.logo { background: rgba($black, .2); @@ -41,6 +42,7 @@ .nav-right { margin-left: auto; a { + color: $white; padding: .5rem 2rem; } } @@ -48,10 +50,12 @@ color: $white; display: inline-block; transition: all .2s linear; - &.active, + svg path { + fill: darken($primary-dark, 8%); + } &:hover { background: rgba($black, .2); - color: $fresh-taiga; + color: $primary-light; svg path { fill: $white; } @@ -77,7 +81,7 @@ height: 1.2rem; max-width: 1.2rem; path { - fill: $dark-taiga; + fill: $top-icon-color; transition: all .2s; } } @@ -130,7 +134,7 @@ padding: .8rem .5rem; &:hover { background: rgba($white, .1); - color: $fresh-taiga; + color: $primary-light; } &.see-more-projects-btn, &.create-organization-btn, diff --git a/app/modules/profile/styles/profile-contacts.scss b/app/modules/profile/styles/profile-contacts.scss index c9bce8e7..baa0dfe5 100644 --- a/app/modules/profile/styles/profile-contacts.scss +++ b/app/modules/profile/styles/profile-contacts.scss @@ -16,7 +16,7 @@ &:hover, &.active { border-bottom: 2px solid $gray-light; - color: $green-taiga; + color: $primary; } } } diff --git a/app/modules/profile/styles/profile-content-tabs.scss b/app/modules/profile/styles/profile-content-tabs.scss index 648d9d7f..492778cc 100644 --- a/app/modules/profile/styles/profile-content-tabs.scss +++ b/app/modules/profile/styles/profile-content-tabs.scss @@ -18,7 +18,7 @@ top: 1px; transition: color .2s linear; .icon { - color: $green-taiga; + color: $primary; transition: color .2s linear; } } diff --git a/app/modules/profile/styles/profile-favorites.scss b/app/modules/profile/styles/profile-favorites.scss index 23cb806b..43212cd5 100644 --- a/app/modules/profile/styles/profile-favorites.scss +++ b/app/modules/profile/styles/profile-favorites.scss @@ -14,7 +14,7 @@ &:hover, &.active { border-bottom: 2px solid $gray-light; - color: $green-taiga; + color: $primary; } } } diff --git a/app/modules/profile/styles/profile-sidebar.scss b/app/modules/profile/styles/profile-sidebar.scss index 822fb599..944c813c 100644 --- a/app/modules/profile/styles/profile-sidebar.scss +++ b/app/modules/profile/styles/profile-sidebar.scss @@ -16,7 +16,7 @@ color: $gray-light; } a { - color: $green-taiga; + color: $primary; } .trans-button { margin-bottom: 1rem; diff --git a/app/modules/projects/listing/projects-listing.scss b/app/modules/projects/listing/projects-listing.scss index 0b329d2d..6b0f99b8 100644 --- a/app/modules/projects/listing/projects-listing.scss +++ b/app/modules/projects/listing/projects-listing.scss @@ -58,7 +58,7 @@ } .active { .icon { - color: $star-fill; + color: $primary-light; } } } diff --git a/app/modules/projects/listing/styles/project-list.scss b/app/modules/projects/listing/styles/project-list.scss index 8ba28f14..c4dc2dfd 100644 --- a/app/modules/projects/listing/styles/project-list.scss +++ b/app/modules/projects/listing/styles/project-list.scss @@ -47,7 +47,7 @@ .project-list-single { background: $white; &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); cursor: move; transition: background .3s; .drag { diff --git a/app/modules/user-timeline/user-timeline/user-timeline.scss b/app/modules/user-timeline/user-timeline/user-timeline.scss index 4f93fe7b..192afee8 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.scss +++ b/app/modules/user-timeline/user-timeline/user-timeline.scss @@ -7,13 +7,13 @@ margin-bottom: 0; } a { - color: $green-taiga; + color: $primary; &:first-child { @extend %bold; color: $gray; } &:hover { - color: $fresh-taiga; + color: $primary-light; } } blockquote { diff --git a/app/styles/components/buttons.scss b/app/styles/components/buttons.scss index 061f9b68..af107dde 100755 --- a/app/styles/components/buttons.scss +++ b/app/styles/components/buttons.scss @@ -46,7 +46,7 @@ &.active { span, .icon { - color: $green-taiga; + color: $primary; } } } @@ -59,10 +59,10 @@ .button-green, a.button-green { @extend %button; - background: $green-taiga; + background: $primary; &:hover, &.active { - background: $fresh-taiga; + background: $primary-light; color: $white; } } @@ -73,7 +73,7 @@ a.button-gray { background: $gray; &:hover, &.active { - background: $fresh-taiga; + background: $primary-light; color: $white; } } @@ -111,13 +111,13 @@ a.button-gray { .button-bulk { @extend %button; - background: $green-taiga; + background: $primary; padding: .35rem .5rem; .icon { margin-right: 0; } &:hover { - background: $fresh-taiga; + background: $primary-light; } } diff --git a/app/styles/components/check.scss b/app/styles/components/check.scss index 3fbce268..ecd64fd5 100644 --- a/app/styles/components/check.scss +++ b/app/styles/components/check.scss @@ -39,7 +39,7 @@ } input:checked { + div { - background-color: $fresh-taiga; + background-color: $primary-light; margin-left: 50%; transition: all .2s linear; } diff --git a/app/styles/components/created-by.scss b/app/styles/components/created-by.scss index bff30e0a..f021993a 100644 --- a/app/styles/components/created-by.scss +++ b/app/styles/components/created-by.scss @@ -23,7 +23,7 @@ } .created-user { @extend %large; - color: $green-taiga; + color: $primary; cursor: default; &.editable { cursor: pointer; diff --git a/app/styles/components/kanban-task.scss b/app/styles/components/kanban-task.scss index 00dcb01f..2aa34c30 100644 --- a/app/styles/components/kanban-task.scss +++ b/app/styles/components/kanban-task.scss @@ -1,6 +1,6 @@ .kanban-task { - background: $postit; - border: 1px solid $postit-hover; + background: $card; + border: 1px solid $card-hover; box-shadow: none; cursor: move; margin: .2rem; @@ -11,7 +11,7 @@ &:hover { .icon-edit, .icon-drag-h { - color: $postit-dark-hover; + color: $card-dark; display: block; opacity: 1; transition: color .3s linear, opacity .3s linear; @@ -34,12 +34,12 @@ } } .kanban-tagline { - border-color: $postit-hover; + border-color: $card-hover; display: flex; height: .6rem; } .kanban-tag { - border-top: .3rem solid $postit-hover; + border-top: .3rem solid $card-hover; flex-basis: 0; flex-grow: 1; height: .6rem; @@ -66,7 +66,7 @@ img { margin: 0 auto; &:hover { - border: 2px solid $green-taiga; + border: 2px solid $primary; transition: border .3s linear; } } @@ -77,7 +77,7 @@ padding: 0 .5rem 0 .8rem; } .task-assigned { - color: $postit-dark-hover; + color: $card-dark; display: block; } .task-num { @@ -90,12 +90,12 @@ .icon-edit, .icon-drag-h { @extend %large; - color: $postit-hover; + color: $card-hover; opacity: 0; position: absolute; transition: opacity .2s linear; &:hover { - color: darken($postit-hover, 15%); + color: darken($card-hover, 15%); transition: color .3s linear; } } @@ -144,7 +144,7 @@ } .task-points { @extend %small; - color: darken($postit-hover, 15%); + color: darken($card-hover, 15%); margin: 0; span { display: inline-block; diff --git a/app/styles/components/markdown-help.scss b/app/styles/components/markdown-help.scss index 36ad3ea3..f43ae37b 100644 --- a/app/styles/components/markdown-help.scss +++ b/app/styles/components/markdown-help.scss @@ -8,7 +8,7 @@ a.help-button { transition: color .2s linear; } .icon { - color: $fresh-taiga; + color: $primary-light; transition: color .2s linear; } } diff --git a/app/styles/components/notification-message.scss b/app/styles/components/notification-message.scss index f43d9a50..e2e9e451 100644 --- a/app/styles/components/notification-message.scss +++ b/app/styles/components/notification-message.scss @@ -1,5 +1,5 @@ .notification-message-success { - background: rgba($fresh-taiga, .95); + background: rgba($primary-light, .95); box-shadow: 0 25px 10px -15px rgba(0, 0, 0, .05); opacity: 1; right: -370px; diff --git a/app/styles/components/paginator.scss b/app/styles/components/paginator.scss index 4d8f4ad8..56d0d908 100644 --- a/app/styles/components/paginator.scss +++ b/app/styles/components/paginator.scss @@ -24,7 +24,7 @@ } .active { span { - background: $fresh-taiga; + background: $primary-light; } } .dots { diff --git a/app/styles/components/summary.scss b/app/styles/components/summary.scss index 8137273b..e99527b1 100644 --- a/app/styles/components/summary.scss +++ b/app/styles/components/summary.scss @@ -15,7 +15,7 @@ $summary-background: $grayer; } .data { .number { - color: $fresh-taiga; + color: $primary-light; } } .number { @@ -82,7 +82,7 @@ $summary-background: $grayer; position: relative; width: 15%; .current-progress { - background: $fresh-taiga; + background: $primary-light; height: 24px; } .defined-points { @@ -97,7 +97,7 @@ $summary-background: $grayer; position: absolute; } .closed-points-progress { - background: $fresh-taiga; + background: $primary-light; height: 24px; position: absolute; } @@ -136,11 +136,11 @@ $summary-background: $grayer; float: right; transition: color .3s linear; &:hover { - color: $fresh-taiga; + color: $primary-light; transition: color .3s linear; } &.active { - color: $fresh-taiga; + color: $primary-light; } &.active:hover { color: $green-taiga; diff --git a/app/styles/components/tag.scss b/app/styles/components/tag.scss index e08792ac..c5212e97 100644 --- a/app/styles/components/tag.scss +++ b/app/styles/components/tag.scss @@ -22,7 +22,7 @@ border: 1px solid $gray-light; z-index: 99910; .ui-state-focus { - background: $fresh-taiga; + background: $primary-light; } li { cursor: pointer; @@ -49,7 +49,7 @@ .add-tag { color: $gray-light; &:hover { - color: $fresh-taiga; + color: $primary-light; } } .icon-plus { diff --git a/app/styles/components/taskboard-task.scss b/app/styles/components/taskboard-task.scss index 07dd5ca6..8e94caab 100644 --- a/app/styles/components/taskboard-task.scss +++ b/app/styles/components/taskboard-task.scss @@ -1,6 +1,6 @@ .taskboard-task { - background: $postit; - border: 1px solid $postit-hover; + background: $card; + border: 1px solid $card-hover; box-shadow: none; cursor: move; margin: .2rem; @@ -8,7 +8,7 @@ &:hover { .icon-edit, .icon-drag-h { - color: $postit-dark-hover; + color: $card-dark; display: block; opacity: 1; transition: color .3s linear, opacity .3s linear; @@ -37,12 +37,12 @@ } } .taskboard-tagline { - border-color: $postit-hover; + border-color: $card-hover; display: flex; height: .6rem; } .taskboard-tag { - border-top: .3rem solid $postit-hover; + border-top: .3rem solid $card-hover; flex-basis: 0; flex-grow: 1; height: .6rem; @@ -64,7 +64,7 @@ img { margin: 0 auto; &:hover { - border: 2px solid $green-taiga; + border: 2px solid $primary; transition: border .3s linear; } } @@ -86,10 +86,10 @@ } .task-assigned { @extend %small; - color: $postit-dark-hover; + color: $card-dark; display: block; &:hover { - color: $green-taiga; + color: $primary; } } .task-num { @@ -113,11 +113,11 @@ .icon-drag-h { @extend %large; bottom: .5rem; - color: $postit-hover; + color: $card-hover; opacity: 0; position: absolute; &:hover { - color: $postit-dark-hover; + color: $card-dark; } } .icon-edit { diff --git a/app/styles/components/wysiwyg.scss b/app/styles/components/wysiwyg.scss index 18dfa7af..c742fbf3 100644 --- a/app/styles/components/wysiwyg.scss +++ b/app/styles/components/wysiwyg.scss @@ -40,9 +40,9 @@ } } a { - color: $green-taiga; + color: $primary; &:hover { - color: $fresh-taiga; + color: $primary-light; } } p { diff --git a/app/styles/core/base.scss b/app/styles/core/base.scss index aa891e32..55e5b543 100644 --- a/app/styles/core/base.scss +++ b/app/styles/core/base.scss @@ -5,8 +5,6 @@ html { } body { @extend %text; - background: $white; // fallback - color: $grayer; line-height: 1.3; min-height: 100%; width: 100%; @@ -17,15 +15,6 @@ body { } &.loading-project { overflow: hidden; - .projects-nav-overlay { - opacity: 1; - overflow: hidden; - transition: opacity 1s ease; - div { - opacity: 1; - transition: opacity 1s ease; - } - } } } @@ -38,7 +27,6 @@ body { } .master { - background: $white; height: 100%; min-height: 100%; position: relative; @@ -57,7 +45,6 @@ body { } .menu-secondary { - background: $whitish; flex: 0 0 auto; min-height: $main-height; min-width: 0; @@ -84,17 +71,11 @@ body { } .menu-tertiary { - background-color: $dark-taiga; flex: 0 0 auto; min-height: $main-height; width: 250px; } -.extrabar { - background: $whitish; -} - -%main, .main { flex: 4; flex-basis: 600px; diff --git a/app/styles/core/elements.scss b/app/styles/core/elements.scss index 6644404e..9c42a1b8 100644 --- a/app/styles/core/elements.scss +++ b/app/styles/core/elements.scss @@ -3,16 +3,13 @@ // Blockquotes blockquote, blockquote p { - color: $gray; line-height: 1.25rem; } blockquote { - border-left: 5px solid $whitish; margin: 0 0 20px; padding: .5rem 1.25rem; cite { @extend %small; - color: $gray; display: block; &:before { content: '\2014 \0020'; @@ -59,14 +56,14 @@ sup { } .is-selected { .pika-button { - background: $green-taiga; + background: $primary; border-radius: 0 !important; - box-shadow: inset 0 1px 3px $green-taiga; + box-shadow: inset 0 1px 3px $primary; } } .is-today { .pika-button { - color: $green-taiga; + color: $primary; } &.is-selected { button { @@ -76,9 +73,9 @@ sup { } .pika-button { &:hover { - background: $fresh-taiga !important; //Important added because plugin has it :S + background: $primary-light !important; //Important added because plugin has it :S border-radius: 0 !important; //Important added because plugin has it :S - box-shadow: inset 0 1px 3px $fresh-taiga !important; //Important added because plugin has it :S + box-shadow: inset 0 1px 3px $primary-light !important; //Important added because plugin has it :S } } } diff --git a/app/styles/core/forms.scss b/app/styles/core/forms.scss index efc8d085..22b5e476 100644 --- a/app/styles/core/forms.scss +++ b/app/styles/core/forms.scss @@ -19,17 +19,11 @@ input[type="date"], input[type="password"], select, textarea { - background: $whitish; - border: 1px solid $gray-light; - color: $grayer; + border: 1px solid; margin: 0; padding: 8px; width: 100%; - @include placeholder { - color: darken($gray-light, 10%); - } &.checksley-error { - border: 1px solid $red; transition: border .3s linear; } } @@ -42,14 +36,12 @@ textarea { .checksley-error-list { @extend %small; - background: rgba($whitish, .8); margin-bottom: 0; padding: 0 .5rem; position: absolute; right: 2rem; top: 10px; li { - color: $red; padding: .2rem; } } diff --git a/app/styles/core/typography.scss b/app/styles/core/typography.scss index 44a8eff3..6e106f99 100755 --- a/app/styles/core/typography.scss +++ b/app/styles/core/typography.scss @@ -53,7 +53,7 @@ h1 { max-width: 40%; } .green { - color: $green-taiga; + color: $primary; } .date { @include ellipsis(500px); @@ -92,10 +92,8 @@ hr { // __Links__ a, a:visited { - color: $grayer; text-decoration: none; &:hover { - color: $green-taiga; transition: color .3s linear; } } diff --git a/app/styles/dependencies/helpers.scss b/app/styles/dependencies/helpers.scss index 336ce8ce..45286c94 100644 --- a/app/styles/dependencies/helpers.scss +++ b/app/styles/dependencies/helpers.scss @@ -16,7 +16,6 @@ %mono {font-family: 'courier new', 'monospace';} %lightbox { - background: rgba($white, .95); bottom: 0; display: none; left: 0; @@ -62,17 +61,6 @@ } } -// Background -%triangled-bg { - background: url('/images/bg.png') no-repeat center center; - background-size: cover; -} - -%background-taiga { - background: url('/images/invitation_bg.jpg') no-repeat center center; - background-size: cover; -} - %loading-spinner { animation-timing-function: ease-in-out; animation: rotate 1.5s cubic-bezier(.00, .05, .87, 1.04) infinite alternate; diff --git a/app/styles/dependencies/mixins.scss b/app/styles/dependencies/mixins.scss index 755f4511..cdde2e53 100644 --- a/app/styles/dependencies/mixins.scss +++ b/app/styles/dependencies/mixins.scss @@ -57,7 +57,7 @@ border: 0; } &:hover { - color: $fresh-taiga; + color: $primary-light; transition: color .3s linear; &.point { color: $white; diff --git a/app/styles/layout/admin-project-values.scss b/app/styles/layout/admin-project-values.scss index 749d7178..4f9d20fd 100644 --- a/app/styles/layout/admin-project-values.scss +++ b/app/styles/layout/admin-project-values.scss @@ -37,8 +37,3 @@ display: inline-block; } } - -//.project-values-options { -// margin-bottom: 1rem; -// text-align: right; -//} diff --git a/app/styles/layout/invitation.scss b/app/styles/layout/invitation.scss index 6807a2d9..ee0c39c9 100644 --- a/app/styles/layout/invitation.scss +++ b/app/styles/layout/invitation.scss @@ -84,7 +84,7 @@ } .button-blackish { &:hover { - background: $green-taiga; + background: $primary; } } .login-form { diff --git a/app/styles/layout/login.scss b/app/styles/layout/login.scss index 95c61fff..8e20b643 100644 --- a/app/styles/layout/login.scss +++ b/app/styles/layout/login.scss @@ -41,17 +41,11 @@ form { margin-bottom: 1rem; } - input { - background: $white; - @include placeholder { - color: $gray-light; - } - } .login-text, .register-text { text-align: center; a:hover { - color: $fresh-taiga; + color: $primary-light; } } .button { diff --git a/app/styles/layout/not-found.scss b/app/styles/layout/not-found.scss index 3959acf9..a7ced5bb 100644 --- a/app/styles/layout/not-found.scss +++ b/app/styles/layout/not-found.scss @@ -25,9 +25,9 @@ margin-bottom: 3rem; } a { - color: $green-taiga; + color: $primary; &:hover { - color: $fresh-taiga; + color: $primary-light; } } } diff --git a/app/styles/layout/team.scss b/app/styles/layout/team.scss index fba2c6e2..862fbcd3 100644 --- a/app/styles/layout/team.scss +++ b/app/styles/layout/team.scss @@ -3,7 +3,7 @@ margin: 1rem 0; span { &:last-child { - color: $green-taiga; + color: $primary; } } } diff --git a/app/styles/layout/us-detail.scss b/app/styles/layout/us-detail.scss index 9a4e8bdf..f3ea42fe 100644 --- a/app/styles/layout/us-detail.scss +++ b/app/styles/layout/us-detail.scss @@ -103,7 +103,7 @@ padding: 0 .2rem; } a:hover { - color: $green-taiga; + color: $primary; } a:first-child { border: 0; @@ -237,7 +237,7 @@ .us-detail-status { @extend %large; - color: $green-taiga; + color: $primary; vertical-align: middle; } @@ -247,7 +247,7 @@ margin-bottom: 1rem; position: relative; .current-progress { - background: $fresh-taiga; + background: $primary-light; height: 26px; left: 0; position: absolute; @@ -281,7 +281,7 @@ text-align: center; transition: color .3s linear; &.active { - background: rgba($fresh-taiga, .9); + background: rgba($primary-light, .9); color: $whitish; } &:first-child { @@ -316,7 +316,7 @@ text-align: center; &:hover, &.active { - background: $fresh-taiga; + background: $primary-light; color: $white; } } @@ -381,7 +381,7 @@ } } &.active { - background: $green-taiga; + background: $primary; } } .item-block { diff --git a/app/styles/modules/admin/admin-custom-attributes.scss b/app/styles/modules/admin/admin-custom-attributes.scss index e0fdfff0..ee7a21d5 100644 --- a/app/styles/modules/admin/admin-custom-attributes.scss +++ b/app/styles/modules/admin/admin-custom-attributes.scss @@ -24,7 +24,7 @@ } } .row:hover { - background: rgba($fresh-taiga, .05); + background: rgba($primary-light, .05); cursor: move; transition: background .2s linear; .icon-drag-v, @@ -89,7 +89,7 @@ transition: color .2s linear; vertical-align: middle; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s linear; } } diff --git a/app/styles/modules/admin/admin-functionalities.scss b/app/styles/modules/admin/admin-functionalities.scss index 9f0842fe..1a02ff99 100644 --- a/app/styles/modules/admin/admin-functionalities.scss +++ b/app/styles/modules/admin/admin-functionalities.scss @@ -19,7 +19,7 @@ vertical-align: top; width: 32%; &.active { - background-color: rgba($green-taiga, .3); + background-color: rgba($primary, .3); opacity: 1; } .icon { diff --git a/app/styles/modules/admin/admin-membership-table.scss b/app/styles/modules/admin/admin-membership-table.scss index 544dc21f..b3420b3c 100644 --- a/app/styles/modules/admin/admin-membership-table.scss +++ b/app/styles/modules/admin/admin-membership-table.scss @@ -55,9 +55,6 @@ .pending { background-color: $red-light; color: $white; - .icon { - float: rsdsdfdvsdvight; - } &:hover { background-color: $red; color: $white; diff --git a/app/styles/modules/admin/admin-project-profile.scss b/app/styles/modules/admin/admin-project-profile.scss index cefec654..b7376f39 100644 --- a/app/styles/modules/admin/admin-project-profile.scss +++ b/app/styles/modules/admin/admin-project-profile.scss @@ -54,8 +54,8 @@ } .privacy-project:checked { + label { - background: $fresh-taiga; - border: 1px solid $fresh-taiga; + background: $primary-light; + border: 1px solid $primary-light; span { color: $white; } diff --git a/app/styles/modules/admin/admin-roles.scss b/app/styles/modules/admin/admin-roles.scss index 83e0511c..ec2049c8 100644 --- a/app/styles/modules/admin/admin-roles.scss +++ b/app/styles/modules/admin/admin-roles.scss @@ -27,7 +27,7 @@ margin-left: .5rem; transition: color.3s linear; &:hover { - color: $green-taiga; + color: $primary; transition: color.3s linear; } } diff --git a/app/styles/modules/admin/admin-submenu.scss b/app/styles/modules/admin/admin-submenu.scss index 5a66bf60..6b019c83 100644 --- a/app/styles/modules/admin/admin-submenu.scss +++ b/app/styles/modules/admin/admin-submenu.scss @@ -15,12 +15,12 @@ justify-content: space-between; padding: 1rem 0 1rem 1rem; &:hover { - background: lighten($dark-taiga, 3%); + background: lighten($primary-dark, 3%); color: $white; transition: all .2s; } &.active { - background: lighten($dark-taiga, 10%); + background: lighten($primary-dark, 10%); color: $white; transition: all .2s; } diff --git a/app/styles/modules/admin/admin-third-parties-webhooks.scss b/app/styles/modules/admin/admin-third-parties-webhooks.scss index d3a69af5..8ef4fa0c 100644 --- a/app/styles/modules/admin/admin-third-parties-webhooks.scss +++ b/app/styles/modules/admin/admin-third-parties-webhooks.scss @@ -47,10 +47,10 @@ vertical-align: middle; } a { - color: $green-taiga; + color: $primary; margin-left: .5rem; &:hover { - color: $fresh-taiga; + color: $primary-light; } } } @@ -65,7 +65,7 @@ transition: color .2s linear; vertical-align: middle; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s linear; } @@ -102,7 +102,7 @@ padding: .5rem; transition: background .2s linear; &:hover { - background: rgba($fresh-taiga, .1); + background: rgba($primary-light, .1); transition: background .2s linear; } &.history-single-open { @@ -127,7 +127,7 @@ margin-right: .5rem; width: .8rem; &.history-success { - background: $fresh-taiga; + background: $primary-light; } &.history-error { background: $red; @@ -149,7 +149,7 @@ @extend %small; color: $gray-light; &:hover { - color: $fresh-taiga; + color: $primary-light; transition: color .2s linear; } } diff --git a/app/styles/modules/admin/project-values.scss b/app/styles/modules/admin/project-values.scss index e8920a8f..2dded76c 100644 --- a/app/styles/modules/admin/project-values.scss +++ b/app/styles/modules/admin/project-values.scss @@ -33,7 +33,7 @@ } .project-values-row { &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); cursor: move; transition: background .2s ease-in; .icon { @@ -72,7 +72,7 @@ color: $gray; margin-right: .5rem; &:hover { - color: $green-taiga; + color: $primary; transition: color .3s linear; .icon-delete { color: $red; diff --git a/app/styles/modules/backlog/backlog-table.scss b/app/styles/modules/backlog/backlog-table.scss index 00c47757..365ed4c7 100644 --- a/app/styles/modules/backlog/backlog-table.scss +++ b/app/styles/modules/backlog/backlog-table.scss @@ -67,7 +67,7 @@ @include popover(200px, 0, 65%, '', ''); a { &.active { - background: $fresh-taiga; + background: $primary-light; color: $white; } } @@ -90,7 +90,7 @@ text-align: center; &:hover, &.active { - background: $fresh-taiga; + background: $primary-light; color: $white; } } @@ -122,7 +122,7 @@ flex-wrap: nowrap; position: relative; &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; .us-settings, .icon-drag-v { @@ -134,7 +134,7 @@ border-bottom: 0; } &.ui-sortable-helper { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); box-shadow: 1px 1px 10px rgba($black, .1); transition: background .2s ease-in; } @@ -151,7 +151,7 @@ width: 100%; } .row-selected { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } .user-story-name { @@ -163,7 +163,7 @@ margin-right: 1rem; vertical-align: super; &:checked+a { - color: $fresh-taiga; + color: $primary-light; transition: color .2s ease-in; } } diff --git a/app/styles/modules/backlog/sprints.scss b/app/styles/modules/backlog/sprints.scss index c96a21b3..cfb90545 100644 --- a/app/styles/modules/backlog/sprints.scss +++ b/app/styles/modules/backlog/sprints.scss @@ -69,7 +69,7 @@ transition: all .2s linear; } &:hover { - color: $fresh-taiga; + color: $primary-light; transition: color .2s linear; } } @@ -82,7 +82,7 @@ transition: opacity .2s ease-in; vertical-align: baseline; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s ease-in; } } @@ -126,7 +126,7 @@ position: relative; width: 100%; .current-progress { - background: $green-taiga; + background: $primary; border-radius: 2px; height: 8px; left: 0; @@ -158,7 +158,7 @@ height: 40px; } &.ui-sortable-helper { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); box-shadow: 1px 1px 10px rgba($black, .1); transition: background .2s ease-in; } diff --git a/app/styles/modules/backlog/taskboard-table.scss b/app/styles/modules/backlog/taskboard-table.scss index f748be15..6b6b5983 100644 --- a/app/styles/modules/backlog/taskboard-table.scss +++ b/app/styles/modules/backlog/taskboard-table.scss @@ -91,7 +91,7 @@ $column-margin: 0 10px 0 0; margin-right: .3rem; transition: color .2s linear; &:hover { - color: $green-taiga; + color: $primary; } &.hfold, &.hunfold { @@ -178,9 +178,6 @@ $column-margin: 0 10px 0 0; } } } - .taskboard-tasks-box { - background: $whitish; - } .taskboard-userstory-box { padding: .5rem .5rem .5rem 1.5rem; @@ -191,7 +188,7 @@ $column-margin: 0 10px 0 0; top: .7rem; transition: color .2s linear; &:hover { - color: $green-taiga; + color: $primary; } &.icon-plus { right: 2rem; @@ -234,7 +231,7 @@ $column-margin: 0 10px 0 0; .points-list { a { - color: $green-taiga; + color: $primary; margin-left: .5rem; &:hover { span { diff --git a/app/styles/modules/common/assigned-to.scss b/app/styles/modules/common/assigned-to.scss index ee87db88..cfb80a23 100644 --- a/app/styles/modules/common/assigned-to.scss +++ b/app/styles/modules/common/assigned-to.scss @@ -33,7 +33,7 @@ } .user-assigned { @extend %large; - color: $green-taiga; + color: $primary; cursor: default; line-height: 1.5rem; &.editable { diff --git a/app/styles/modules/common/attachments.scss b/app/styles/modules/common/attachments.scss index 374170ae..556324ac 100644 --- a/app/styles/modules/common/attachments.scss +++ b/app/styles/modules/common/attachments.scss @@ -23,7 +23,7 @@ color: $grayer; cursor: pointer; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s ease-in; } } @@ -45,7 +45,7 @@ } } &.ui-sortable-helper { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); box-shadow: 1px 1px 10px rgba($black, .1); transition: background .2s ease-in; } @@ -96,7 +96,7 @@ display: block; position: absolute; &:hover { - color: $green-taiga; + color: $primary; } } .settings { @@ -143,7 +143,7 @@ } } .percentage { - background: rgba($green-taiga, .1); + background: rgba($primary, .1); bottom: 0; height: 40px; left: 0; @@ -162,11 +162,11 @@ color: $gray-light; } .more-attachments-num { - color: $green-taiga; + color: $primary; margin-left: .5rem; } &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } } diff --git a/app/styles/modules/common/category-config.scss b/app/styles/modules/common/category-config.scss index 7a9346d3..f3341d81 100644 --- a/app/styles/modules/common/category-config.scss +++ b/app/styles/modules/common/category-config.scss @@ -28,7 +28,7 @@ margin-right: .1rem; width: 15px; &.active { - background: $green-taiga; + background: $primary; } &.inactive { background: $gray; diff --git a/app/styles/modules/common/colors-table.scss b/app/styles/modules/common/colors-table.scss index 56caeca1..314c87de 100644 --- a/app/styles/modules/common/colors-table.scss +++ b/app/styles/modules/common/colors-table.scss @@ -24,7 +24,7 @@ justify-content: center; padding: 1rem; &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); cursor: move; transition: background .2s ease-in; .icon { @@ -117,7 +117,7 @@ margin-right: 1rem; opacity: 0; &:hover { - color: $green-taiga; + color: $primary; transition: all .2s ease-in; } &.icon-check-square { @@ -131,7 +131,7 @@ } .icon-check-square { @extend %large; - color: $green-taiga; + color: $primary; } } diff --git a/app/styles/modules/common/custom-fields.scss b/app/styles/modules/common/custom-fields.scss index 929546ba..ec336e5e 100644 --- a/app/styles/modules/common/custom-fields.scss +++ b/app/styles/modules/common/custom-fields.scss @@ -43,7 +43,7 @@ color: $gray-light; } a:hover { - color: $green-taiga; + color: $primary; } } } diff --git a/app/styles/modules/common/external-reference.scss b/app/styles/modules/common/external-reference.scss index 7c6c2f43..44336f69 100644 --- a/app/styles/modules/common/external-reference.scss +++ b/app/styles/modules/common/external-reference.scss @@ -20,7 +20,7 @@ padding: 0 .2rem; transition: color .3s linear; &:hover { - color: $green-taiga; + color: $primary; } &:first-child { border: 0; diff --git a/app/styles/modules/common/history.scss b/app/styles/modules/common/history.scss index 688bcb9e..3c6947c3 100644 --- a/app/styles/modules/common/history.scss +++ b/app/styles/modules/common/history.scss @@ -6,7 +6,7 @@ padding: .5rem; &:hover { .icon { - color: $green-taiga; + color: $primary; transform: rotate(180deg); transition: all .2s linear; } @@ -58,7 +58,7 @@ color: $grayer; } &:hover { - color: $green-taiga; + color: $primary; transition: color .2s ease-in; } } @@ -119,7 +119,7 @@ display: block; padding: 1rem 0 1rem 1rem; &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } } @@ -130,7 +130,7 @@ display: block; padding: 1rem; .prev-comments-num { - color: $green-taiga; + color: $primary; margin-left: .5rem; } } @@ -180,7 +180,7 @@ color: $gray-light; margin-left: .3rem; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s linear; } } @@ -206,12 +206,12 @@ vertical-align: baseline; } &:hover { - color: $green-taiga; + color: $primary; transition: color .2s linear; } } .username { - color: $green-taiga; + color: $primary; margin-bottom: .5rem; } .activity-user { @@ -223,7 +223,7 @@ } } .activity-username { - color: $green-taiga; + color: $primary; margin-bottom: .5rem; } .activity-content { @@ -272,7 +272,7 @@ display: block; padding: 1rem; .prev-activity-num { - color: $green-taiga; + color: $primary; margin-left: .5rem; } } diff --git a/app/styles/modules/common/lightbox.scss b/app/styles/modules/common/lightbox.scss index 198e7cbf..baa7fadc 100644 --- a/app/styles/modules/common/lightbox.scss +++ b/app/styles/modules/common/lightbox.scss @@ -57,8 +57,8 @@ .requirement, .iocaine { &:hover { - background: $fresh-taiga; - border: 1px solid $green-taiga; + background: $primary-light; + border: 1px solid $primary; color: $white; transition: all .2s ease-in; } @@ -79,8 +79,8 @@ .team-requirement, .iocaine-flag { input:checked+label { - background: $green-taiga; - border: 1px solid $green-taiga; + background: $primary; + border: 1px solid $primary; color: $white; } @@ -400,7 +400,7 @@ padding: 3px; position: relative; .bar { - background: $fresh-taiga; + background: $primary-light; height: 24px; position: absolute; transition: width .1s linear; @@ -477,7 +477,7 @@ position: relative; &:hover, &.active { - background: lighten($green-taiga, 55%); + background: lighten($primary, 55%); cursor: pointer; } &:hover { diff --git a/app/styles/modules/common/nav.scss b/app/styles/modules/common/nav.scss index b397516c..82d6c1d6 100644 --- a/app/styles/modules/common/nav.scss +++ b/app/styles/modules/common/nav.scss @@ -1,8 +1,6 @@ $label-arrow-wh: 12px; tg-project-menu { - background-color: $dark-taiga; - background-image: url('../images/menu.png'); background-position: 0 -300px; min-height: $main-height; padding: 1rem 0; @@ -22,7 +20,7 @@ tg-project-menu { } a:hover { background: rgba($black, .2); - color: $fresh-taiga; + color: $primary-light; transition: color .3s linear; .helper { @extend %small; @@ -52,7 +50,6 @@ tg-project-menu { } } svg path { - fill: $white; opacity: 1; } span { @@ -70,9 +67,9 @@ tg-project-menu { } .active { background: rgba($black, .2); - color: $fresh-taiga; + color: $primary-light; svg path { - fill: $fresh-taiga; + fill: $primary-light; opacity: 1; } } diff --git a/app/styles/modules/common/projects-nav.scss b/app/styles/modules/common/projects-nav.scss deleted file mode 100644 index ca3d0671..00000000 --- a/app/styles/modules/common/projects-nav.scss +++ /dev/null @@ -1,141 +0,0 @@ -.projects-nav { - background-color: $menu; - display: flex; - flex-direction: column; - height: 100%; - left: 0; - overflow: hidden; - padding: 2rem 1rem; - position: fixed; - top: 0; - transform: translate3d(-300px, 0, 0); - width: 300px; - z-index: 99; - form { - flex-shrink: 0; - } - h1 { - color: $white; - flex-shrink: 0; - margin-bottom: 2rem; - text-align: center; - } - input { - background-color: $gray; - color: $whitish; - } - .icon-search { - position: absolute; - right: .7rem; - top: .7rem; - } - ul { - left: 0; - margin-bottom: 0; - margin-top: 1rem; - position: relative; - top: 0; - width: 100%; - } - .projects-pagination { - display: flex; - flex-direction: column; - margin-top: 1rem; - min-height: 1px; //firefox bug #2057 - } - .create-project-button-wrapper { - display: flex; - flex-shrink: 0; - margin-top: 1rem; - .create-project-button { - flex-grow: 8; - margin-right: .2rem; - text-align: center; - } - .import-project-button { - flex-grow: 1; - padding-left: .5rem; - padding-right: .5rem; - text-align: center; - .icon { - color: $grayer; - margin: 0; - } - } - } - .v-pagination-previous, - .v-pagination-next { - flex-shrink: 0; - } -} - -.projects-list { - a { - @extend %large; - @extend %title; - color: $whitish; - display: block; - padding: 1rem; - position: relative; - text-transform: uppercase; - width: 100%; - &.active, - &:hover { - background-color: $gray; - color: $green-taiga; - transition: background-color .3s linear; - .icon { - opacity: 1; - transition: opacity .3s linear; - } - } - .project-name { - display: block; - max-width: 90%; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } - } - .icon { - color: $whitish; - opacity: 0; - position: absolute; - right: 1rem; - top: 1rem; - } - li { - border-bottom: 2px solid $gray; - } -} - -.projects-nav-overlay { - // @include transition (all 1s ease); - @extend %background-taiga; - // background-blend-mode: multiply; - // background-color: $green-taiga; - bottom: 0; - display: none; - left: 0; - opacity: 0; - position: fixed; - right: 0; - top: 0; - width: 100%; - z-index: 99900; - .container { - left: -200px; - margin: 0 auto; - margin-top: 15%; - opacity: 0; - position: relative; - transform: translateY(-50%); - width: 150px; - } - p { - @extend %medium; - color: $fresh-taiga; - padding-top: 20px; - text-align: center; - } -} diff --git a/app/styles/modules/common/related-tasks.scss b/app/styles/modules/common/related-tasks.scss index e40ff5b8..9655cee8 100644 --- a/app/styles/modules/common/related-tasks.scss +++ b/app/styles/modules/common/related-tasks.scss @@ -19,7 +19,7 @@ color: $grayer; cursor: pointer; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s ease-in; } } @@ -153,7 +153,7 @@ } .iocaine, .iocaine:hover { - background: rgba($fresh-taiga, .3); + background: rgba($primary-light, .3); .icon-iocaine { @extend %large; display: inline-block; diff --git a/app/styles/modules/common/wizard.scss b/app/styles/modules/common/wizard.scss index b06d7a29..75c60ac7 100644 --- a/app/styles/modules/common/wizard.scss +++ b/app/styles/modules/common/wizard.scss @@ -1,6 +1,6 @@ .wizard-create-project { @extend %lightbox; - background: url('/images/invitation_bg.jpg') no-repeat center center; + @extend %background-taiga; background-size: cover; color: $white; text-align: center; @@ -77,7 +77,7 @@ } input:checked { +label { - background: rgba($fresh-taiga, .7); + background: rgba($primary-light, .7); transition: background .3s ease-in; } } @@ -90,7 +90,7 @@ text-align: center; transition: background .3s ease-in; &:hover { - background: rgba($green-taiga, .7); + background: rgba($primary, .7); transition: background .3s ease-in; } .icon { @@ -160,12 +160,8 @@ left: 25%; } &:nth-child(2) { - // left: 50%; left: 75%; } - // &:nth-child(3) { - // left: 75%; - // } } } .progress-bar-wrapper { @@ -173,7 +169,7 @@ height: .5rem; } .bar { - background: rgba($fresh-taiga, .9); + background: rgba($primary-light, .9); height: .5rem; left: 0; position: absolute; diff --git a/app/styles/modules/create-project.scss b/app/styles/modules/create-project.scss index f7958a33..dc22aefd 100644 --- a/app/styles/modules/create-project.scss +++ b/app/styles/modules/create-project.scss @@ -47,7 +47,7 @@ margin-bottom: .5rem; text-align: center; &:hover { - background: $fresh-taiga; + background: $primary-light; } } a { diff --git a/app/styles/modules/filters/filters.scss b/app/styles/modules/filters/filters.scss index 5a5444a7..527f44cc 100644 --- a/app/styles/modules/filters/filters.scss +++ b/app/styles/modules/filters/filters.scss @@ -75,7 +75,7 @@ } .custom-filters { .title { - color: $green-taiga; + color: $primary; } } a { @@ -84,7 +84,7 @@ padding: .5rem 0 .5rem .5rem; transition: color .2s ease-in; &:hover { - color: $green-taiga; + color: $primary; transition: color .2s ease-in; .icon { opacity: 1; diff --git a/app/styles/modules/home-project.scss b/app/styles/modules/home-project.scss index a2b8c816..4956a40e 100644 --- a/app/styles/modules/home-project.scss +++ b/app/styles/modules/home-project.scss @@ -49,9 +49,6 @@ display: flex; flex-wrap: wrap; margin-bottom: 1rem; - a { - display: block; - } li { margin-right: .14rem; width: 24%; @@ -59,6 +56,9 @@ margin-right: 0; } } + a { + display: block; + } img { border-radius: .2rem; width: 100%; diff --git a/app/styles/modules/issues/issues-table.scss b/app/styles/modules/issues/issues-table.scss index 22a4a2ec..99d11211 100644 --- a/app/styles/modules/issues/issues-table.scss +++ b/app/styles/modules/issues/issues-table.scss @@ -6,7 +6,7 @@ } .row { &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } .icon { @@ -14,7 +14,7 @@ } } .row-selected { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } .title { diff --git a/app/styles/modules/kanban/kanban-table.scss b/app/styles/modules/kanban/kanban-table.scss index d4c0485e..63612206 100644 --- a/app/styles/modules/kanban/kanban-table.scss +++ b/app/styles/modules/kanban/kanban-table.scss @@ -87,7 +87,7 @@ $column-margin: 0 10px 0 0; margin-right: .3rem; transition: color .2s linear; &:hover { - color: $green-taiga; + color: $primary; } &.hfold, &.hunfold { diff --git a/app/styles/modules/search/search-result-table.scss b/app/styles/modules/search/search-result-table.scss index f01f2822..db6ec827 100644 --- a/app/styles/modules/search/search-result-table.scss +++ b/app/styles/modules/search/search-result-table.scss @@ -1,5 +1,4 @@ .search-result-table { - .empty { .title { border: 0; @@ -13,7 +12,7 @@ justify-content: space-between; padding: .5rem; &:hover { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } .ref { @@ -40,7 +39,7 @@ } } .row-selected { - background: lighten($green-taiga, 60%); + background: lighten($primary, 60%); transition: background .2s ease-in; } diff --git a/app/styles/modules/team/team-filters.scss b/app/styles/modules/team/team-filters.scss index 1d39765d..e638fe0d 100644 --- a/app/styles/modules/team/team-filters.scss +++ b/app/styles/modules/team/team-filters.scss @@ -18,7 +18,7 @@ padding: 1rem 0 1rem 1rem; &:hover, &.active { - color: $green-taiga; + color: $primary; transition: color .3s linear; } &.active.icon { diff --git a/app/styles/modules/team/team-table.scss b/app/styles/modules/team/team-table.scss index b6ccef7f..a75332d4 100644 --- a/app/styles/modules/team/team-table.scss +++ b/app/styles/modules/team/team-table.scss @@ -28,7 +28,7 @@ color: $grayer; } .top { - color: $fresh-taiga; + color: $primary-light; opacity: 1; } &:hover { diff --git a/app/styles/modules/user-settings/mail-notifications-table.scss b/app/styles/modules/user-settings/mail-notifications-table.scss index 01fffa42..adc7da4b 100644 --- a/app/styles/modules/user-settings/mail-notifications-table.scss +++ b/app/styles/modules/user-settings/mail-notifications-table.scss @@ -33,7 +33,7 @@ display: none; &:checked { +label { - background: $green-taiga; + background: $primary; transition: background .3s linear; } } @@ -45,7 +45,7 @@ display: block; padding: .5rem; &:hover { - background: $fresh-taiga; + background: $primary-light; cursor: pointer; transition: background .3s linear; } diff --git a/app/styles/modules/wiki/wiki-summary.scss b/app/styles/modules/wiki/wiki-summary.scss index 0328f1eb..cadf915f 100644 --- a/app/styles/modules/wiki/wiki-summary.scss +++ b/app/styles/modules/wiki/wiki-summary.scss @@ -22,7 +22,7 @@ } .username { @extend %large; - color: $fresh-taiga; + color: $primary-light; white-space: nowrap; } } diff --git a/app/themes/high-contrast/custom.scss b/app/themes/high-contrast/custom.scss new file mode 100644 index 00000000..4486c097 --- /dev/null +++ b/app/themes/high-contrast/custom.scss @@ -0,0 +1,117 @@ +// Any styles in this stylesheet will override any previous defined style in Taiga. + +// Max: Beat it or I'll call the Brute Squad! +// Fezzik: I'm on the Brute Squad. +// Max: [sees Fezzik's size] You are the Brute Squad! + +.working-on .duty-id, +.watching .duty-id, +.activity-item p, +.table-team .avatar .position, +.points-per-role > li, +.private path { + color: $black; +} +.navbar a:hover { + color: $white; +} + +.points-per-role > li:first-child { + background: $black; +} + +.login-main { + color: $white; + a { + color: $white; + } +} + +.home-project-list { + li { + border: 1px solid $black; + } + p { + color: $black; + } +} + +.main-nav .active { + background: $white; + svg path { + fill: $black; + } +} + +// Titles +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: Arial, Helvetica, sans-serif; + .date { + color: $black; + } +} + +.tag { + background: $white; + border: 1px solid $black; +} + +.master, +.menu-secondary, +.menu-tertiary, +.extrabar { + background: $white; + border-left: 1px solid $black; + border-right: 1px solid $black; +} + +.button-gray { + background: $black; +} + +.settings-nav { + .active { + background: $black; + color: $white; + } +} + +.admin-submenu ul a { + color: $black; +} + +.policy-table { + input:checked { + +label { + color: $white; + } + } + label { + color: $black; + &:hover { + color: $white; + } + } +} + +.admin-common .admin-subtitle { + color: $black; +} + +.admin-functionalities .functionality.active { + background: $white; + border: 1px solid $black; +} + +.admin-membership-table { + .avatar .email, + .delete { + color: $black; + } + +} diff --git a/app/themes/high-contrast/variables.scss b/app/themes/high-contrast/variables.scss new file mode 100755 index 00000000..365e34fa --- /dev/null +++ b/app/themes/high-contrast/variables.scss @@ -0,0 +1,237 @@ +//************************* +//** COLORS +//************************ + +// Colors +$black: #000; +$blackish: #212121; +$grayer: #212121; +$gray: #757575; +$gray-light: #f5f5f5; +$whitish: #f5f5f5; +$white: #fff; + +// Primary colors +$primary-light: #212121; +$primary: #000; +$primary-dark: #000; + +//Warning colors +$red-light: #ff0062; +$red: #ff2400; + +//Card color +$card: #F0EFD1; +$card-hover: $black; +$card-dark: $black; + +$green-japanese-laurel: #009688; +$green-olive: #cddc39; +$red-amaranth: #e91e63; +$purple-eggplant: #9c27b0; +$yellow-pear: #ffc107; + +//************************* +//** LAYOUT +//************************* + +// Default body color and background +body { + background: $white; // fallback + color: $grayer; +} + +// Main +.master { + background: $white; +} + +// Secondary panel +.menu-secondary { + background: $white; +} + +// Tertiary panel +.menu-tertiary { + background-color: $white; +} + +// Extra bar panel +.extrabar { + background: $white; +} + + +//************************** +//** TYPOGRAPHY +//************************** + +// Font Sizes +%xsmall {font-size: .75rem;} +%small {font-size: .9rem;} +%medium {font-size: 1rem;} +%large {font-size: 1.2rem;} +%larger {font-size: 1.6rem;} +%xlarge {font-size: 2rem;} +%xxlarge {font-size: 3rem;} + +// Font Types +%title {font-family: Arial, Helvetica, sans-serif; } +%light {font-family: Arial, Helvetica, sans-serif; font-weight: 100; } +%text {font-family: Arial, Helvetica, sans-serif; font-weight: 400; } +%bold {font-family: Arial, Helvetica, sans-serif; font-weight:800; } +%taiga {font-family: 'taiga';} +%mono {font-family: 'courier new', 'monospace';} + +// Titles +h1, +h2, +h3, +h4, +h5, +h6 { + color: $blackish; +} + +a { + color: $grayer; + &:hover { + color: $primary; + } +} + +//************************** +//** SCAFFOLDING +//************************** + +//Forms +input[type="text"], +input[type="number"], +input[type="password"], +input[type="email"], +input[type="date"], +input[type="password"], +select, +textarea { + background: $white; + border-color: $black; + color: $black; + @include placeholder { + color:$black; + } + &.checksley-error { + border: 1px solid $red; + } +} + + +// Input errors +.checksley-error-list { + background: rgba($whitish, .8); + color: $red; +} + +// Blockquote +blockquote { + border-left: 5px solid $gray; +} + +blockquote, +blockquote p { + color: $black; +} + +cite { + color: $black; +} + +// lightbox +%lightbox { + background: rgba($white, .95); +} + +// Background images +%triangled-bg { + background: url('https://farm9.staticflickr.com/8449/7893171238_a201af22bc_k_d.jpg') no-repeat center center; + background-size: cover; +} + +%background-taiga { + background: url('https://farm9.staticflickr.com/8449/7893171238_a201af22bc_k_d.jpg') no-repeat center center; + background-size: cover; +} + +.summary { + background: $grayer; + color: $white; +} + + +//************************ +//** NAVIGATION +//*********************** + +// Top navigation bar +.navbar { + background: $black; + &:after { + background: url('../images/menu-vert.png') repeat top left; + } +} + +$top-icon-color: $white; +$dropdown-color: rgba(darken($primary-dark, 20%), 1); + +//In project left navigation bar +tg-project-menu { + background-color: rgba(darken($primary-dark, 15%), 1); + background-image: none; +} + +.main-nav { + svg path { + fill: $white; + } +} + +//***************************** +//** TASKBOARD +//****************************** + +//Taskboard table +.taskboard-table-header { + .task-colum-name { + background: lighten($white, 20%); + border-top: 3px solid $black; + .icon { + color: $black; + } + } +} +.taskboard-table-body { + .taskboard-tasks-box { + background: $white; + border: 1px solid $black; + } +} + +//***************************** +//** KANBAN +//****************************** + +//Kanban table +.kanban-table-header { + .task-colum-name { + background: lighten($white, 20%); + border-top: 3px solid $black; + .icon { + color: $black; + } + } +} + +.kanban-table-body { + .kanban-uses-box { + background: $whitish; + } +} diff --git a/app/themes/material-design/custom.scss b/app/themes/material-design/custom.scss new file mode 100644 index 00000000..32e735da --- /dev/null +++ b/app/themes/material-design/custom.scss @@ -0,0 +1,5 @@ +// Any styles in this stylesheet will override any previous defined style in Taiga. + +// Max: Beat it or I'll call the Brute Squad! +// Fezzik: I'm on the Brute Squad. +// Max: [sees Fezzik's size] You are the Brute Squad! diff --git a/app/themes/material-design/variables.scss b/app/themes/material-design/variables.scss new file mode 100755 index 00000000..e33b43e1 --- /dev/null +++ b/app/themes/material-design/variables.scss @@ -0,0 +1,246 @@ +//************************* +//** COLORS +//************************ + +// Colors +$black: #000; +$blackish: #212121; +$grayer: #424242; +$gray: #757575; +$gray-light: #bdbdbd; +$whitish: #f5f5f5; +$white: #fff; + +// Primary colors +$primary-light: #8c9eff; +$primary: #3f51b5; +$primary-dark: #1a237e; + +//Warning colors +$red-light: #ff5252; +$red: #f44336; + +//Card color +$card: #fff8e4; +$card-hover: #f1e8cd; +$card-dark: #cfc29b; + +$green-japanese-laurel: #009688; +$green-olive: #cddc39; +$red-amaranth: #e91e63; +$purple-eggplant: #9c27b0; +$yellow-pear: #ffc107; + +//************************* +//** LAYOUT +//************************* + +// Default body color and background +body { + background: $white; // fallback + color: $grayer; +} + +// Main +.master { + background: $white; +} + +// Secondary panel +.menu-secondary { + background: lighten($primary-light, 22%); +} + +// Tertiary panel +.menu-tertiary { + background-color: $primary-dark; +} + +// Extra bar panel +.extrabar { + background: lighten($primary-light, 22%); +} + + +//************************** +//** TYPOGRAPHY +//************************** + +@each $font-face in OpenSans-CondLight, OpenSans-Light, opensans-regular, opensans-semibold, taiga { + @font-face { + font-family: '#{$font-face}'; + src: url('../fonts/#{$font-face}.eot?#iefix') format('embedded-opentype'), + url('../fonts/#{$font-face}.woff') format('woff'), + url('../fonts/#{$font-face}.ttf') format('truetype'), + url('../fonts/#{$font-face}.svg#{$font-face}') format('svg'); + } +} + +// Font Sizes +%xsmall {font-size: .75rem;} +%small {font-size: .9rem;} +%medium {font-size: 1rem;} +%large {font-size: 1.2rem;} +%larger {font-size: 1.6rem;} +%xlarge {font-size: 2rem;} +%xxlarge {font-size: 3rem;} + +// Font Types +%title {font-family: 'OpenSans-CondLight', Arial, Helvetica, sans-serif; } +%light {font-family: 'OpenSans-Light', Arial, Helvetica, sans-serif; } +%text {font-family: 'opensans-regular', Arial, Helvetica, sans-serif; } +%bold {font-family: 'opensans-semibold', Arial, Helvetica, sans-serif; } +%taiga {font-family: 'taiga';} +%mono {font-family: 'courier new', 'monospace';} + +// Titles +h1, +h2, +h3, +h4, +h5, +h6 { + color: $blackish; +} + +a { + color: $grayer; + &:hover { + color: $primary; + } +} + +//************************** +//** SCAFFOLDING +//************************** + +//Forms +input[type="text"], +input[type="number"], +input[type="password"], +input[type="email"], +input[type="date"], +input[type="password"], +select, +textarea { + background: $whitish; + border-color: $primary; + color: $grayer; + @include placeholder { + color: darken($gray-light, 10%); + } + &.checksley-error { + border: 1px solid $red; + } +} + + +// Input errors +.checksley-error-list { + background: rgba($whitish, .8); + color: $red; +} + +// Blockquote +blockquote { + border-left: 5px solid $primary-light; +} + +blockquote, +blockquote p { + color: $gray; +} + +cite { + color: $gray; +} + +// lightbox +%lightbox { + background: rgba($white, .95); +} + +// Background images +%triangled-bg { + background: url('https://lh4.googleusercontent.com/-k7YewfrSQ_Q/VGdNZND0NBI/AAAAAAAAD1A/UDZBeSGR7iM/w1465-h824-no/Ultimate%2BMaterial%2BLollipop%2BCollection%2B-%2B480') no-repeat center center; + background-size: cover; +} + +%background-taiga { + background: url('https://lh6.googleusercontent.com/-2l_mJ5g6j4k/VGdNZCpaERI/AAAAAAAAD2o/zCx5Z3cYv6Y/w1465-h824-no/Ultimate%2BMaterial%2BLollipop%2BCollection%2B-%2B497') no-repeat center center; + background-size: cover; +} + +.summary { + background: $grayer; + color: $white; +} + + +//************************ +//** NAVIGATION +//*********************** + +// Top navigation bar +.navbar { + background: rgba($red-amaranth, .6); + &:after { + background: url('../images/menu-vert.png') repeat top left; + } +} + +$top-icon-color: $white; +$dropdown-color: rgba(darken($primary-dark, 20%), 1); + +//In project left navigation bar +tg-project-menu { + background-color: rgba(darken($primary-dark, 15%), 1); + background-image: none; +} + +.main-nav { + svg path { + fill: $white; + } +} + +//***************************** +//** TASKBOARD +//****************************** + +//Taskboard table +.taskboard-table-header { + .task-colum-name { + background: lighten($primary-light, 20%); + border-top: 3px solid $primary; + .icon { + color: $primary; + } + } +} +.taskboard-table-body { + .taskboard-tasks-box { + background: $whitish; + } +} + +//***************************** +//** KANBAN +//****************************** + +//Kanban table +.kanban-table-header { + .task-colum-name { + background: lighten($primary-light, 20%); + border-top: 3px solid $primary; + .icon { + color: $primary; + } + } +} + +.kanban-table-body { + .kanban-uses-box { + background: $whitish; + } +} diff --git a/app/themes/taiga/custom.scss b/app/themes/taiga/custom.scss index e69de29b..32e735da 100644 --- a/app/themes/taiga/custom.scss +++ b/app/themes/taiga/custom.scss @@ -0,0 +1,5 @@ +// Any styles in this stylesheet will override any previous defined style in Taiga. + +// Max: Beat it or I'll call the Brute Squad! +// Fezzik: I'm on the Brute Squad. +// Max: [sees Fezzik's size] You are the Brute Squad! diff --git a/app/themes/taiga/variables.scss b/app/themes/taiga/variables.scss index 8db5386a..c8595aa5 100755 --- a/app/themes/taiga/variables.scss +++ b/app/themes/taiga/variables.scss @@ -1,5 +1,8 @@ -// Colors +//************************* +//** COLORS +//************************ +// Colors $black: #000; $blackish: #050505; $grayer: #444; @@ -8,29 +11,226 @@ $gray-light: #b8b8b8; $whitish: #f5f5f5; $white: #fff; -$green-taiga: #72a114; -$fresh-taiga: #9dce0a; -$dark-taiga: #879b89; +// Primary colors +$primary-light: #9dce0a; +$primary: #72a114; +$primary-dark: #879b89; +//Warning colors $red-light: #ff8282; $red: #f00; -$postit: #fff8e4; -$postit-hover: #f1e8cd; -$postit-dark-hover: #cfc29b; +//Card color +$card: #fff8e4; +$card-hover: #f1e8cd; +$card-dark: #cfc29b; - -//Loading bar $green-japanese-laurel: #237400; $green-olive: #618000; $red-amaranth: #e43050; $purple-eggplant: #810061; $yellow-pear: #bbe831; -$menu: #232323; -$star-fill: #edd400; +//************************* +//** LAYOUT +//************************* + +// Default body color and background +body { + background: $white; // fallback + color: $grayer; +} + +// Main +.master { + background: $white; +} + +// Secondary panel +.menu-secondary { + background: $whitish; +} + +// Tertiary panel +.menu-tertiary { + background-color: $primary-dark; +} + +// Extra bar panel +.extrabar { + background: $whitish; +} + + +//************************** +//** TYPOGRAPHY +//************************** + +// Font Sizes +%xsmall {font-size: .75rem;} +%small {font-size: .9rem;} +%medium {font-size: 1rem;} +%large {font-size: 1.2rem;} +%larger {font-size: 1.6rem;} +%xlarge {font-size: 2rem;} +%xxlarge {font-size: 3rem;} + +// Font Types +%title {font-family: 'OpenSans-CondLight', Arial, Helvetica, sans-serif; } +%light {font-family: 'OpenSans-Light', Arial, Helvetica, sans-serif; } +%text {font-family: 'opensans-regular', Arial, Helvetica, sans-serif; } +%bold {font-family: 'opensans-semibold', Arial, Helvetica, sans-serif; } +%taiga {font-family: 'taiga';} +%mono {font-family: 'courier new', 'monospace';} + +// Titles +h1, +h2, +h3, +h4, +h5, +h6 { + color: $blackish; +} + +a { + color: $grayer; + &:hover { + color: $primary; + } +} + +//************************** +//** SCAFFOLDING +//************************** + +//Forms +input[type="text"], +input[type="number"], +input[type="password"], +input[type="email"], +input[type="date"], +input[type="password"], +select, +textarea { + background: $whitish; + border-color: $gray-light; + color: $grayer; + @include placeholder { + color: darken($gray-light, 10%); + } + &.checksley-error { + border: 1px solid $red; + } +} + + +// Input errors +.checksley-error-list { + background: rgba($whitish, .8); + color: $red; +} + +// Blockquote +blockquote { + border-left: 5px solid $whitish; +} + +blockquote, +blockquote p { + color: $gray; +} + +cite { + color: $gray; +} + +// lightbox +%lightbox { + background: rgba($white, .95); +} + +// Background images +%triangled-bg { + background: url('/images/bg.png') no-repeat center center; + background-size: cover; +} + +%background-taiga { + background: url('/images/invitation_bg.jpg') no-repeat center center; + background-size: cover; +} + +.summary { + background: $grayer; + color: $white; +} + + +//************************ +//** NAVIGATION +//*********************** + +// Top navigation bar +.navbar { + background: rgba($black, .5); + &:after { + background: url('../images/menu-vert.png') repeat top left; + } +} -// Top menu values $top-icon-color: #11241f; -$dropdown-width: 350px; $dropdown-color: rgba(darken($grayer, 20%), 1); + +//In project left navigation bar +tg-project-menu { + background-color: $primary-dark; + background-image: url('../images/menu.png'); +} + +.main-nav { + svg path { + fill: $white; + } +} + +//***************************** +//** TASKBOARD +//****************************** + +//Taskboard table +.taskboard-table-header { + .task-colum-name { + background: $whitish; + border-top: 3px solid $gray-light; + .icon { + color: $gray-light; + } + } +} +.taskboard-table-body { + .taskboard-tasks-box { + background: $whitish; + } +} + +//***************************** +//** KANBAN +//****************************** + +//Kanban table +.kanban-table-header { + .task-colum-name { + background: $whitish; + border-top: 3px solid $gray-light; + .icon { + color: $gray-light; + } + } +} + +.kanban-table-body { + .kanban-uses-box { + background: $whitish; + } +} From 4c4162ce2448abaf0fe7a0cd76ea3775505fc2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 7 Jul 2015 17:34:58 +0200 Subject: [PATCH 061/403] [i18n] Update locales --- app/locales/locale-ca.json | 7 +++++-- app/locales/locale-de.json | 7 +++++-- app/locales/locale-es.json | 7 +++++-- app/locales/locale-fi.json | 7 +++++-- app/locales/locale-fr.json | 7 +++++-- app/locales/locale-nl.json | 7 +++++-- app/locales/locale-zh-hant.json | 7 +++++-- 7 files changed, 35 insertions(+), 14 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index 8e74b459..f410a230 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "tasques
obertes", "CLOSED_TASKS": "tasques
tancades", "IOCAINE_DOSES": "dosis
iocaína", - "SHOW_STATISTICS_TITLE": "Mostrar estadístiques" + "SHOW_STATISTICS_TITLE": "Mostrar estadístiques", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "punts
projecte", @@ -1189,7 +1190,9 @@ "BIO": "Bio (max. 210 caràcters)", "PLACEHOLDER_BIO": "Contans algo sobre tu mateix", "LANGUAGE": "Idioma", - "LANGUAGE_DEFAULT": "-- utiliza l'idioma per defecte --" + "LANGUAGE_DEFAULT": "-- utiliza l'idioma per defecte --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index cd71532c..7d45e048 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "offene
Aufgaben", "CLOSED_TASKS": "geschlossene
Aufgaben", "IOCAINE_DOSES": "Iocaine
Dosen", - "SHOW_STATISTICS_TITLE": "Statistik anzeigen" + "SHOW_STATISTICS_TITLE": "Statistik anzeigen", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "Projekt
Punkte", @@ -1189,7 +1190,9 @@ "BIO": "Bio (max. 210 Zeichen)", "PLACEHOLDER_BIO": "Erzählen Sie etwas über sich", "LANGUAGE": "Sprache", - "LANGUAGE_DEFAULT": "-- benutzen Sie eine vorgegebene Sprache --" + "LANGUAGE_DEFAULT": "-- benutzen Sie eine vorgegebene Sprache --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 57497f91..8dec9703 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "tareas
abiertas", "CLOSED_TASKS": "tareas
cerradas", "IOCAINE_DOSES": "dosis de
iocaína", - "SHOW_STATISTICS_TITLE": "Ver estadísticas" + "SHOW_STATISTICS_TITLE": "Ver estadísticas", + "TOGGLE_BAKLOG_GRAPH": "Ver/Ocultar gráfica de burndown" }, "SUMMARY": { "PROJECT_POINTS": "puntos
proyecto", @@ -1189,7 +1190,9 @@ "BIO": "Bio (max. 210 caracteres)", "PLACEHOLDER_BIO": "Dinos algo acerca de ti", "LANGUAGE": "Idioma", - "LANGUAGE_DEFAULT": "- usar idioma por defecto -" + "LANGUAGE_DEFAULT": "- usar idioma por defecto -", + "THEME": "Tema", + "THEME_DEFAULT": "-- usar tema por defecto --" } }, "WIZARD": { diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index e3b747ea..9d9e4bd8 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "avaa
tehtävät", "CLOSED_TASKS": "suljettu
tehtävää", "IOCAINE_DOSES": "myrkkye-
annosta", - "SHOW_STATISTICS_TITLE": "Näytä tilastot" + "SHOW_STATISTICS_TITLE": "Näytä tilastot", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "projekti
pistettä", @@ -1189,7 +1190,9 @@ "BIO": "Bio (max. 210 chars)", "PLACEHOLDER_BIO": "Kerro jotain itsestäsi", "LANGUAGE": "Kieli", - "LANGUAGE_DEFAULT": "-- käytä oletuskieltä --" + "LANGUAGE_DEFAULT": "-- käytä oletuskieltä --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 73262e56..620d4937 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "tâches
ouvertes", "CLOSED_TASKS": "tâches
fermées", "IOCAINE_DOSES": "doses
de iocaine", - "SHOW_STATISTICS_TITLE": "Afficher les statistiques" + "SHOW_STATISTICS_TITLE": "Afficher les statistiques", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "projet
points", @@ -1189,7 +1190,9 @@ "BIO": "Biographie (maximum 210 caractères)", "PLACEHOLDER_BIO": "Dites en nous plus sur vous", "LANGUAGE": "Langue", - "LANGUAGE_DEFAULT": "-- utiliser la langue par défaut --" + "LANGUAGE_DEFAULT": "-- utiliser la langue par défaut --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 33a01064..550782de 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "open
taken", "CLOSED_TASKS": "gesloten
taken", "IOCAINE_DOSES": "iocaine
dosissen", - "SHOW_STATISTICS_TITLE": "Toon statistieken" + "SHOW_STATISTICS_TITLE": "Toon statistieken", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "project
punten", @@ -1189,7 +1190,9 @@ "BIO": "Bio", "PLACEHOLDER_BIO": "Vertel iets over jezelf", "LANGUAGE": "Taal", - "LANGUAGE_DEFAULT": "-- gebruik standaard taal --" + "LANGUAGE_DEFAULT": "-- gebruik standaard taal --", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 8393fff4..39feb405 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -916,7 +916,8 @@ "OPEN_TASKS": "開啟
任務", "CLOSED_TASKS": "已關閉
任務", "IOCAINE_DOSES": "毒物(全新任務挑戰)
劑量", - "SHOW_STATISTICS_TITLE": "顯示統計" + "SHOW_STATISTICS_TITLE": "顯示統計", + "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" }, "SUMMARY": { "PROJECT_POINTS": "專案
點數", @@ -1189,7 +1190,9 @@ "BIO": "自介(最多210字)", "PLACEHOLDER_BIO": "請自我介紹", "LANGUAGE": "語言", - "LANGUAGE_DEFAULT": "-- 使用設預語言 -- " + "LANGUAGE_DEFAULT": "-- 使用設預語言 -- ", + "THEME": "Theme", + "THEME_DEFAULT": "-- use default theme --" } }, "WIZARD": { From 8e8d2dd57e5c016bd20d238293fef678c3b8fef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Wed, 8 Jul 2015 10:31:21 +0200 Subject: [PATCH 062/403] Fix summary css variables by merge --- app/styles/components/summary.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/styles/components/summary.scss b/app/styles/components/summary.scss index e99527b1..2d435a17 100644 --- a/app/styles/components/summary.scss +++ b/app/styles/components/summary.scss @@ -41,7 +41,7 @@ $summary-background: $grayer; &:hover { .graph, .color-line { - fill: $fresh-taiga; + fill: $primary-light; transition: fill .2s; } } @@ -51,7 +51,7 @@ $summary-background: $grayer; display: none; } .graph { - fill: $green-taiga; + fill: $primary; } } svg { @@ -132,7 +132,7 @@ $summary-background: $grayer; font-size: 1.4rem; margin-right: .4rem; &.icon-stats { - color: $green-taiga; + color: $primary; float: right; transition: color .3s linear; &:hover { @@ -143,7 +143,7 @@ $summary-background: $grayer; color: $primary-light; } &.active:hover { - color: $green-taiga; + color: $primary; transition: color .3s linear; } } From f43ac475ce2206d3580d1bcc93b8bf49b9df263f Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 8 Jul 2015 11:30:35 +0200 Subject: [PATCH 063/403] fix 404 on karma --- karma.conf.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/karma.conf.js b/karma.conf.js index 2de2abfe..ac545dfe 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,6 +1,10 @@ // Karma configuration // Generated on Wed Apr 15 2015 09:44:14 GMT+0200 (CEST) +// this is needed by theme.service.spec +var fs = require('fs'); +fs.writeFileSync('dist/styles/empty.css', ''); + module.exports = function(config) { var configuration = { @@ -86,6 +90,13 @@ module.exports = function(config) { } }, + proxies: { + '/images/': 'http://localhost:9001/images/', + '/base/dist/js/maps/': 'http://localhost:9001/js/maps/', + '/base/dist/js/maps/': 'http://localhost:9001/js/maps/', + '/styles/theme-testTheme.css': 'http://localhost:9001/styles/empty.css' + }, + // Continuous Integration mode // if true, Karma captures browsers, runs the tests and exits singleRun: false From 9cc0ea22db5aea6f4bdbceb8438a7910af48e037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Wed, 8 Jul 2015 19:21:53 +0200 Subject: [PATCH 064/403] Fix Issue #3033: Typo at role points field name in history entries --- app/partials/common/history/history-change-points.jade | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/partials/common/history/history-change-points.jade b/app/partials/common/history/history-change-points.jade index 1f4df3c6..89429a93 100644 --- a/app/partials/common/history/history-change-points.jade +++ b/app/partials/common/history/history-change-points.jade @@ -1,7 +1,7 @@ <% _.each(points, function(point, name) { %> .change-entry .activity-changed - span(translate="ACTIVITY.US_POINTS", translate-values!="<%- name.toLowerCase() %>") + span(translate="ACTIVITY.US_POINTS", translate-values!="{name: '<%- name %>'}") .activity-fromto p strong(translate="COMMON.FROM") @@ -11,4 +11,4 @@ strong(translate="COMMON.TO") br span <%- point[1] %> -<% }); %> \ No newline at end of file +<% }); %> From f3980c46236c8127a5c5d464216037652d2bc3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 9 Jul 2015 12:54:42 +0200 Subject: [PATCH 065/403] [i18n] Update locales --- app/locales/locale-de.json | 18 +++++++++--------- app/locales/locale-nl.json | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 7d45e048..c2bfb263 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -411,8 +411,8 @@ "JITSI_CHAT_ROOM": "Jitsi", "APPEARIN_CHAT_ROOM": "Erscheint in", "TALKY_CHAT_ROOM": "Gesprächig", - "CUSTOM_CHAT_ROOM": "Custom", - "URL_CHAT_ROOM": "URL of your chat room" + "CUSTOM_CHAT_ROOM": "Kunde", + "URL_CHAT_ROOM": "URL Ihres Chatrooms" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Projekt Profil - {{projectName}}", @@ -898,7 +898,7 @@ "YAXIS_LABEL": "Punkte", "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Erhöhte Punktezahl von Teamanfragen für Sprint \"{{sprintName}}\" ist {{value}}", "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { @@ -1192,7 +1192,7 @@ "LANGUAGE": "Sprache", "LANGUAGE_DEFAULT": "-- benutzen Sie eine vorgegebene Sprache --", "THEME": "Theme", - "THEME_DEFAULT": "-- use default theme --" + "THEME_DEFAULT": "-- Standard-Theme benutzen --" } }, "WIZARD": { @@ -1244,13 +1244,13 @@ "NEW_PROJECT": "{{username}} erstellte das Projekt {{project_name}}", "MILESTONE_UPDATED": "{{username}} aktualisierte den Sprint {{obj_name}}", "US_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}}", - "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}} zu {{new_value}}", "ISSUE_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}}", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", - "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}} zu {{new_value}}", + "TASK_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} zu {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} zu {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} von User-Story {{us_name}}", - "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} die zu der User-Story gehört {{us_name}} zu {{new_value}}", "WIKI_UPDATED": "{{username}} aktualisierte die WIKI Seite {{obj_name}}", "NEW_COMMENT_US": "{{username}} schrieb einen Kommentar in der User-Story {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} schrieb einen Kommentar im Ticket {{obj_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 550782de..ff0f70cf 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -412,7 +412,7 @@ "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", "CUSTOM_CHAT_ROOM": "Custom", - "URL_CHAT_ROOM": "URL of your chat room" + "URL_CHAT_ROOM": "URL van je chat room" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Project profiel - {{projectName}}", @@ -454,7 +454,7 @@ "TASK_ADD": "Voeg een aangepast veld toe in taken", "ISSUE_DESCRIPTION": "Issues aangepaste velden", "ISSUE_ADD": "Voeg een aangepast veld toe in issues", - "FIELD_TYPE_TEXT": "Text", + "FIELD_TYPE_TEXT": "Tekst", "FIELD_TYPE_MULTI": "Multi-line" }, "PROJECT_VALUES": { @@ -896,8 +896,8 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punten", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", - "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "OPTIMAL": "Optimaal aantal openstaande punten voor sprint \"{{sprintName}}\" zou {{value}} moeten zijn", + "REAL": "Reële openstaande punten voor sprint \"{{sprintName}}\" is {{value}}", "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, @@ -917,7 +917,7 @@ "CLOSED_TASKS": "gesloten
taken", "IOCAINE_DOSES": "iocaine
dosissen", "SHOW_STATISTICS_TITLE": "Toon statistieken", - "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" + "TOGGLE_BAKLOG_GRAPH": "Toon/Verstop burndown grafiek" }, "SUMMARY": { "PROJECT_POINTS": "project
punten", @@ -1191,8 +1191,8 @@ "PLACEHOLDER_BIO": "Vertel iets over jezelf", "LANGUAGE": "Taal", "LANGUAGE_DEFAULT": "-- gebruik standaard taal --", - "THEME": "Theme", - "THEME_DEFAULT": "-- use default theme --" + "THEME": "Thema", + "THEME_DEFAULT": "-- gebruikt standaard thema --" } }, "WIZARD": { @@ -1244,9 +1244,9 @@ "NEW_PROJECT": "{{username}} heeft een nieuw project aangemaakt {{project_name}}", "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", - "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de US {{obj_name}} gewijzigd naar {{new_value}}", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de issue gewijzigd van {{obj_name}} naar {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} heeft de eigenschap \"{{field_name}}\" van de taak {{obj_name}} die behoort tot de US {{us_name}} bijgewerkt", From a28e4bfdaa4c8a26a8d674b37d871108684a240b Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 3 Jul 2015 13:15:30 +0200 Subject: [PATCH 066/403] fix several timeline bugs - bulk changes splited on timeline - new text for role points changes - remove user timeline link if the user hasn't a visible profile - fix timeline text when an object becomes unassigned --- app/coffee/modules/base/navurls.coffee | 31 +++- app/locales/locale-en.json | 1 + .../feedback/feedback.service.spec.coffee | 2 +- .../dropdown-user.directive.spec.coffee | 2 +- .../user-timeline-attachment-image.jade | 4 +- .../user-timeline-attachment.directive.coffee | 2 +- ...-timeline-attachment.directive.spec.coffee | 8 +- .../user-timeline-attachment.jade | 4 +- .../user-timeline-item-title.service.coffee | 141 +++++++++++------- ...er-timeline-item-title.service.spec.coffee | 133 +++++++++-------- .../user-timeline-item-type.service.coffee | 136 +++++++++-------- .../user-timeline-item.controller.coffee | 31 ++-- .../user-timeline-item.controller.spec.coffee | 46 +++--- .../user-timeline-item.jade | 35 +++-- .../user-timeline/user-timeline.scss | 9 +- .../user-timeline.service.coffee | 92 ++++++++---- .../user-timeline.service.spec.coffee | 77 +++++----- karma.conf.js | 2 +- package.json | 8 +- 19 files changed, 427 insertions(+), 337 deletions(-) diff --git a/app/coffee/modules/base/navurls.coffee b/app/coffee/modules/base/navurls.coffee index d3908790..287523cb 100644 --- a/app/coffee/modules/base/navurls.coffee +++ b/app/coffee/modules/base/navurls.coffee @@ -71,16 +71,39 @@ NavigationUrlsDirective = ($navurls, $auth, $q, $location) -> parseNav = (data, $scope) -> [name, params] = _.map(data.split(":"), trim) if params - params = _.map(params.split(","), trim) + # split by 'xxx=' + # example + # project=vm.timeline.getIn(['data', 'project', 'slug']), ref=vm.timeline.getIn(['obj', 'ref']) + # ["", "project", "vm.timeline.getIn(['data', 'project', 'slug']), ", "ref", "vm.timeline.getIn(['obj', 'ref'])"] + result = params.split(/(\w+)=/) + + # remove empty string + result = _.filter result, (str) -> return str.length + + # remove , at the end of the string + result = _.map result, (str) -> return trim(str.replace(/,$/g, '')) + + params = [] + index = 0 + + # ['param1', 'value'] => [{'param1': 'value'}] + while index < result.length + obj = {} + obj[result[index]] = result[index + 1] + params.push obj + index = index + 2 else params = [] - values = _.map(params, (x) -> trim(x.split("=")[1])) + + values = _.map params, (param) -> _.values(param)[0] promises = _.map(values, (x) -> bindOnceP($scope, x)) return $q.all(promises).then -> options = {} - for item in params - [key, value] = _.map(item.split("="), trim) + for param in params + key = Object.keys(param)[0] + value = param[key] + options[key] = $scope.$eval(value) return [name, options] diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index b2ca0d4c..eef0352d 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -1248,6 +1248,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/modules/feedback/feedback.service.spec.coffee b/app/modules/feedback/feedback.service.spec.coffee index da067961..d7e96b5b 100644 --- a/app/modules/feedback/feedback.service.spec.coffee +++ b/app/modules/feedback/feedback.service.spec.coffee @@ -35,4 +35,4 @@ describe "tgFeedbackService", -> params = { "class": "lightbox lightbox-feedback lightbox-generic-form" } - expect(mocks.tgLightboxFactory.create.calledWith("tg-lb-feedback", params)).to.be.true() + expect(mocks.tgLightboxFactory.create.calledWith("tg-lb-feedback", params)).to.be.true diff --git a/app/modules/navigation-bar/dropdown-user/dropdown-user.directive.spec.coffee b/app/modules/navigation-bar/dropdown-user/dropdown-user.directive.spec.coffee index b8eeb527..d7046165 100644 --- a/app/modules/navigation-bar/dropdown-user/dropdown-user.directive.spec.coffee +++ b/app/modules/navigation-bar/dropdown-user/dropdown-user.directive.spec.coffee @@ -87,7 +87,7 @@ describe "dropdownUserDirective", () -> vm.logout() expect(mockTgAuth.logout.callCount).to.be.equal(1) expect(mockTgLocation.path.callCount).to.be.equal(1) - expect(mockTgLocation.path.calledWith("/login")).to.be.true() + expect(mockTgLocation.path.calledWith("/login")).to.be.true it "dropdown user send feedback", () -> elm = createDirective() diff --git a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade index d82cc411..2d5424ae 100644 --- a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade +++ b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment-image.jade @@ -1,5 +1,5 @@ // timeline-attachment directive div.activity-image-attachment blockquote - a(href="{{::attachment.url}}", title="See {{::attachment.filename}}", target="_blank") - img(ng-src="{{::attachment.thumb_url || attachment.url}}", alt="{{::attachment.filename}}") + a(href="{{::attachment.get('url')}}", title="See {{::attachment.get('filename')}}", target="_blank") + img(ng-src="{{::attachment.get('thumb_url') || attachment.get('url')}}", alt="{{::attachment.get('filename')}}") diff --git a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.coffee b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.coffee index 10e438a4..30a875f4 100644 --- a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.coffee +++ b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.coffee @@ -8,7 +8,7 @@ UserTimelineAttachmentDirective = (template, $compile) -> return url.indexOf(extension, url - extension.length) != -1 link = (scope, el) -> - is_image = isImage(scope.attachment.url) + is_image = isImage(scope.attachment.get('url')) if is_image templateHtml = template.get("user-timeline/user-timeline-attachment/user-timeline-attachment-image.html") diff --git a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.spec.coffee b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.spec.coffee index 37a3f927..a70ac8a0 100644 --- a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.spec.coffee +++ b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.directive.spec.coffee @@ -32,9 +32,9 @@ describe "userTimelineAttachmentDirective", () -> compile = $compile it "attachment image template", () -> - scope.attachment = { + scope.attachment = Immutable.fromJS({ url: "path/path/file.jpg" - } + }) mockTgTemplate.get .withArgs("user-timeline/user-timeline-attachment/user-timeline-attachment-image.html") @@ -45,9 +45,9 @@ describe "userTimelineAttachmentDirective", () -> expect(elm.find('#image')).to.have.length(1) it "attachment file template", () -> - scope.attachment = { + scope.attachment = Immutable.fromJS({ url: "path/path/file.pdf" - } + }) mockTgTemplate.get .withArgs("user-timeline/user-timeline-attachment/user-timeline-attachment.html") diff --git a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.jade b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.jade index cdac755e..a2f83b04 100644 --- a/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.jade +++ b/app/modules/user-timeline/user-timeline-attachment/user-timeline-attachment.jade @@ -1,5 +1,5 @@ div.single-attachment blockquote - a(ng-href="{{ attachment.url }}", title="Click to download {{ attachment.filename }}", target="_blank") + a(ng-href="{{ attachment.get('url') }}", title="Click to download {{ attachment.get('filename') }}", target="_blank") span.icon.icon-document - span {{attachment.filename}} + span {{attachment.get('filename')}} diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee index bc34c4b6..c39e2b0a 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.coffee @@ -14,74 +14,93 @@ class UserTimelineItemTitle 'severity': 'ISSUES.FIELDS.SEVERITY', 'priority': 'ISSUES.FIELDS.PRIORITY', 'type': 'ISSUES.FIELDS.TYPE', - 'is_iocaine': 'TASK.FIELDS.IS_IOCAINE' + 'is_iocaine': 'TASK.FIELDS.IS_IOCAINE', + 'is_blocked': 'COMMON.FIELDS.IS_BLOCKED' + } + + _params: { + username: (timeline, event) -> + user = timeline.getIn(['data', 'user']) + + if user.get('is_profile_visible') + title_attr = @translate.instant('COMMON.SEE_USER_PROFILE', {username: user.get('username')}) + url = "user-profile:username=vm.timeline.getIn(['data', 'user', 'username'])" + + return @._getLink(url, user.get('name'), title_attr) + else + return @._getUsernameSpan(user.get('name')) + + field_name: (timeline, event) -> + field_name = timeline.getIn(['data', 'value_diff', 'key']) + + return @translate.instant(@._fieldTranslationKey[field_name]) + + project_name: (timeline, event) -> + url = "project:project=vm.timeline.getIn(['data', 'project', 'slug'])" + + return @._getLink(url, timeline.getIn(["data", "project", "name"])) + + new_value: (timeline, event) -> + if _.isArray(timeline.getIn(["data", "value_diff", "value"]).toJS()) + value = timeline.getIn(["data", "value_diff", "value"]).get(1) + + # assigned to unasigned + if value == null && timeline.getIn(["data", "value_diff", "key"]) == 'assigned_to' + value = @translate.instant('ACTIVITY.VALUES.UNASSIGNED') + + return value + else + return timeline.getIn(["data", "value_diff", "value"]).first().get(1) + + sprint_name: (timeline, event) -> + url = "project-taskboard:project=vm.timeline.getIn(['data', 'project', 'slug']),sprint=vm.timeline.getIn(['data', 'milestone', 'slug'])" + + return @._getLink(url, timeline.getIn(['data', 'milestone', 'name'])) + + us_name: (timeline, event) -> + obj = @._getTimelineObj(timeline, event).get('userstory') + + event_us = {obj: 'parent_userstory'} + url = @._getDetailObjUrl(event_us) + + text = '#' + obj.get('ref') + ' ' + obj.get('subject') + + return @._getLink(url, text) + + obj_name: (timeline, event) -> + obj = @._getTimelineObj(timeline, event) + url = @._getDetailObjUrl(event) + + if event.obj == 'wikipage' + text = unslugify(obj.get('slug')) + else if event.obj == 'milestone' + text = obj.get('name') + else + text = '#' + obj.get('ref') + ' ' + obj.get('subject') + + return @._getLink(url, text) + + role_name: (timeline, event) -> + return timeline.getIn(['data', 'value_diff', 'value']).keySeq().first() } constructor: (@translate) -> _translateTitleParams: (param, timeline, event) -> - if param == "username" - user = timeline.data.user - title_attr = @translate.instant('COMMON.SEE_USER_PROFILE', {username: user.username}) - url = 'user-profile:username=vm.activity.user.username' - - return @._getLink(url, user.name, title_attr) - - else if param == 'field_name' - field_name = Object.keys(timeline.data.values_diff)[0] - - return @translate.instant(@._fieldTranslationKey[field_name]) - - else if param == 'project_name' - url = 'project:project=vm.activity.project.slug' - - return @._getLink(url, timeline.data.project.name) - - else if param == 'new_value' - field_name = Object.keys(timeline.data.values_diff)[0] - - return timeline.data.values_diff[field_name][1] - - else if param == 'sprint_name' - url = 'project-taskboard:project=vm.activity.project.slug,sprint=vm.activity.sprint.slug' - - return @._getLink(url, timeline.data.milestone.name) - - else if param == 'us_name' - obj = @._getTimelineObj(timeline, event).userstory - - event_us = {obj: 'parent_userstory'} - url = @._getDetailObjUrl(event_us) - - text = '#' + obj.ref + ' ' + obj.subject - - return @._getLink(url, text) - - else if param == 'obj_name' - obj = @._getTimelineObj(timeline, event) - url = @._getDetailObjUrl(event) - - if event.obj == 'wikipage' - text = unslugify(obj.slug) - else if event.obj == 'milestone' - text = obj.name - else - text = '#' + obj.ref + ' ' + obj.subject - - return @._getLink(url, text) + return @._params[param].call(this, timeline, event) _getTimelineObj: (timeline, event) -> - return timeline.data[event.obj] + return timeline.getIn(['data', event.obj]) _getDetailObjUrl: (event) -> url = { - "issue": ["project-issues-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], - "wikipage": ["project-wiki-page", ":project=vm.activity.project.slug,slug=vm.activity.obj.slug"], - "task": ["project-tasks-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], - "userstory": ["project-userstories-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.ref"], - "parent_userstory": ["project-userstories-detail", ":project=vm.activity.project.slug,ref=vm.activity.obj.userstory.ref"], - "milestone": ["project-taskboard", ":project=vm.activity.project.slug,sprint=vm.activity.obj.slug"] + "issue": ["project-issues-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"], + "wikipage": ["project-wiki-page", ":project=vm.timeline.getIn(['data', 'project', 'slug']),slug=vm.timeline.getIn(['obj', 'ref'])"], + "task": ["project-tasks-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"], + "userstory": ["project-userstories-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"], + "parent_userstory": ["project-userstories-detail", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'userstory', 'ref'])"], + "milestone": ["project-taskboard", ":project=vm.timeline.getIn(['data', 'project', 'slug']),ref=vm.timeline.getIn(['obj', 'ref'])"] } return url[event.obj][0] + url[event.obj][1] @@ -95,6 +114,14 @@ class UserTimelineItemTitle .attr('title', title) .prop('outerHTML') + _getUsernameSpan: (text) -> + title = title || text + + return $('') + .addClass('username') + .text(text) + .prop('outerHTML') + _getParams: (timeline, event, timeline_type) -> params = {} diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee index 36bc6f52..4f09c32e 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-title.service.spec.coffee @@ -32,14 +32,15 @@ describe "tgUserTimelineItemTitle", -> _setup() it "title with username", () -> - timeline = { + timeline = Immutable.fromJS({ data: { user: { username: 'xx', - name: 'oo' + name: 'oo', + is_profile_visible: true } } - } + }) event = {} @@ -49,11 +50,45 @@ describe "tgUserTimelineItemTitle", -> } mockTranslate.instant - .withArgs('COMMON.SEE_USER_PROFILE', {username: timeline.data.user.username}) + .withArgs('COMMON.SEE_USER_PROFILE', {username: timeline.getIn(['data', 'user', 'username'])}) .returns('user-param') usernamelink = sinon.match ((value) -> - return value.username == 'oo' + return value.username == 'oo' + ), "usernamelink" + + mockTranslate.instant + .withArgs('TITLE_USER_NAME', usernamelink) + .returns('title_ok') + + title = mySvc.getTitle(timeline, event, type) + + expect(title).to.be.equal("title_ok") + + it "title with username not visible", () -> + timeline = Immutable.fromJS({ + data: { + user: { + username: 'xx', + name: 'oo', + is_profile_visible: false + } + } + }) + + event = {} + + type = { + key: 'TITLE_USER_NAME', + translate_params: ['username'] + } + + mockTranslate.instant + .withArgs('COMMON.SEE_USER_PROFILE', {username: timeline.getIn(['data', 'user', 'username'])}) + .returns('user-param') + + usernamelink = sinon.match ((value) -> + return value.username == 'oo' ), "usernamelink" mockTranslate.instant @@ -65,13 +100,13 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "title with a field name", () -> - timeline = { + timeline = Immutable.fromJS({ data: { - values_diff: { - status: {} + value_diff: { + key: 'status' } } - } + }) event = {} @@ -92,19 +127,19 @@ describe "tgUserTimelineItemTitle", -> .withArgs('TITLE_FIELD', fieldparam) .returns('title_ok') - title = mySvc.getTitle(timeline, event, type) expect(title).to.be.equal("title_ok") it "title with new value", () -> - timeline = { + timeline = Immutable.fromJS({ data: { - values_diff: { - status: ['old', 'new'] + value_diff: { + key: 'status', + value: ['old', 'new'] } } - } + }) event = {} @@ -122,13 +157,13 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("new_value_ok") it "title with project name", () -> - timeline = { + timeline = Immutable.fromJS({ data: { project: { name: "project_name" } } - } + }) event = {} @@ -138,7 +173,7 @@ describe "tgUserTimelineItemTitle", -> } projectparam = sinon.match ((value) -> - return value.project_name == 'project_name' + return value.project_name == 'project_name' ), "projectparam" mockTranslate.instant @@ -150,13 +185,13 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "title with sprint name", () -> - timeline = { + timeline = Immutable.fromJS({ data: { milestone: { name: "milestone_name" } } - } + }) event = {} @@ -166,7 +201,7 @@ describe "tgUserTimelineItemTitle", -> } milestoneparam = sinon.match ((value) -> - return value.sprint_name == 'milestone_name' + return value.sprint_name == 'milestone_name' ), "milestoneparam" mockTranslate.instant @@ -178,14 +213,14 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "title with object", () -> - timeline = { + timeline = Immutable.fromJS({ data: { issue: { ref: '123', subject: 'subject' } } - } + }) event = { obj: 'issue', @@ -197,7 +232,7 @@ describe "tgUserTimelineItemTitle", -> } objparam = sinon.match ((value) -> - return value.obj_name == '#123 subject' + return value.obj_name == '#123 subject' ), "objparam" mockTranslate.instant @@ -209,13 +244,13 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "title obj wiki", () -> - timeline = { + timeline = Immutable.fromJS({ data: { wikipage: { slug: 'slug-wiki', } } - } + }) event = { obj: 'wikipage', @@ -227,7 +262,7 @@ describe "tgUserTimelineItemTitle", -> } objparam = sinon.match ((value) -> - return value.obj_name == 'Slug wiki' + return value.obj_name == 'Slug wiki' ), "objparam" mockTranslate.instant @@ -239,13 +274,13 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "title obj milestone", () -> - timeline = { + timeline = Immutable.fromJS({ data: { milestone: { name: 'milestone_name', } } - } + }) event = { obj: 'milestone', @@ -257,7 +292,7 @@ describe "tgUserTimelineItemTitle", -> } objparam = sinon.match ((value) -> - return value.obj_name == 'milestone_name' + return value.obj_name == 'milestone_name' ), "objparam" mockTranslate.instant @@ -269,7 +304,7 @@ describe "tgUserTimelineItemTitle", -> expect(title).to.be.equal("title_ok") it "task title with us_name", () -> - timeline = { + timeline = Immutable.fromJS({ data: { task: { name: 'task_name', @@ -279,7 +314,7 @@ describe "tgUserTimelineItemTitle", -> } } } - } + }) event = { obj: 'task', @@ -291,41 +326,7 @@ describe "tgUserTimelineItemTitle", -> } objparam = sinon.match ((value) -> - return value.us_name == '#2 subject' - ), "objparam" - - mockTranslate.instant - .withArgs('TITLE_OBJ', objparam) - .returns('title_ok') - - title = mySvc.getTitle(timeline, event, type) - - expect(title).to.be.equal("title_ok") - - it "task title with us_name", () -> - timeline = { - data: { - task: { - name: 'task_name', - userstory: { - ref: 2 - subject: 'subject' - } - } - } - } - - event = { - obj: 'task', - } - - type = { - key: 'TITLE_OBJ', - translate_params: ['us_name'] - } - - objparam = sinon.match ((value) -> - return value.us_name == '#2 subject' + return value.us_name == '#2 subject' ), "objparam" mockTranslate.instant diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee index 20d866a9..db2e20fa 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee @@ -6,10 +6,10 @@ timelineType = (timeline, event) -> key: 'TIMELINE.NEW_MEMBER', translate_params: ['project_name'] member: (timeline) -> - return { - user: timeline.data.user, - role: timeline.data.role - } + return Immutable.Map({ + user: timeline.getIn(['data', 'user']), + role: timeline.getIn(['data', 'role']) + }) }, { # NewProject check: (timeline, event) -> @@ -17,11 +17,13 @@ timelineType = (timeline, event) -> key: 'TIMELINE.NEW_PROJECT', translate_params: ['username', 'project_name'], description: (timeline) -> - return timeline.data.project.description + return timeline.getIn(['data', 'project', 'description']) }, { # NewAttachment check: (timeline, event) -> - return event.type == 'change' && timeline.data.values_diff.attachments + return event.type == 'change' && + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'attachments' key: 'TIMELINE.UPLOAD_ATTACHMENT', translate_params: ['username', 'obj_name'] }, @@ -45,13 +47,13 @@ timelineType = (timeline, event) -> }, { # NewTask check: (timeline, event) -> - return event.obj == 'task' && event.type == 'create' && !timeline.data.task.userstory + return event.obj == 'task' && event.type == 'create' && !timeline.getIn(['data', 'task', 'userstory']) key: 'TIMELINE.TASK_CREATED', translate_params: ['username', 'project_name', 'obj_name'] }, { # NewTask with US check: (timeline, event) -> - return event.obj == 'task' && event.type == 'create' && timeline.data.task.userstory + return event.obj == 'task' && event.type == 'create' && timeline.getIn(['data', 'task', 'userstory']) key: 'TIMELINE.TASK_CREATED_WITH_US', translate_params: ['username', 'project_name', 'obj_name', 'us_name'] }, @@ -63,41 +65,45 @@ timelineType = (timeline, event) -> }, { # NewUsComment check: (timeline, event) -> - return timeline.data.comment && event.obj == 'userstory' + return timeline.getIn(['data', 'comment']) && event.obj == 'userstory' key: 'TIMELINE.NEW_COMMENT_US', translate_params: ['username', 'obj_name'], description: (timeline) -> - return $(timeline.data.comment_html).text() + return $(timeline.getIn(['data', 'comment_html'])).text() }, { # NewIssueComment check: (timeline, event) -> - return timeline.data.comment && event.obj == 'issue' + return timeline.getIn(['data', 'comment']) && event.obj == 'issue' key: 'TIMELINE.NEW_COMMENT_ISSUE', translate_params: ['username', 'obj_name'], description: (timeline) -> - return $(timeline.data.comment_html).text() + return $(timeline.getIn(['data', 'comment_html'])).text() }, { # NewTaskComment check: (timeline, event) -> - return timeline.data.comment && event.obj == 'task' + return timeline.getIn(['data', 'comment']) && event.obj == 'task' key: 'TIMELINE.NEW_COMMENT_TASK' translate_params: ['username', 'obj_name'], description: (timeline) -> - return $(timeline.data.comment_html).text() + return $(timeline.getIn(['data', 'comment_html'])).text() }, { # UsToMilestone - check: (timeline, event, field_name) -> - if field_name == 'milestone' && event.type == 'change' - return timeline.data.values_diff.milestone[0] == null + check: (timeline, event) -> + if timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'milestone' && + event.type == 'change' + return timeline.getIn(['data', 'value_diff', 'value']).get(0) == null return false key: 'TIMELINE.US_ADDED_MILESTONE', translate_params: ['username', 'obj_name', 'sprint_name'] }, { # UsToBacklog - check: (timeline, event, field_name) -> - if field_name == 'milestone' && event.type == 'change' - return timeline.data.values_diff.milestone[1] == null + check: (timeline, event) -> + if timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'milestone' && + event.type == 'change' + return timeline.getIn(['data', 'value_diff', 'value']).get(1) == null return false key: 'TIMELINE.US_REMOVED_FROM_MILESTONE', @@ -105,22 +111,26 @@ timelineType = (timeline, event) -> }, { # Blocked check: (timeline, event) -> - if event.type == 'change' && timeline.data.values_diff.is_blocked - return timeline.data.values_diff.is_blocked[1] == true + if timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'blocked' && + event.type == 'change' + return timeline.getIn(['data', 'value_diff', 'value', 'is_blocked']).get(1) == true return false key: 'TIMELINE.BLOCKED', translate_params: ['username', 'obj_name'], description: (timeline) -> - if timeline.data.values_diff.blocked_note_html - return $(timeline.data.values_diff.blocked_note_html[1]).text() + if timeline.hasIn(['data', 'value_diff', 'value', 'blocked_note_html']) + return $(timeline.getIn(['data', 'value_diff', 'value', 'blocked_note_html']).get(1)).text() else return false }, { # UnBlocked check: (timeline, event) -> - if event.type == 'change' && timeline.data.values_diff.is_blocked - return timeline.data.values_diff.is_blocked[1] == false + if timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'blocked' && + event.type == 'change' + return timeline.getIn(['data', 'value_diff', 'value', 'is_blocked']).get(1) == false return false key: 'TIMELINE.UNBLOCKED', @@ -138,74 +148,83 @@ timelineType = (timeline, event) -> key: 'TIMELINE.WIKI_UPDATED', translate_params: ['username', 'obj_name'] }, - { # UsUpdated + { # UsUpdated points check: (timeline, event) -> return event.obj == 'userstory' && event.type == 'change' && - !timeline.data.values_diff.description_diff - key: 'TIMELINE.US_UPDATED_WITH_NEW_VALUE', - translate_params: ['username', 'field_name', 'obj_name', 'new_value'] + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'points' + key: 'TIMELINE.US_UPDATED_POINTS', + translate_params: ['username', 'field_name', 'obj_name', 'new_value', 'role_name'] }, { # UsUpdated description check: (timeline, event) -> return event.obj == 'userstory' && event.type == 'change' && - timeline.data.values_diff.description_diff + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'description_diff' key: 'TIMELINE.US_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, - { # IssueUpdated + { # UsUpdated general check: (timeline, event) -> - return event.obj == 'issue' && - event.type == 'change' && - !timeline.data.values_diff.description_diff - key: 'TIMELINE.ISSUE_UPDATED_WITH_NEW_VALUE', + return event.obj == 'userstory' && + event.type == 'change' + key: 'TIMELINE.US_UPDATED_WITH_NEW_VALUE', translate_params: ['username', 'field_name', 'obj_name', 'new_value'] }, { # IssueUpdated description check: (timeline, event) -> return event.obj == 'issue' && event.type == 'change' && - timeline.data.values_diff.description_diff + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'description_diff' key: 'TIMELINE.ISSUE_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, - { # TaskUpdated + { # IssueUpdated general check: (timeline, event) -> - return event.obj == 'task' && - event.type == 'change' && - !timeline.data.task.userstory && - !timeline.data.values_diff.description_diff - key: 'TIMELINE.TASK_UPDATED_WITH_NEW_VALUE', + return event.obj == 'issue' && + event.type == 'change' + key: 'TIMELINE.ISSUE_UPDATED_WITH_NEW_VALUE', translate_params: ['username', 'field_name', 'obj_name', 'new_value'] }, { # TaskUpdated description check: (timeline, event) -> return event.obj == 'task' && event.type == 'change' && - !timeline.data.task.userstory && - timeline.data.values_diff.description_diff + !timeline.getIn('data', 'task', 'userstory') && + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'description_diff' key: 'TIMELINE.TASK_UPDATED', translate_params: ['username', 'field_name', 'obj_name'] }, - { # TaskUpdated with US - check: (timeline, event) -> - return event.obj == 'task' && - event.type == 'change' && - timeline.data.task.userstory && - !timeline.data.values_diff.description_diff - key: 'TIMELINE.TASK_UPDATED_WITH_US_NEW_VALUE', - translate_params: ['username', 'field_name', 'obj_name', 'us_name', 'new_value'] - }, { # TaskUpdated with US description check: (timeline, event) -> return event.obj == 'task' && event.type == 'change' && - timeline.data.task.userstory && - timeline.data.values_diff.description_diff + timeline.getIn('data', 'task', 'userstory') && + timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'description_diff' key: 'TIMELINE.TASK_UPDATED_WITH_US', translate_params: ['username', 'field_name', 'obj_name', 'us_name'] }, + { # TaskUpdated general + check: (timeline, event) -> + return event.obj == 'task' && + event.type == 'change' && + !timeline.getIn(['data', 'task', 'userstory']) + key: 'TIMELINE.TASK_UPDATED_WITH_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'new_value'] + }, + { # TaskUpdated with US + check: (timeline, event) -> + return event.obj == 'task' && + event.type == 'change' && + timeline.getIn(['data', 'task', 'userstory']) + key: 'TIMELINE.TASK_UPDATED_WITH_US_NEW_VALUE', + translate_params: ['username', 'field_name', 'obj_name', 'us_name', 'new_value'] + }, { # New User check: (timeline, event) -> return event.obj == 'user' && event.type == 'create' @@ -214,11 +233,8 @@ timelineType = (timeline, event) -> } ] - if timeline.data.values_diff - field_name = Object.keys(timeline.data.values_diff)[0] - return _.find types, (obj) -> - return obj.check(timeline, event, field_name) + return obj.check(timeline, event) class UserTimelineType getType: (timeline, event) -> timelineType(timeline, event) diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee index c1e9cde6..9228cf37 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee @@ -5,28 +5,27 @@ class UserTimelineItemController ] constructor: (@userTimelineItemType, @userTimelineItemTitle) -> - timeline = @.timeline.toJS() + event = @.parseEventType(@.timeline.get('event_type')) + type = @userTimelineItemType.getType(@.timeline, event) - event = @.parseEventType(timeline.event_type) - type = @userTimelineItemType.getType(timeline, event) + title = @userTimelineItemTitle.getTitle(@.timeline, event, type) - @.activity = {} + @.timeline = @.timeline.set('title_html', title) - @.activity.user = timeline.data.user - @.activity.project = timeline.data.project - @.activity.sprint = timeline.data.milestone - @.activity.title = @userTimelineItemTitle.getTitle(timeline, event, type) - @.activity.created_formated = moment(timeline.created).fromNow() - @.activity.obj = @.getObject(timeline, event) + @.timeline = @.timeline.set('obj', @.getObject(@.timeline, event)) if type.description - @.activity.description = type.description(timeline) + @.timeline = @.timeline.set('description', type.description(@.timeline)) if type.member - @.activity.member = type.member(timeline) + @.timeline = @.timeline.set('member', type.member(@.timeline)) - if timeline.data.values_diff?.attachments - @.activity.attachments = timeline.data.values_diff.attachments.new + if @.timeline.hasIn(['data', 'value_diff', 'attachments', 'new']) + @.timeline = @.timeline.set('attachments', @.timeline.getIn(['data', 'value_diff', 'attachments', 'new'])) + + getObject: (timeline, event) -> + if timeline.get('data').get(event.obj) + return timeline.get('data').get(event.obj) parseEventType: (event_type) -> event_type = event_type.split(".") @@ -37,9 +36,5 @@ class UserTimelineItemController type: event_type[2] } - getObject: (timeline, event) -> - if timeline.data[event.obj] - return timeline.data[event.obj] - angular.module("taigaUserTimeline") .controller("UserTimelineItem", UserTimelineItemController) diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee index fae5ad1a..28a3f15d 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee @@ -43,16 +43,23 @@ describe "UserTimelineItemController", -> type: 'created' } - timeline = { + timeline = Immutable.fromJS({ event_type: 'issues.issue.created', data: { user: 'user_fake', project: 'project_fake', milestone: 'milestone_fake', created: new Date().getTime(), - values_diff: {} + issue: { + id: 2 + }, + value_diff: { + attachments: { + new: "fakeAttachment" + } + } } - } + }) scope = { vm: { @@ -69,36 +76,19 @@ describe "UserTimelineItemController", -> inject ($controller) -> controller = $controller - it "basic activity fields filled", () -> - timeline = scope.vm.timeline - timeline_immutable = Immutable.fromJS(timeline) - - myCtrl = controller("UserTimelineItem", {$scope: scope}, {timeline: timeline_immutable}) - - expect(myCtrl.activity.user).to.be.equal(timeline.data.user) - expect(myCtrl.activity.project).to.be.equal(timeline.data.project) - expect(myCtrl.activity.sprint).to.be.equal(timeline.data.milestone) - expect(myCtrl.activity.title).to.be.equal("fakeTitle") - expect(myCtrl.activity.created_formated).to.have.length.above(1) - it "all activity fields filled", () -> timeline = scope.vm.timeline - attachment = "fakeAttachment" - timeline.data.values_diff.attachments = { - new: attachment - } - description = "fakeDescription" member = "fakeMember" - mockType.description.withArgs(timeline).returns(description) - mockType.member.withArgs(timeline).returns(member) + mockType.description.returns(description) + mockType.member.returns(member) - timeline_immutable = Immutable.fromJS(timeline) + myCtrl = controller("UserTimelineItem", {$scope: scope}, {timeline: timeline}) - myCtrl = controller("UserTimelineItem", {$scope: scope}, {timeline: timeline_immutable}) - - expect(myCtrl.activity.description).to.be.equal(description) - expect(myCtrl.activity.member).to.be.equal(member) - expect(myCtrl.activity.attachments).to.be.equal(attachment) + expect(myCtrl.timeline.get('title_html')).to.be.equal("fakeTitle") + expect(myCtrl.timeline.get('obj')).to.be.equal(myCtrl.timeline.getIn(["data", "issue"])) + expect(myCtrl.timeline.get("description")).to.be.equal(description) + expect(myCtrl.timeline.get("member")).to.be.equal(member) + expect(myCtrl.timeline.get("attachments")).to.be.equal("fakeAttachment") diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade index 3b26c847..6ed8f7f9 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade @@ -1,22 +1,29 @@ div.activity-item - span.activity-date {{::vm.activity.created_formated}} + span.activity-date {{::vm.timeline.get('created') | momentFromNow}} + + div.activity-info(tg-user-timeline-title="vm.timeline") + div.activity-info - div.profile-contact-picture - a(tg-nav="user-profile:username=vm.activity.user.username", title="{{::vm.activity.user.name }}") - img(ng-src="{{::vm.activity.user.photo || '/images/user-noimage.png'}}", alt="{{::vm.activity.user.name}}") + // profile image with url + div.profile-contact-picture(ng-if="vm.timeline.getIn(['data', 'user', 'is_profile_visible'])") + a(tg-nav="user-profile:username=vm.timeline.getIn(['data', 'user', 'username'])", title="{{::vm.timeline.getIn(['data', 'user', 'name']) }}") + img(ng-src="{{::vm.timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::vm.timeline.getIn(['data', 'user', 'name'])}}") + // profile image without url + div.profile-contact-picture(ng-if="!vm.timeline.getIn(['data', 'user', 'is_profile_visible'])") + img(ng-src="{{::vm.timeline.getIn(['data', 'user', 'photo']) || '/images/user-noimage.png'}}", alt="{{::vm.timeline.getIn(['data', 'user', 'name'])}}") - p(tg-compile-html="vm.activity.title") + p(tg-compile-html="vm.timeline.get('title_html')") - blockquote.activity-comment-quote(ng-if="::vm.activity.description") - | {{::vm.activity.description | limitTo:300}} + blockquote.activity-comment-quote(ng-if="::vm.timeline.get('description')") + | {{::vm.timeline.get('description') | limitTo:300}} - .activity-member-view(ng-if="::vm.activity.member") - a.profile-member-picture(tg-nav="user-profile:username=vm.activity.member.user.username", title="{{::vm.activity.member.user.name }}") - img(ng-src="{{::vm.activity.member.user.photo}}", alt="{{::vm.activity.member.user.name}}") + .activity-member-view(ng-if="::vm.timeline.has('member')") + a.profile-member-picture(tg-nav="user-profile:username=vm.timeline.getIn(['member', 'user', 'username'])", title="{{::vm.timeline.getIn(['member', 'user', 'name'])}}") + img(ng-src="{{::vm.timeline.getIn(['member', 'user', 'photo'])}}", alt="{{::vm.timeline.getIn(['member','user', 'name'])}}") .activity-member-info - a(tg-nav="user-profile:username=vm.activity.member.user.username", title="{{::vm.activity.member.user.name }}") - span {{::vm.activity.member.user.name}} - p {{::vm.activity.member.role.name}} + a(tg-nav="user-profile:username=vm.timeline.getIn(['member', 'user', 'username'])", title="{{::vm.timeline.getIn(['member','user', 'name'])}}") + span {{::vm.timeline.getIn(['member','user', 'name'])}} + p {{::vm.timeline.getIn(['member','role', 'name'])}} - div(ng-repeat="attachment in vm.activity.attachments") + div(ng-repeat="attachment in vm.timeline.get('attachments')") div(tg-user-timeline-attachment="attachment") diff --git a/app/modules/user-timeline/user-timeline/user-timeline.scss b/app/modules/user-timeline/user-timeline/user-timeline.scss index 192afee8..38cb644a 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.scss +++ b/app/modules/user-timeline/user-timeline/user-timeline.scss @@ -6,15 +6,16 @@ p { margin-bottom: 0; } - a { + a, + .username { color: $primary; &:first-child { @extend %bold; color: $gray; } - &:hover { - color: $primary-light; - } + } + a:hover { + color: $primary-light; } blockquote { line-height: 1.4rem; diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee index 052c491b..ed82befb 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee @@ -5,19 +5,37 @@ class UserTimelineService extends taiga.Service constructor: (@rs, @userTimelinePaginationSequenceService) -> + _valid_fields: [ + 'status', + 'subject', + 'description_diff', + 'assigned_to', + 'points', + 'severity', + 'priority', + 'type', + 'attachments', + 'milestone', + 'is_iocaine', + 'content_diff', + 'name', + 'estimated_finish', + 'estimated_start', + 'blocked' + ] + _invalid: [ {# Items with only invalid fields check: (timeline) -> - values_diff = timeline.get("data").get("values_diff") + value_diff = timeline.get("data").get("value_diff") - if values_diff - values = Object.keys(values_diff.toJS()) + if value_diff + fieldKey = value_diff.get('key') - if values && values.length - if _.every(values, (value) => @._valid_fields.indexOf(value) == -1) + if @._valid_fields.indexOf(fieldKey) == -1 return true - else if values[0] == 'attachments' && - values_diff.get('attachments').get('new').size == 0 + else if fieldKey == 'attachments' && + value_diff.get('value').get('new').size == 0 return true return false @@ -39,42 +57,57 @@ class UserTimelineService extends taiga.Service {# Task milestone check: (timeline) -> event = timeline.get('event_type').split(".") + value_diff = timeline.get("data").get("value_diff") - if event[1] == "task" && event[2] == "change" - return timeline.get("data").get("values_diff").get("milestone") + if value_diff && + event[1] == "task" && + event[2] == "change" && + value_diff.get("key") == "milestone" + return timeline.get("data").get("value_diff").get("value") return false } ] - _valid_fields: [ - 'status', - 'subject', - 'description_diff', - 'assigned_to', - 'points', - 'severity', - 'priority', - 'type', - 'attachments', - 'milestone', - 'is_blocked', - 'is_iocaine', - 'content_diff', - 'name', - 'estimated_finish', - 'estimated_start' - ] - _isInValidTimeline: (timeline) -> return _.some @._invalid, (invalid) => return invalid.check.call(this, timeline) + # create a entry per every item in the values_diff + _splitChanges: (response) -> + newdata = Immutable.List() + + response.get('data').forEach (item) -> + data = item.get('data') + values_diff = data.get('values_diff') + + if values_diff && values_diff.count() + # blocked/unblocked change must be a single change + if values_diff.has('is_blocked') + values_diff = Immutable.Map({'blocked': values_diff}) + + values_diff.forEach (value, key) -> + obj = Immutable.Map({ + key: key, + value: value + }) + + newItem = item.setIn(['data', 'value_diff'], obj) + newItem = newItem.deleteIn(['data', 'values_diff']) + newdata = newdata.push(newItem) + else + newItem = item.deleteIn(['data', 'values_diff']) + newdata = newdata.push(newItem) + + return response.set('data', newdata) + getProfileTimeline: (userId) -> config = {} config.fetch = (page) => return @rs.users.getProfileTimeline(userId, page) + .then (response) => + return @._splitChanges(response) config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) @@ -86,6 +119,8 @@ class UserTimelineService extends taiga.Service config.fetch = (page) => return @rs.users.getUserTimeline(userId, page) + .then (response) => + return @._splitChanges(response) config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) @@ -97,6 +132,7 @@ class UserTimelineService extends taiga.Service config.fetch = (page) => return @rs.projects.getTimeline(projectId, page) + .then (response) => return @._splitChanges(response) config.filter = (items) => return items.filterNot (item) => @._isInValidTimeline(item) diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee index 4735b474..64f2198c 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee @@ -7,7 +7,9 @@ describe "tgUserTimelineService", -> mocks.resources = {} mocks.resources.users = { - getTimeline: sinon.stub() + getTimeline: sinon.stub(), + getProfileTimeline: sinon.stub(), + getUserTimeline: sinon.stub() } mocks.resources.projects = { @@ -147,73 +149,66 @@ describe "tgUserTimelineService", -> userId = 3 page = 2 - mocks.resources.users.getProfileTimeline = (_userId_) -> - expect(_userId_).to.be.equal(userId) + response = Immutable.fromJS({ + data: valid_items + }) - return Immutable.fromJS(valid_items) + mocks.resources.users.getProfileTimeline.withArgs(userId).promise().resolve(response) mocks.userTimelinePaginationSequence.generate = (config) -> - all = config.fetch() - expect(all.size).to.be.equal(11) + return config.fetch().then (res) -> + expect(res.get('data').size).to.be.equal(14) - items = config.filter(all).toJS() - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) + items = config.filter(res.get('data')) + expect(items.size).to.be.equal(5) - return true + return true result = userTimelineService.getProfileTimeline(userId) - expect(result).to.be.true + + return expect(result).to.be.eventually.true it "filter invalid user timeline items", () -> userId = 3 page = 2 - mocks.resources.users.getUserTimeline = (_userId_) -> - expect(_userId_).to.be.equal(userId) + response = Immutable.fromJS({ + data: valid_items + }) - return Immutable.fromJS(valid_items) + mocks.resources.users.getUserTimeline.withArgs(userId).promise().resolve(response) mocks.userTimelinePaginationSequence.generate = (config) -> - all = config.fetch() - expect(all.size).to.be.equal(11) + return config.fetch().then (res) -> + expect(res.get('data').size).to.be.equal(14) - items = config.filter(all).toJS() - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) + items = config.filter(res.get('data')) + expect(items.size).to.be.equal(5) - return true + return true result = userTimelineService.getUserTimeline(userId) - expect(result).to.be.true - it "filter invalid user timeline items", () -> + return expect(result).to.be.eventually.true + + it "filter invalid project timeline items", () -> userId = 3 page = 2 - mocks.resources.projects.getTimeline = (_userId_) -> - expect(_userId_).to.be.equal(userId) + response = Immutable.fromJS({ + data: valid_items + }) - return Immutable.fromJS(valid_items) + mocks.resources.projects.getTimeline.withArgs(userId).promise().resolve(response) mocks.userTimelinePaginationSequence.generate = (config) -> - all = config.fetch() - expect(all.size).to.be.equal(11) + return config.fetch().then (res) -> + expect(res.get('data').size).to.be.equal(14) - items = config.filter(all).toJS() - expect(items).to.have.length(4) - expect(items[0]).to.be.eql(valid_items[0]) - expect(items[1]).to.be.eql(valid_items[3]) - expect(items[2]).to.be.eql(valid_items[5]) - expect(items[3]).to.be.eql(valid_items[9]) + items = config.filter(res.get('data')) + expect(items.size).to.be.equal(5) - return true + return true result = userTimelineService.getProjectTimeline(userId) - expect(result).to.be.true + expect(result).to.be.eventually.true diff --git a/karma.conf.js b/karma.conf.js index ac545dfe..1dbc8720 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -14,7 +14,7 @@ module.exports = function(config) { // frameworks to use // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['mocha', 'sinon-chai'], + frameworks: ['mocha', 'chai', 'chai-as-promised', 'sinon-chai'], // list of files / patterns to load in the browser diff --git a/package.json b/package.json index eb64c67d..bfd6dd6b 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "author": "Kaleidos OpenSource SL", "license": "AGPL-3.0", "repository": { - "type":"git", - "url":"https://github.com/taigaio/taiga-front.git" + "type": "git", + "url": "https://github.com/taigaio/taiga-front.git" }, "scripts": { "scss-lint": "gulp scss-lint --fail", @@ -57,12 +57,10 @@ "gulp-wrap": "^0.11.0", "inquirer": "^0.8.2", "karma": "^0.12.31", - "karma-chai": "^0.1.0", + "karma-chai-plugins": "^0.6.0", "karma-chrome-launcher": "^0.1.7", "karma-coffee-preprocessor": "^0.2.1", "karma-mocha": "^0.1.10", - "karma-sinon": "^1.0.4", - "karma-sinon-chai": "^0.3.0", "karma-sourcemap-loader": "^0.3.4", "minimist": "^1.1.1", "mocha": "^2.2.4", From c7835769e78b0fc6409995101cfe28dbab4fe681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 21 Jul 2015 11:45:49 +0200 Subject: [PATCH 067/403] Travis: Migrating from legacy to container-based infrastructure --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 18a06b23..25ce3621 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +sudo: false + before_install: - export CHROME_BIN=chromium-browser - export DISPLAY=:99.0 @@ -11,4 +13,4 @@ before_script: - gulp deploy language: node_js node_js: - - "0.12" \ No newline at end of file + - "0.12" From f614c3eb196680d81a512743ef9ee8bdba1bb225 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 22 Jul 2015 14:14:34 +0200 Subject: [PATCH 068/403] Fixing translations --- app/coffee/modules/backlog/main.coffee | 14 ++++++++------ app/locales/locale-en.json | 2 +- app/partials/us/us-detail.jade | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 86fe61b5..75bafc3e 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -1067,14 +1067,16 @@ module.directive("tgBurndownBacklogGraph", ["$translate", BurndownBacklogGraphDi ## Backlog progress bar directive ############################################################################# -TgBacklogProgressBarDirective = ($template) -> +TgBacklogProgressBarDirective = ($template, $compile) -> template = $template.get("backlog/progress-bar.html", true) - render = (el, projectPointsPercentaje, closedPointsPercentaje) -> - el.html(template({ + render = (scope, el, projectPointsPercentaje, closedPointsPercentaje) -> + html = template({ projectPointsPercentaje: projectPointsPercentaje, closedPointsPercentaje:closedPointsPercentaje - })) + }) + html = $compile(html)(scope) + el.html(html) adjustPercentaje = (percentage) -> adjusted = _.max([0 , percentage]) @@ -1098,11 +1100,11 @@ TgBacklogProgressBarDirective = ($template) -> projectPointsPercentaje = adjustPercentaje(projectPointsPercentaje - 3) closedPointsPercentaje = adjustPercentaje(closedPointsPercentaje - 3) - render($el, projectPointsPercentaje, closedPointsPercentaje) + render($scope, $el, projectPointsPercentaje, closedPointsPercentaje) $scope.$on "$destroy", -> $el.off() return {link: link} -module.directive("tgBacklogProgressBar", ["$tgTemplate", TgBacklogProgressBarDirective]) +module.directive("tgBacklogProgressBar", ["$tgTemplate", "$compile", TgBacklogProgressBarDirective]) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index eef0352d..c8015f2f 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Type a short description", "DEPRECATED": "(deprecated)", "DEPRECATED_FILE": "Deprecated?", - "ADD": "Add new attachment. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. size: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ show deprecated atachments", "HIDE_DEPRECATED": "- hide deprecated atachments", diff --git a/app/partials/us/us-detail.jade b/app/partials/us/us-detail.jade index ddfd9b4e..bb2de2ac 100644 --- a/app/partials/us/us-detail.jade +++ b/app/partials/us/us-detail.jade @@ -75,6 +75,6 @@ div.wrapper(ng-controller="UserStoryDetailController as ctrl", on-delete-go-to-url="onDeleteGoToUrl", ng-model="us") - div.lightbox.lightbox-block(tg-lb-block, title="US.LIGHTBOX_TITLE_BLOKING_US", ng-model="us") + div.lightbox.lightbox-block(tg-lb-block, title="{{ 'US.LIGHTBOX_TITLE_BLOKING_US' | translate }}", ng-model="us") div.lightbox.lightbox-select-user(tg-lb-assignedto) div.lightbox.lightbox-select-user(tg-lb-watchers) From 5eb173d9cf67967c61c512c7ffedb1cf4a4b5b94 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 22 Jul 2015 14:56:36 +0200 Subject: [PATCH 069/403] fix issue #3094 - angular code xss in comments --- app/partials/common/history/history-activity.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/partials/common/history/history-activity.jade b/app/partials/common/history/history-activity.jade index 85f069f4..ee6152fa 100644 --- a/app/partials/common/history/history-activity.jade +++ b/app/partials/common/history/history-activity.jade @@ -15,7 +15,7 @@ div(class!="activity-single <%- mode %>") span(translate="COMMENTS.DELETED_INFO", translate-values!="{ user: '<%- deleteCommentUser %>', date: '<%- deleteCommentDate %>'}") <% } %> - .comment.wysiwyg + .comment.wysiwyg(ng-non-bindable) | <%= comment %> <% if (!deleteCommentDate && mode !== "activity" && canDeleteComment) { %> a(href="", class="icon icon-delete comment-delete", data-activity-id!="<%- activityId %>") From 5ba8d3a60e7f212d41e5c5f489681b79b79f69c7 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 23 Jul 2015 11:16:07 +0200 Subject: [PATCH 070/403] Fixing list edition on rich editor --- app/coffee/modules/common/wisiwyg.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/coffee/modules/common/wisiwyg.coffee b/app/coffee/modules/common/wisiwyg.coffee index 37ade9d3..cfd6a6bb 100644 --- a/app/coffee/modules/common/wisiwyg.coffee +++ b/app/coffee/modules/common/wisiwyg.coffee @@ -184,7 +184,12 @@ MarkitupDirective = ($rootscope, $rs, $selectedText, $template, $compile, $trans replaceWith: () -> "\n" afterInsert: (data) -> lines = data.textarea.value.split("\n") - cursorLine = data.textarea.value[0..(data.caretPosition - 1)].split("\n").length + # Detect if we are in this situation +- aa at the beginning if the textarea + if data.caretPosition > 0 + cursorLine = data.textarea.value[0..(data.caretPosition - 1)].split("\n").length + else + cursorLine = 1 + newLineContent = data.textarea.value[data.caretPosition..].split("\n")[0] lastLine = lines[cursorLine - 1] From 29e68dd0a138df21a20b0ac11ccda9944e7c655d Mon Sep 17 00:00:00 2001 From: CliffBrown Date: Thu, 23 Jul 2015 23:33:04 +0100 Subject: [PATCH 071/403] Correct spelling for analyze --- app/locales/locale-en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index c8015f2f..daa387fd 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Reports", "SUBTITLE": "Export your project data in CSV format and make your own reports.", - "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analize all your data easily.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "How to use this on my own spreadsheet?", "REGENERATE_TITLE": "Change URL", "REGENERATE_SUBTITLE": "You going to change the CSV data access url. The previous url will be disabled. Are you sure?" From 13d10e9507cc14e982256efca038269a36ec7a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 25 Jul 2015 20:11:19 +0200 Subject: [PATCH 072/403] [i18n] Update locales --- app/locales/locale-ca.json | 5 +- app/locales/locale-de.json | 11 +-- app/locales/locale-es.json | 5 +- app/locales/locale-fi.json | 5 +- app/locales/locale-fr.json | 137 ++++++++++++++++---------------- app/locales/locale-nl.json | 5 +- app/locales/locale-zh-hant.json | 5 +- 7 files changed, 90 insertions(+), 83 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index f410a230..374c2e3d 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Escriu una descripció curta", "DEPRECATED": "(obsolet)", "DEPRECATED_FILE": "Obsolet?", - "ADD": "Afegir nou adjunt. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. grandària: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ mostra els adjunts obsolets", "HIDE_DEPRECATED": "- Amagar els adjunts obsolets", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Informes", "SUBTITLE": "Exporta les dades del teu projecte en CSV i fes els teus propis informes.", - "DESCRIPTION": "Descarrega el fitxer CSV o copia la URL generada o obri-la amb el teu editor de text o fulla de càlcul per a fer els teus propis informes. Podràs visualitzar i analitzar les dades fàcilment.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "Com utilitzar açó a la meu fulla de càlcul?", "REGENERATE_TITLE": "Canviar URL", "REGENERATE_SUBTITLE": "Vas a canviar la URL d'accés al CSV. La URL previa no funcionarà. Estàs segur?" @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index c2bfb263..49290993 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Geben Sie eine kurze Beschreibung ein", "DEPRECATED": "(verworfen)", "DEPRECATED_FILE": "Verworfen?", - "ADD": "Neuen Anhang hinzufügen. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. Größe: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ verworfene Anhänge zeigen", "HIDE_DEPRECATED": "- verworfene Anhänge verbergen", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Berichte", "SUBTITLE": "Exportieren Sie Ihre Projektdaten in CSV Format und erstellen Sie Ihre eigenen Berichte. ", - "DESCRIPTION": "Laden Sie eine CSV Datei herunter oder kopieren Sie die generierte URL und öffnen Sie sie in Ihrem bevorzugten Text-Editor oder in Ihrer Tabellenkalkulation, um Ihre eigenen Projektdaten-Berichte zu erstellen. So können Sie Ihre Daten leicht überblicken und analysieren.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "Wie kann ich dies in meiner eigenen Tabellenkalkulation nutzen?", "REGENERATE_TITLE": "Die URL ändern", "REGENERATE_SUBTITLE": "Sie sind im Begriff, die CSV data access URL zu ändern. Die vorherige URL wird deaktiviert. Sind Sie sicher?" @@ -896,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punkte", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", - "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "OPTIMAL": "Optimale unerledigte Punkte für Sprint \"{{sprintName}}\" sollten sein {{value}}", + "REAL": "Tatsächliche Anzahl unerledigter Punkte für Sprint \"{{sprintName}}\" ist {{value}}", "INCREMENT_TEAM": "Erhöhte Punktezahl von Teamanfragen für Sprint \"{{sprintName}}\" ist {{value}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" + "INCREMENT_CLIENT": "Erhöhte Punkteanzahl von Kundenanfragen für Sprint \"{{sprintName}}\" ist {{value}}" }, "TAGS": { "TOGGLE": "Sichtbarkeit des Schlagwortes umschalten", @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} aktualisierte den Sprint {{obj_name}}", "US_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}} zu {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}} zu {{new_value}}", "TASK_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} zu {{new_value}}", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 8dec9703..d31eff16 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Escribe una pequeña descripción", "DEPRECATED": "(obsoleto)", "DEPRECATED_FILE": "¿Desactualizado?", - "ADD": "Agrega nuevos adjunto", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Tamaño Max. : {{maxFileSize}}]", "SHOW_DEPRECATED": "+ muestra adjuntos desactualizados", "HIDE_DEPRECATED": "- ocultar adjuntos obsoletos", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Informes", "SUBTITLE": "Exporta los datos de tu proyecto en formato CSV y crea tus propios informes.", - "DESCRIPTION": "Descarga el fichero CSV o copia la URL generada y abre tu editor de textos o hoja de cálculo favorito para realizar tus propios informes. Podrás visualizar y analizar todos los datos fácilmente.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "¿Cómo puedo usar esto en mi hoja de cálculo?", "REGENERATE_TITLE": "Cambiar URL", "REGENERATE_SUBTITLE": "Vas a cambiar la url de acceso a los datos en formato CSV. La url anterior se deshabilitará. ¿Estás seguro?" @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} ha actualizado el sprint {{obj_name}}", "US_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}} a {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}} a {{new_value}}", "TASK_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} a {{new_value}}", diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index 9d9e4bd8..1a227df0 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Kirjoita lyhyt kuvaus", "DEPRECATED": "(poistettu)", "DEPRECATED_FILE": "Vanhentunut?", - "ADD": "Lisää liite. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Maks. koko: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ näytä vanhentuneet liitteet", "HIDE_DEPRECATED": "- piilota vanhentuneet liitteet", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Raportit", "SUBTITLE": "Vie projektisi CSV-tiedostoon", - "DESCRIPTION": "Lataa CSV-tiedosto tai luo URL ja avaa haluamassasi ohjelmassa. Voit visualisoida ja analysoida tietoa helposti.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "Kuinka tätä käytetään omassa taulukossani?", "REGENERATE_TITLE": "Vaihda URL", "REGENERATE_SUBTITLE": "Jos muutata CSV-datan URLia, edellien lakkaa toimimasta. Oletko varma?" @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 620d4937..b1efbe28 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -2,7 +2,7 @@ "COMMON": { "YES": "Oui", "NO": "Non", - "LOADING": "Chargement...", + "LOADING": "Veuillez patienter...", "LOADING_PROJECT": "Chargement du projet...", "DATE": "DD MMM YYYY", "DATETIME": "DD MMM YYYY HH:mm", @@ -103,7 +103,7 @@ "SEE_USER_PROFILE": "Afficher le profil de {{username}}", "USER_STORY": "Récit utilisateur", "TASK": "Tâche", - "ISSUE": "Suivi de problème", + "ISSUE": "Ticket", "TAGS": { "PLACEHOLDER": "Taggez moi !", "DELETE": "Supprimer le mot-clé", @@ -220,11 +220,11 @@ "DELETE_TASKS": "Supprimer des tâches" }, "ISSUES": { - "NAME": "Problèmes", - "VIEW_ISSUES": "Voir les suivis de problèmes", - "ADD_ISSUES": "Ajouter des suivis de problèmes", - "MODIFY_ISSUES": "Modifier des suivis de problèmes", - "DELETE_ISSUES": "Supprimer des suivis de problèmes" + "NAME": "Tickets", + "VIEW_ISSUES": "Voir les tickets", + "ADD_ISSUES": "Ajouter des tickets", + "MODIFY_ISSUES": "Modifier des tickets", + "DELETE_ISSUES": "Supprimer des tickets" }, "WIKI": { "NAME": "Wiki", @@ -253,7 +253,7 @@ "CREATE_ACCOUNT": "créer votre compte gratuit ici" }, "LOGIN_COMMON": { - "HEADER": "J'ai déjà un login Taiga", + "HEADER": "J'ai déjà un identifiant Taiga", "PLACEHOLDER_AUTH_NAME": "Nom d'utilisateur ou adresse courriel (sensible à la casse)", "LINK_FORGOT_PASSWORD": "Mot de passe oublié?", "TITLE_LINK_FORGOT_PASSWORD": "Avez-vous oublié votre mot de passe ?", @@ -288,7 +288,7 @@ "SUBTITLE": "Saisissez votre nom d'utilisateur ou votre adresse courriel pour en obtenir un nouveau", "PLACEHOLDER_FIELD": "Nom d'utilisateur ou adresse courriel", "ACTION_RESET_PASSWORD": "Réinitialiser le mot de passe", - "LINK_CANCEL": "Nan, ramenez-moi en arrière. Je crois que je m'en rappelle.", + "LINK_CANCEL": "Nan, ramenez-moi en arrière. Je crois que je m'en souviens.", "SUCCESS": "Consultez votre messagerie!
Nous venons d'envoyer un courriel avec les instructions pour créer un nouveau mot de passe", "ERROR": "D'après nos Oompa Loompas, vous n'êtes pas encore enregistré." }, @@ -326,8 +326,8 @@ }, "HOME": { "PAGE_TITLE": "Accueil - Taiga", - "PAGE_DESCRIPTION": "La page d'accueil de Taiga sur laquelle apparaissent vos projets principaux et toutes les récits utilisateur, tâches et suivis de problèmes qui vont sont assignés et surveillés.", - "EMPTY_WATCHING": "Suivre les projets, Récits Utilisateur, Tâches, Problèmes... que vous voulez connaître :)", + "PAGE_DESCRIPTION": "La page d'accueil de Taiga sur laquelle apparaissent vos projets principaux et toutes les récits utilisateur, tâches et tickets qui vont sont assignés et surveillés.", + "EMPTY_WATCHING": "Suivre les projets, Récits Utilisateur, Tâches, Tickets... que vous voulez connaître :)", "EMPTY_PROJECT_LIST": "Vous n'avez aucun projet pour l'instant", "WORKING_ON_SECTION": "Projets en cours", "WATCHING_SECTION": "Observant" @@ -343,7 +343,7 @@ "DESCRIPTION": "Saisissez une courte description", "DEPRECATED": "(obsolète)", "DEPRECATED_FILE": "Obsolète?", - "ADD": "Ajouter une pièce jointe. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Taille max.: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ montrer les pièces jointes obsolètes", "HIDE_DEPRECATED": "- cacher les pièces jointes obsolètes", @@ -400,7 +400,7 @@ "BACKLOG_DESCRIPTION": "Gérez votre récits utilisateur pour garder une vue organisée des travaux à venir et priorisés.", "KANBAN": "Kanban", "KANBAN_DESCRIPTION": "Organisez votre projet de manière agile avec ce tableau.", - "ISSUES": "Suivis de problèmes", + "ISSUES": "Tickets", "ISSUES_DESCRIPTION": "Suivez les bugs, questions et améliorations liés à votre projet. Ne ratez rien !", "WIKI": "Wiki", "WIKI_DESCRIPTION": "Ajoutez, modifiez, ou supprimez du contenu en collaboration avec d'autres. C'est le bon endroit pour la documentation de votre projet.", @@ -411,8 +411,8 @@ "JITSI_CHAT_ROOM": "Jitsi", "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", - "CUSTOM_CHAT_ROOM": "Custom", - "URL_CHAT_ROOM": "URL of your chat room" + "CUSTOM_CHAT_ROOM": "Personnalisé", + "URL_CHAT_ROOM": "URL du salon de discussion" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - Profil projet - {{projectName}}\n", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Rapports", "SUBTITLE": "Exportez les données de votre projet au format CSV pour créer vos propres rapports.", - "DESCRIPTION": "Téléchargez un fichier CSV ou copiez l'URL générée et ouvrez-là dans votre éditeur de texte ou feuille de calcul favorite pour créer vos propres rapports de projet. Vous pourrez visualiser et analyser toutes vos données facilement.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "Comment utiliser ceci dans ma propre feuille de calcul?", "REGENERATE_TITLE": "Changer l'URL", "REGENERATE_SUBTITLE": "Vous êtes sur le point de changer l'url d'accès aux données CSV. L'url précédente sera désactivée. Êtes-vous sûre ?" @@ -438,7 +438,7 @@ "CSV": { "SECTION_TITLE_US": "Rapports des récits utilisateur", "SECTION_TITLE_TASK": "rapports des tâches", - "SECTION_TITLE_ISSUE": "Rapports des suivis de problèmes", + "SECTION_TITLE_ISSUE": "Rapports des tickets", "DOWNLOAD": "Télécharger au format CSV", "URL_FIELD_PLACEHOLDER": "Merci de regénérer l'url de téléchargement au format CSV", "TITLE_REGENERATE_URL": "Regénérer l'URL du CSV", @@ -447,15 +447,15 @@ }, "CUSTOM_FIELDS": { "TITLE": "Champs Personnalisés", - "SUBTITLE": "Spécifiez les champs personnalisés de vos récits utilisateur, tâches et problèmes", + "SUBTITLE": "Spécifiez les champs personnalisés de vos récits utilisateur, tâches et tickets", "US_DESCRIPTION": "Champs personnalisés des récits utilisateur", "US_ADD": "Ajouter un champ personnalisé dans les récits utilisateur", "TASK_DESCRIPTION": "Champs personnalisés de tâches", "TASK_ADD": "Ajouter un champ personnalisé dans les tâches", - "ISSUE_DESCRIPTION": "Champs personnalisés des problèmes", - "ISSUE_ADD": "Ajouter un champ personnalisé dans les problèmes", - "FIELD_TYPE_TEXT": "Text", - "FIELD_TYPE_MULTI": "Multi-line" + "ISSUE_DESCRIPTION": "Champs personnalisés des tickets", + "ISSUE_ADD": "Ajouter un champ personnalisé dans les tickets", + "FIELD_TYPE_TEXT": "Texte", + "FIELD_TYPE_MULTI": "Multiligne" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Valeurs du projet - {{projectName}}", @@ -470,27 +470,27 @@ }, "PROJECT_VALUES_PRIORITIES": { "TITLE": "Priorités", - "SUBTITLE": "Spécifiez les priorités qu'auront vos suivis de problèmes", - "ISSUE_TITLE": "Priorités de problèmes", + "SUBTITLE": "Spécifiez les priorités qu'auront vos tickets", + "ISSUE_TITLE": "Priorités de tickets", "ACTION_ADD": "Ajouter une priorité" }, "PROJECT_VALUES_SEVERITIES": { "TITLE": "Sévérités", - "SUBTITLE": "Spécifiez les sévérités qu'auront vos problèmes", - "ISSUE_TITLE": "Sévérités des suivis de problèmes", + "SUBTITLE": "Spécifiez les sévérités qu'auront vos tickets", + "ISSUE_TITLE": "Sévérités des tickets", "ACTION_ADD": "Ajouter un degré de sévérité" }, "PROJECT_VALUES_STATUS": { "TITLE": "Statut", - "SUBTITLE": "Spécifiez les statuts que vont prendre vos récits utilisateur, tâches et suivis de problèmes", + "SUBTITLE": "Spécifiez les statuts que vont prendre vos récits utilisateur, tâches et tickets", "US_TITLE": "Statuts des HU", "TASK_TITLE": "Statuts des Tâches", - "ISSUE_TITLE": "Statuts des Problèmes" + "ISSUE_TITLE": "Statuts des Tickets" }, "PROJECT_VALUES_TYPES": { "TITLE": "Types", "SUBTITLE": "Spécifiez les priorités qu'auront vos bugs", - "ISSUE_TITLE": "Types de problèmes", + "ISSUE_TITLE": "Types de tickets", "ACTION_ADD": "Ajouter un nouveau {{objName}}" }, "ROLES": { @@ -669,7 +669,7 @@ "TIMELINE": "Chronologie", "BACKLOG": "Backlog", "KANBAN": "Kanban", - "ISSUES": "Suivis de problèmes", + "ISSUES": "Tickets", "WIKI": "Wiki", "TEAM": "Équipe", "MEETUP": "Meet up", @@ -730,7 +730,7 @@ "DELETE_PROJECT": { "TITLE": "Supprimer le projet", "QUESTION": "Êtes-vous sûr de vouloir supprimer ce projet?", - "SUBTITLE": "Toutes les données ( récit utilisateur, tâches, problèmes, sprints et pages de wiki) seront perdues! :-(", + "SUBTITLE": "Toutes les données ( récit utilisateur, tâches, tickets, sprints et pages de wiki) seront perdues! :-(", "CONFIRM": "Oui, je suis sûr" }, "ASSIGNED_TO": { @@ -742,7 +742,7 @@ "HELP_TEXT": "Si vos utilisateurs sont déjà inscrits sur Taiga, ils seront automatiquement ajoutés. Sinon, ils recevront une invitation." }, "CREATE_ISSUE": { - "TITLE": "Ajouter un suivi de problème" + "TITLE": "Ajouter un ticket" }, "FEEDBACK": { "TITLE": "Dites nous quelque chose...", @@ -793,8 +793,8 @@ "TOTAL_POINTS": "total", "ADD": "Ajouter un nouveau récit utilisateur", "ADD_BULK": "Ajouter de nouveaux récits utilisateur en lot", - "PROMOTED": "Ce récit utilisateur a été promue à partir d'un suivi de problème :", - "TITLE_LINK_GO_TO_ISSUE": "Aller vers ce suivi de problème", + "PROMOTED": "Ce récit utilisateur a été promue à partir d'un ticket :", + "TITLE_LINK_GO_TO_ISSUE": "Aller vers ce ticket", "EXTERNAL_REFERENCE": "Ce récit utilisateur a été créé depuis", "GO_TO_EXTERNAL_REFERENCE": "Allez à l'origine", "BLOCKED": "Ce récit utilisateur est bloqué", @@ -896,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Points", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", - "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" + "OPTIMAL": "Le nombre optimal de points pour le sprint \"{{sprintName}}\" devrait être {{value}}", + "REAL": "Le nombre réel de points pour le sprint \"{{sprintName}}\" est {{value}}", + "INCREMENT_TEAM": "Le nombre de points ajoutés par les exigences de l'équipe pour le sprint \"{{sprintName}}\" est {{value}}", + "INCREMENT_CLIENT": "Le nombre de points ajoutés par les exigences du client pour le sprint \"{{sprintName}}\" est {{value}}" }, "TAGS": { "TOGGLE": "Afficher/Cacher les tags", @@ -917,7 +917,7 @@ "CLOSED_TASKS": "tâches
fermées", "IOCAINE_DOSES": "doses
de iocaine", "SHOW_STATISTICS_TITLE": "Afficher les statistiques", - "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" + "TOGGLE_BAKLOG_GRAPH": "Afficher/masquer le graphique d'avancement" }, "SUMMARY": { "PROJECT_POINTS": "projet
points", @@ -1029,29 +1029,29 @@ "SUCCESS": "Nos Oompa Loompas ont mis à jour votre adresse courriel" }, "ISSUES": { - "PAGE_TITLE": "Problèmes - {{projectName}}", - "PAGE_DESCRIPTION": "Le panneau de la liste des problèmes du projet {{projectName}} : {{projectDescription}}", - "LIST_SECTION_NAME": "Problèmes", - "SECTION_NAME": "Détails du problème", - "ACTION_NEW_ISSUE": "+ NOUVEAU PROBLÈME", + "PAGE_TITLE": "Tickets - {{projectName}}", + "PAGE_DESCRIPTION": "Le panneau de la liste des tickets du projet {{projectName}} : {{projectDescription}}", + "LIST_SECTION_NAME": "Tickets", + "SECTION_NAME": "Détails du ticket", + "ACTION_NEW_ISSUE": "+ NOUVEAU TICKET", "ACTION_PROMOTE_TO_US": "Transformer en User Story", "PLACEHOLDER_FILTER_NAME": "Écrivez le nom du filtre et appuyez sur \"Entrée\"", - "PROMOTED": "Le problème a été promu en récit utilisateur", - "EXTERNAL_REFERENCE": "Ce problème a été créé à partir de", + "PROMOTED": "Le ticket a été promu en récit utilisateur", + "EXTERNAL_REFERENCE": "Ce ticket a été créé à partir de", "GO_TO_EXTERNAL_REFERENCE": "Aller à l'origine", "BLOCKED": "Ce bug est bloqué", "TITLE_PREVIOUS_ISSUE": "bug précédent", - "TITLE_NEXT_ISSUE": "problème suivant", - "ACTION_DELETE": "Supprimer le problème", - "LIGHTBOX_TITLE_BLOKING_ISSUE": "Problème bloquant", + "TITLE_NEXT_ISSUE": "ticket suivant", + "ACTION_DELETE": "Supprimer le ticket", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Ticket bloquant", "FIELDS": { "PRIORITY": "Priorité", "SEVERITY": "Sévérité", "TYPE": "Type" }, "CONFIRM_PROMOTE": { - "TITLE": "Transformer ce problème en une nouvelle user story", - "MESSAGE": "Etes-vous sure de vouloir créer un nouvelle US à partir de ce problème ?" + "TITLE": "Transformer ce ticket en un nouveau récit utilisateur", + "MESSAGE": "Êtes-vous sure de vouloir créer un nouveau récit utilisateur à partir de ce ticket ?" }, "FILTERS": { "TITLE": "Filtres", @@ -1088,14 +1088,14 @@ "TITLE_ACTION_CHANGE_STATUS": "Changer le statut", "TITLE_ACTION_ASSIGNED_TO": "Affecté à", "EMPTY": { - "TITLE": "Aucun problème rapporté :-)", + "TITLE": "Aucun ticket rapporté :-)", "SUBTITLE": "Avez-vous trouvé un problème ?", - "ACTION_CREATE_ISSUE": "Créer un nouveau problème" + "ACTION_CREATE_ISSUE": "Créer un nouveau ticket" } } }, "ISSUE": { - "PAGE_TITLE": "{{issueSubject}} - Problème {{issueRef}} - {{projectName}}", + "PAGE_TITLE": "{{issueSubject}} - Ticket {{issueRef}} - {{projectName}}", "PAGE_DESCRIPTION": "État : {{issueStatus }}. Type : {{issueType}}, Priorité : {{issuePriority}}. Sévérité : {{issueSeverity}}. Description : {{issueDescription}}" }, "KANBAN": { @@ -1116,9 +1116,9 @@ }, "SEARCH": { "PAGE_TITLE": "Chercher - {{projectName}}", - "PAGE_DESCRIPTION": "Chercher tout, récits utilisateurs, problèmes, tâches ou pages de wiki, dans le projet {{projectName}} : {{projectDescription}}", + "PAGE_DESCRIPTION": "Chercher tout, récits utilisateurs, tickets, tâches ou pages de wiki, dans le projet {{projectName}} : {{projectDescription}}", "FILTER_USER_STORIES": "Récits utilisateur", - "FILTER_ISSUES": "Problèmes", + "FILTER_ISSUES": "Tickets", "FILTER_TASKS": "Tâches", "FILTER_WIKI": "Pages Wiki", "PLACEHOLDER_SEARCH": "Rechercher dans...", @@ -1139,7 +1139,7 @@ "COLUMN_CERVANTES": "Cervantes", "EXPLANATION_COLUMN_CERVANTES": "Page Wiki éditée", "COLUMN_BUG_HUNTER": "Chasseur de bug", - "EXPLANATION_COLUMN_BUG_HUNTER": "Problèmes rapportés", + "EXPLANATION_COLUMN_BUG_HUNTER": "Tickets rapportés", "COLUMN_NIGHT_SHIFT": "Equipe de nuit", "EXPLANATION_COLUMN_NIGHT_SHIFT": "Tâches fermées", "COLUMN_TOTAL_POWER": "Puissance totale", @@ -1191,8 +1191,8 @@ "PLACEHOLDER_BIO": "Dites en nous plus sur vous", "LANGUAGE": "Langue", "LANGUAGE_DEFAULT": "-- utiliser la langue par défaut --", - "THEME": "Theme", - "THEME_DEFAULT": "-- use default theme --" + "THEME": "Thème", + "THEME_DEFAULT": "-- Utiliser la langue par défaut --" } }, "WIZARD": { @@ -1231,12 +1231,12 @@ "HINT3_TITLE": "Triez vos projets pour mettre en avant ceux qui sont les plus pertinants pour vous", "HINT3_TEXT": "Vos 10 principaux projets seront accessibles via la barre du haut", "HINT4_TITLE": "Avez-vous oublié ce sur quoi vous travailliez ?", - "HINT4_TEXT": "Pas d'inquiétude, vous trouverez dans votre tableau de bord vos tâches, problèmes et récits utilisateurs dans l'ordre dans lequel vous avez travaillé dessus." + "HINT4_TEXT": "Pas d'inquiétude, vous trouverez dans votre tableau de bord vos tâches, tickets et récits utilisateurs dans l'ordre dans lequel vous avez travaillé dessus." }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} a téléversé une nouvelle pièce jointe dans {{obj_name}}", "US_CREATED": "{{username}} a créé un nouveau récit utilisateur {{obj_name}} dans {{project_name}}", - "ISSUE_CREATED": "{{username}} a créé un nouveau suivi de problème {{obj_name}} dans {{project_name}}", + "ISSUE_CREATED": "{{username}} a créé un nouveau ticket {{obj_name}} dans {{project_name}}", "TASK_CREATED": "{{username}} a créé une nouvelle Tâche {{obj_name}} dans {{project_name}}", "TASK_CREATED_WITH_US": "{{username}} a créé une nouvelle tâche {{obj_name}} dans le projet {{project_name}} pour le récit utilisateur {{us_name}}", "WIKI_CREATED": "{{username}} a créé une nouvelle page wiki {{obj_name}} dans {{project_name}}", @@ -1244,16 +1244,17 @@ "NEW_PROJECT": "{{username}} a créé le projet {{project_name}}", "MILESTONE_UPDATED": "{{username}} a mis à jour le sprint {{obj_name}}", "US_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du récit utilisateur {{obj_name}}", - "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "ISSUE_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du suivi de problème {{obj_name}}", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", - "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour le récit utilisateur {{obj_name}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "ISSUE_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du ticket {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour le ticket {{obj_name}}", + "TASK_UPDATED": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour la tâche {{obj_name}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour la tâche {{obj_name}}", "TASK_UPDATED_WITH_US": "{{username}} a mis à jour l'attribut «{{field_name}}» de la tâche {{obj_name}} qui appartient au récit utilisateur {{us_name}}", - "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour la tâche {{obj_name}} appartenant au récit utilisateur {{us_name}}", "WIKI_UPDATED": "{{username}} a mis à jour la page wiki {{obj_name}}", "NEW_COMMENT_US": "{{username}} a commenté le récit utilisateur {{obj_name}}", - "NEW_COMMENT_ISSUE": "{{username}} a commenté le suivi de problème {{obj_name}}", + "NEW_COMMENT_ISSUE": "{{username}} a commenté le ticket {{obj_name}}", "NEW_COMMENT_TASK": "{{username}} a commenté la tâche {{obj_name}}", "NEW_MEMBER": "{{project_name}} a un nouveau membre", "US_ADDED_MILESTONE": "{{username}} a ajouté le récit utilisateur {{obj_name}} à {{sprint_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index ff0f70cf..48ebbcb8 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Geef een korte beschrijving", "DEPRECATED": "(verouderd)", "DEPRECATED_FILE": "Verouderd?", - "ADD": "Nieuwe bijlage toevoegen. <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. grootte: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ toon verouderde bijlagen", "HIDE_DEPRECATED": "- verberg verouderde bijlagen", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Rapporten", "SUBTITLE": "Exporteer je project data in CSV formaat en maak je eigen rapporten", - "DESCRIPTION": "Download een CSV bestand of kopieer de gegenereerde URL en open het in je favoriete tekstverwerker of spreadsheet om je eigen project data rapporten aan te maken. Je zal al je data makkelijk kunnen visualiseren en analyseren.", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "Hoe kan ik dit gebruiken in mijn eigen spreadsheet?", "REGENERATE_TITLE": "Wijzig URL", "REGENERATE_SUBTITLE": "Je staat op het punt de CSV data toegang url te veranderen. De vorige url zal worden uitgeschakeld. Ben je zeker dat je ermee door wil gaan?" @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", "US_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de US {{obj_name}} gewijzigd naar {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de issue gewijzigd van {{obj_name}} naar {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 39feb405..8ed69d22 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -343,7 +343,7 @@ "DESCRIPTION": "輸入一段簡短描述", "DEPRECATED": "(被棄用)", "DEPRECATED_FILE": "棄用?", - "ADD": "加入新附件 <%- maxFileSizeMsg %>", + "ADD": "Add new attachment. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. size: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ 顯示棄用的附件", "HIDE_DEPRECATED": "+ 隱藏棄用的附件", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Reports", "SUBTITLE": "以 CSV 格式匯出你的專案資料,並製作你的專屬報告", - "DESCRIPTION": "下載CSV檔案或是複製這個生成的網址到你愛用的文字編輯器或電子表格上製作自己的專案檔案資料報告。你可能輕易地視覺化或分析這些資料。", + "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", "HELP": "使用者故事預設欄位", "REGENERATE_TITLE": "改變網址", "REGENERATE_SUBTITLE": "你將要改變CSV資料的連結網址,之前的網址將失效。你確定要這樣做嗎?" @@ -1245,6 +1245,7 @@ "MILESTONE_UPDATED": "{{username}}更新衝刺任務 {{obj_name}} ", "US_UPDATED": "{{username}} 已更新 {{obj_name}}使用者故事之 \"{{field_name}}\"屬性。", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} 更新了{{obj_name}}問題的 \"{{field_name}}\" 屬性", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", From 6fe996c6a112d74629dfc45778e979e34659b147 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 25 Jul 2015 20:18:46 +0200 Subject: [PATCH 073/403] [i18n] Update and fix locales --- app/locales/locale-ca.json | 2 +- app/locales/locale-de.json | 2 +- app/locales/locale-en.json | 2 +- app/locales/locale-es.json | 6 +++--- app/locales/locale-fi.json | 2 +- app/locales/locale-fr.json | 2 +- app/locales/locale-nl.json | 2 +- app/locales/locale-zh-hant.json | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index 374c2e3d..af143261 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 49290993..20725740 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} aktualisierte den Sprint {{obj_name}}", "US_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der User-Story {{obj_name}} zu {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} aktualisierte das Attribut \"{{field_name}}\" des Tickets {{obj_name}} zu {{new_value}}", "TASK_UPDATED": "{{username}} aktualisierte das Attribut \"{{field_name}}\" der Aufgabe {{obj_name}} zu {{new_value}}", diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index daa387fd..a09bff42 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -1248,7 +1248,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index d31eff16..cad4e01a 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -343,7 +343,7 @@ "DESCRIPTION": "Escribe una pequeña descripción", "DEPRECATED": "(obsoleto)", "DEPRECATED_FILE": "¿Desactualizado?", - "ADD": "Add new attachment. {{maxFileSizeMsg}}", + "ADD": "Agrega nuevos adjunto. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Tamaño Max. : {{maxFileSize}}]", "SHOW_DEPRECATED": "+ muestra adjuntos desactualizados", "HIDE_DEPRECATED": "- ocultar adjuntos obsoletos", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Informes", "SUBTITLE": "Exporta los datos de tu proyecto en formato CSV y crea tus propios informes.", - "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", + "DESCRIPTION": "Descarga el fichero CSV o copia la URL generada y abre tu editor de textos o hoja de cálculo favorito para realizar tus propios informes. Podrás visualizar y analizar todos los datos fácilmente.", "HELP": "¿Cómo puedo usar esto en mi hoja de cálculo?", "REGENERATE_TITLE": "Cambiar URL", "REGENERATE_SUBTITLE": "Vas a cambiar la url de acceso a los datos en formato CSV. La url anterior se deshabilitará. ¿Estás seguro?" @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} ha actualizado el sprint {{obj_name}}", "US_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la historia {{obj_name}} a {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} ha actualizado los puntos de '{{role_name}}' de la historia {{obj_name}} a {{new_value}}", "ISSUE_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la petición {{obj_name}} a {{new_value}}", "TASK_UPDATED": "{{username}} ha actualizado el atributo \"{{field_name}}\" de la tarea {{obj_name}} a {{new_value}}", diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index 1a227df0..973388d7 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index b1efbe28..56624146 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} a mis à jour le sprint {{obj_name}}", "US_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du récit utilisateur {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour le récit utilisateur {{obj_name}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} a mis à jour l'attribut «{{field_name}}» du ticket {{obj_name}}", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour le ticket {{obj_name}}", "TASK_UPDATED": "{{username}} a mis l'attribut \"{{field_name}}\" à {{new_value}} pour la tâche {{obj_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 48ebbcb8..8faa9c17 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", "US_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de US {{obj_name}} gewijzigd naar {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de issue gewijzigd van {{obj_name}} naar {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 8ed69d22..9db6916a 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -1245,7 +1245,7 @@ "MILESTONE_UPDATED": "{{username}}更新衝刺任務 {{obj_name}} ", "US_UPDATED": "{{username}} 已更新 {{obj_name}}使用者故事之 \"{{field_name}}\"屬性。", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated the '{{role_name}}' role of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", "ISSUE_UPDATED": "{{username}} 更新了{{obj_name}}問題的 \"{{field_name}}\" 屬性", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", From 56571168918ee5a5ec7f63b2953be7fa87af688d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 27 Jul 2015 00:38:17 +0200 Subject: [PATCH 074/403] [i18n] Add polish (pl) translation --- CHANGELOG.md | 2 + app/locales/locale-pl.json | 1266 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1268 insertions(+) create mode 100644 app/locales/locale-pl.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 31470c2a..e36f04aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - Add custom videoconference system. - Make burndown chart collapsible at the backlog panel. - Ability to choose a theme (thanks to [@astagi](https://github.com/astagi)) +- i18n. + - Add polish (pl) translation. ### Misc - Improve performance: Show cropped images in timelines. diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json new file mode 100644 index 00000000..32d63f19 --- /dev/null +++ b/app/locales/locale-pl.json @@ -0,0 +1,1266 @@ +{ + "COMMON": { + "YES": "Tak", + "NO": "Nie", + "LOADING": "Ładowanie...", + "LOADING_PROJECT": "Ładowanie projektu...", + "DATE": "DD MMM YYYY", + "DATETIME": "DD MMM YYYY HH:mm", + "SAVE": "Zapisz", + "CANCEL": "Anuluj", + "ACCEPT": "Akceptuj", + "DELETE": "Usuń", + "CREATE": "Stwórz", + "ADD": "Dodaj", + "COPY_TO_CLIPBOARD": "Skopiuj do schowka: Ctrl+C", + "EDIT": "Edycja", + "DRAG": "Przeciągnij", + "TAG_LINE": "Twoje zwinne, wolne, otwarto źródłowe narzędzie do zarządzania projektem", + "TAG_LINE_2": "KOCHAM TWÓJ PROJEKT", + "BLOCK": "Blokuj", + "UNBLOCK": "Odblokuj", + "BLOCKED": "Zablokowane", + "CREATED_BY": "Utworzone przez {{fullDisplayName}}", + "FROM": "od", + "TO": "do", + "CLOSE": "zamknij", + "BLOCKED_NOTE": "Dlaczego ta historyjka użytkownika jest zablokowana?", + "BLOCKED_REASON": "Wyjaśnij powód", + "GO_HOME": "Zabierz mnie do strony domowej", + "PLUGINS": "Wtyczki", + "BETA": "Wersja beta", + "ONE_ITEM_LINE": "Jedna pozycja na wiersz...", + "NEW_BULK": "Nowe zbiorcze dodawanie", + "RELATED_TASKS": "Zadania pokrewne", + "LOGOUT": "Wyloguj", + "EXTERNAL_USER": "zewnętrzny użytkownik", + "GENERIC_ERROR": "Umpa Lumpa mówi {{error}}.", + "IOCAINE_TEXT": "Czujesz się trochę przytłoczony zadaniem? Daj znać innym klikając na ikonę Iokainy podczas edycji zadania. Jest szansa, że staniesz się odporny na tą (fikcyjną ;) ) śmiertelną truciznę biorąc małe dawki. Z pewnością jednak da Ci ona dodatkowego kopa, który pomoże w pokonaniu nowego wyzwania i staniu się lepszym w tym co robisz!", + "FORM_ERRORS": { + "DEFAULT_MESSAGE": "Nieprawidłowa wartość", + "TYPE_EMAIL": "Podaj prawidłowy adres email.", + "TYPE_URL": "Podaj prawidłowy link.", + "TYPE_URLSTRICT": "Tutaj powinien być prawidłowy link.", + "TYPE_NUMBER": "Podaj prawidłową wartość liczbową.", + "TYPE_DIGITS": "Tutaj powinny znajdować się cyfry.", + "TYPE_DATEISO": "Tutaj powinna znajdować się data w formacie (RRRR-MM-DD).", + "TYPE_ALPHANUM": "Tutaj powinna znajdować się wartość alfanumeryczna.", + "TYPE_PHONE": "Wpisz numer telefonu.", + "NOTNULL": "Ta wartość nie powinna być zerowa.", + "NOT_BLANK": "To pole nie powinno zostać puste.", + "REQUIRED": "To pole jest wymagane.", + "REGEXP": "Nieprawidłowa wartość", + "MIN": "Ta wartość powinna być większa lub równa od %s.", + "MAX": "Ta wartość powinna być mniejsza lub równa od %s.", + "RANGE": "Ta wartość powinna mieścić się w przedziale od %s do %s.", + "MIN_LENGTH": "Zbyt mało znaków. Wpisz %s lub więcej znaków.", + "MAX_LENGTH": "Zbyt dużo znaków. Wpisz %s lub mniej znaków.", + "RANGE_LENGTH": "Niewłaściwa ilość znaków. Wpisz pomiędzy %s a %s znaków.", + "MIN_CHECK": "Musisz zaznaczyć przynajmniej %s pozycji.", + "MAX_CHECK": "Musisz zaznaczyć %s pozycji lub mniej.", + "RANGE_CHECK": "Musisz zaznaczyć pomiędzy %s a %s pozycji.", + "EQUAL_TO": "Ta wartość powinna być taka sama." + }, + "PICKERDATE": { + "FORMAT": "DD MMM YYYY", + "IS_RTL": "false", + "FIRST_DAY_OF_WEEK": "1", + "PREV_MONTH": "Poprzedni Miesiąc", + "NEXT_MONTH": "Następny Miesiąc", + "MONTHS": { + "JAN": "Styczeń", + "FEB": "Luty", + "MAR": "Marzec", + "APR": "Kwiecień", + "MAY": "Maj", + "JUN": "Czerwiec", + "JUL": "Lipiec", + "AUG": "Sierpień", + "SEP": "Wrzesień", + "OCT": "Październik", + "NOV": "Listopad", + "DEC": "Grudzień" + }, + "WEEK_DAYS": { + "SUN": "Niedziela", + "MON": "Poniedziałek", + "TUE": "Wtorek", + "WED": "Środa", + "THU": "Czwartek", + "FRI": "Piątek", + "SAT": "Sobota" + }, + "WEEK_DAYS_SHORT": { + "SUN": "Nd", + "MON": "Pon", + "TUE": "Wt", + "WED": "Śr", + "THU": "Czw", + "FRI": "Pt", + "SAT": "Sob" + } + }, + "SEE_USER_PROFILE": "Zobacz profil użytkownika {{username }}", + "USER_STORY": "Historyjka użytkownika", + "TASK": "Zadania", + "ISSUE": "Zgłoszenie", + "TAGS": { + "PLACEHOLDER": "Otaguj mnie!...", + "DELETE": "Usuń tag", + "ADD": "Dodaj tag" + }, + "DESCRIPTION": { + "EMPTY": "Puste miejsce jest takie nudne... opisz, przydaj sensu...", + "NO_DESCRIPTION": "Jeszcze bez opisu" + }, + "FIELDS": { + "SUBJECT": "Temat", + "NAME": "Nazwa", + "URL": "Link", + "DESCRIPTION": "Opis", + "VALUE": "Wartość", + "SLUG": "Slug", + "COLOR": "Kolor", + "IS_CLOSED": "Zamknięte?", + "STATUS": "Status", + "TYPE": "Typ", + "SEVERITY": "Rygor", + "PRIORITY": "Priorytet", + "ASSIGNED_TO": "Przydzielone do", + "POINTS": "Punkty", + "BLOCKED_NOTE": "zablokowana notka", + "IS_BLOCKED": "zablokowana", + "REF": "Ref" + }, + "ROLES": { + "ALL": "Wszystko" + }, + "ASSIGNED_TO": { + "NOT_ASSIGNED": "Nieprzypisane", + "DELETE_ASSIGNMENT": "Usuń przypisanie", + "REMOVE_ASSIGNED": "Ukryj przypisane", + "TOO_MANY": "...zbyt wielu użytkowników, filtruj dalej Umpa Lumpy nie ogarniają", + "CONFIRM_UNASSIGNED": "Jesteś pewny, że chcesz pozostawić nieprzypisane?", + "TITLE_ACTION_EDIT_ASSIGNMENT": "Edytuj przypisanie" + }, + "STATUS": { + "CLOSED": "Zamknięte", + "OPEN": "Otwórz" + }, + "WATCHERS": { + "ADD": "Dodaj obserwatora", + "TITLE": "obserwatory", + "DELETE": "Usuń obserwatora", + "TITLE_LIGHTBOX_DELETE_WARTCHER": "Usuwanie obserwatora..." + }, + "CUSTOM_ATTRIBUTES": { + "CUSTOM_FIELDS": "Własne Pola", + "SAVE": "Zapisz pole niestandardowe", + "EDIT": "Edytuj pole niestandardowe", + "DELETE": "Usuń niestandardowy atrybut", + "CONFIRM_DELETE": "Pamiętaj, że wszystkie wartości w tym polu zostaną usunięte.
Czy kontynuować?" + }, + "FILTERS": { + "TITLE": "filtry", + "INPUT_PLACEHOLDER": "Temat lub odniesienie", + "TITLE_ACTION_FILTER_BUTTON": "szukaj", + "BREADCRUMB_TITLE": "wróć do kategorii", + "BREADCRUMB_FILTERS": "Filtry", + "BREADCRUMB_STATUS": "status" + }, + "WYSIWYG": { + "H1_BUTTON": "Nagłówek pierwszego poziomu", + "H1_SAMPLE_TEXT": "Przykładowy tekst...", + "H2_BUTTON": "Nagłówek drugiego poziomu", + "H2_SAMPLE_TEXT": "Przykładowy tekst...", + "H3_BUTTON": "Nagłówek trzeciego poziomu", + "H3_SAMPLE_TEXT": "Przykładowy tekst...", + "BOLD_BUTTON": "Pogrubienie", + "BOLD_BUTTON_SAMPLE_TEXT": "Przykładowy tekst...", + "ITALIC_BUTTON": "Kursywa", + "ITALIC_SAMPLE_TEXT": "Przykładowy tekst...", + "STRIKE_BUTTON": "Przekreślenie", + "STRIKE_SAMPLE_TEXT": "Przykładowy tekst...", + "BULLETED_LIST_BUTTON": "Lista", + "BULLETED_LIST_SAMPLE_TEXT": "Przykładowy tekst...", + "NUMERIC_LIST_BUTTON": "Lista Numerowana", + "NUMERIC_LIST_SAMPLE_TEXT": "Przykładowy tekst...", + "PICTURE_BUTTON": "Obraz", + "PICTURE_SAMPLE_TEXT": "Tekst alternatywny dla obrazka...", + "LINK_BUTTON": "Link", + "LINK_SAMPLE_TEXT": "Twój tekst do linku...", + "QUOTE_BLOCK_BUTTON": "Cytat", + "QUOTE_BLOCK_SAMPLE_TEXT": "Przykładowy tekst...", + "CODE_BLOCK_BUTTON": "Blok Kodu", + "CODE_BLOCK_SAMPLE_TEXT": "Przykładowy tekst...", + "PREVIEW_BUTTON": "Podgląd", + "EDIT_BUTTON": "Edycja", + "MARKDOWN_HELP": "Składnia Markdown pomoc" + }, + "PERMISIONS_CATEGORIES": { + "SPRINTS": { + "NAME": "Sprinty", + "VIEW_SPRINTS": "Przeglądaj Sprinty", + "ADD_SPRINTS": "Dodawaj sprinty", + "MODIFY_SPRINTS": "Modyfikuj sprinty", + "DELETE_SPRINTS": "Usuwaj sprinty" + }, + "USER_STORIES": { + "NAME": "Historyjki użytkownika", + "VIEW_USER_STORIES": "Przeglądaj historyjki użytkownika", + "ADD_USER_STORIES": "Dodawaj historyjki użytkownika", + "MODIFY_USER_STORIES": "Modyfikuj historyjki użytkownika", + "DELETE_USER_STORIES": "Usuwaj historyjki użytkownika" + }, + "TASKS": { + "NAME": "Zadania", + "VIEW_TASKS": "Przeglądaj zadania", + "ADD_TASKS": "Dodawaj zadania", + "MODIFY_TASKS": "Modyfikuj zadania", + "DELETE_TASKS": "Usuwaj zadania" + }, + "ISSUES": { + "NAME": "Zgłoszenia", + "VIEW_ISSUES": "Przeglądaj zgłoszenia", + "ADD_ISSUES": "Dodawaj zgłoszenia", + "MODIFY_ISSUES": "Modyfikuj zgłoszenia", + "DELETE_ISSUES": "Usuwaj zgłoszenia" + }, + "WIKI": { + "NAME": "Wiki", + "VIEW_WIKI_PAGES": "Przeglądaj strony Wiki", + "ADD_WIKI_PAGES": "Dodawaj strony Wiki", + "MODIFY_WIKI_PAGES": "Modyfikuj strony Wiki", + "DELETE_WIKI_PAGES": "Usuwaj strony Wiki", + "VIEW_WIKI_LINKS": "Przeglądaj linki Wiki", + "ADD_WIKI_LINKS": "Dodawaj linki Wiki", + "DELETE_WIKI_LINKS": "Usuwaj linki Wiki" + } + }, + "META": { + "PAGE_TITLE": "Taiga", + "PAGE_DESCRIPTION": "Taiga to platforma do zarządzania projektami dla startup'ów i zwinnych deweloperów i projektantów, którzy potrzebują prostego,atrakcyjnego wizualnie narzędzia. Taiga sprawia, że praca z projektem staje się przyjemniejsza." + } + }, + "LOGIN": { + "PAGE_TITLE": "Logowanie - Taiga", + "PAGE_DESCRIPTION": "Logowanie do Taiga, platformy do zarządzania projektami dla startup'ów oraz zwinnych developerów i designerów, którzy potrzebują prostego, ładnego narzędzia, które sprawi, że praca stanie się przyjemnością." + }, + "AUTH": { + "INVITED_YOU": "zaprasza cię do dołączenia do projektu", + "NOT_REGISTERED_YET": "Jeszcze nie zarejestrowany?", + "REGISTER": "Zarejestruj", + "CREATE_ACCOUNT": "Tutaj utwórz swoje darmowe konto" + }, + "LOGIN_COMMON": { + "HEADER": "Mam już login do Taigi", + "PLACEHOLDER_AUTH_NAME": "Login albo e-mail (uwzględnij wielkość liter)", + "LINK_FORGOT_PASSWORD": "Zapomniałeś?", + "TITLE_LINK_FORGOT_PASSWORD": "Zapomniałeś hasła?", + "ACTION_ENTER": "Wprowadź", + "ACTION_SIGN_IN": "Zaloguj", + "PLACEHOLDER_AUTH_PASSWORD": "Hasło (uwzględnij wielkość liter)" + }, + "LOGIN_FORM": { + "ERROR_AUTH_INCORRECT": "Nasze Umpa Lumpy twierdzą,że Twój login/e-mail lub hasło nie są poprawne.", + "SUCCESS": "Nasze Umpa Lumpy są szczęśliwe, witaj w Taiga." + }, + "REGISTER": { + "PAGE_TITLE": "Rejestracja - Taiga", + "PAGE_DESCRIPTION": "Załóż własne konto w Taiga, platformie do zarządzania projektami dla startup'ów i zwinnych deweloperów oraz designerów, którzy chcą prostego, pięknego narzędzia sprawiającego, że praca jest przyjemna." + }, + "REGISTER_FORM": { + "TITLE": "Utwórz nowe konto (bezpłatnie)", + "PLACEHOLDER_NAME": "Wybierz nazwę użytkownika (z uwzględnieniem wielkości liter)", + "PLACEHOLDER_FULL_NAME": "Podaj twoje imię i nazwisko", + "PLACEHOLDER_EMAIL": "Twój e-mail", + "PLACEHOLDER_PASSWORD": "Wpisz nowe hasło (z uwzględnieniem wielkości liter)", + "ACTION_SIGN_UP": "Zarejestruj", + "TITLE_LINK_LOGIN": "Zaloguj", + "LINK_LOGIN": "Jesteś już zarejestrowany? Zaloguj się" + }, + "FORGOT_PASSWORD": { + "PAGE_TITLE": "Zapomniałem hasła - Taiga", + "PAGE_DESCRIPTION": "Podaj twoją nazwę użytkownika lub e-mail by zdobyć nowe hasło i odzyskać dostęp do Taiga." + }, + "FORGOT_PASSWORD_FORM": { + "TITLE": "Ups, czy nie zapomniałaś swojego hasła?", + "SUBTITLE": "Podaj twoją nazwę użytkownika lub e-mail by zdobyć nowe", + "PLACEHOLDER_FIELD": "Login albo e-mail", + "ACTION_RESET_PASSWORD": "Resetuj hasło", + "LINK_CANCEL": "Nie, zabierz mnie stąd. Chyba je pamiętam.", + "SUCCESS": "Sprawdź swoją skrzynkę!
Wysłaliśmy Ci wiadomość e-mail z instrukcją jak ustawić nowe hasło", + "ERROR": "NAsze Umpa Lumpy twierdzą, że nie jesteś jeszcze zarejestrowany." + }, + "CHANGE_PASSWORD": { + "PAGE_TITLE": "Zmień hasło - Taiga", + "PAGE_DESCRIPTION": "Ustaw nowe hasło dla swojego konta Taiga. Ej! może byś coś zjadł? To jest dobre dla Twojego mózgu :)", + "SECTION_NAME": "Zmień hasło", + "FIELD_CURRENT_PASSWORD": "Obecne hasło", + "PLACEHOLDER_CURRENT_PASSWORD": "Twoje obecne hasło (lub puste, jeśli jeszcze go nie masz)", + "FIELD_NEW_PASSWORD": "Nowe hasło", + "PLACEHOLDER_NEW_PASSWORD": "Wpisz nowe hasło", + "FIELD_RETYPE_PASSWORD": "Wpisz ponownie nowe hasło", + "PLACEHOLDER_RETYPE_PASSWORD": "Wpisz ponownie nowe hasło", + "ERROR_PASSWORD_MATCH": "Hasło nie jest zgodne" + }, + "CHANGE_PASSWORD_RECOVERY_FORM": { + "TITLE": "Ustaw nowe hasło do Taiga", + "SUBTITLE": "Powinieneś spróbować jeść więcej rzeczy bogatych w żelazo, są dobre dla Twojej pamięci :P", + "PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Token odzyskiwania hasła", + "LINK_NEED_TOKEN": "Potrzebujesz taki?", + "TITLE_LINK_NEED_TOKEN": "Potrzebowałeś tokena, aby odzyskać hasło, bo zapomniałeś jak ono brzmi?", + "PLACEHOLDER_NEW_PASSWORD": "Nowe hasło", + "PLACEHOLDER_RE_TYPE_NEW_PASSWORD": "Wpisz ponownie nowe hasło", + "ACTION_RESET_PASSWORD": "Resetuj hasło", + "SUCCESS": "Nasze Umpa Lumpy zapisały Twoje nowe hasło
Spróbuj zalogować się z jego pomocą." + }, + "INVITATION": { + "PAGE_TITLE": "Akceptowanie zaproszenia - Taiga", + "PAGE_DESCRIPTION": "Zaakceptuj zaproszenie, aby dołączyć do projektu w Taiga, platformie do zarządzania projektami dla startup'ów i zwinnych deweloperów oraz designerów, którzy chcą prostego, pięknego narzędzia sprawiającego, że praca jest przyjemna." + }, + "INVITATION_LOGIN_FORM": { + "NOT_FOUND": "Ups, mamy problem
Nasze Umpa Lumpy nie mogą znaleźć Twojego zaproszenia", + "SUCCESS": "Udało Ci się dołączyć do tego projektu. Witaj w {{project_name}}", + "ERROR": "Według naszych Umpa Lump, nie jesteś jeszcze zarejestrowany. Albo wpisałeś złe hasło." + }, + "HOME": { + "PAGE_TITLE": "Strona główna - Taiga", + "PAGE_DESCRIPTION": "Główna strona Taiga, z Twoimi głównymi projektami i wszystkimi przypisanymi Tobie i obserwowanymi historyjkami użytkownika, zadaniami i zgłoszeniami.", + "EMPTY_WATCHING": "Śledź - Projekty, Historyjki użytkowników, Zadania, Zgłoszenia... o których chcesz wiedzieć :)", + "EMPTY_PROJECT_LIST": "Nie masz jeszcze żadnych projektów", + "WORKING_ON_SECTION": "Pracujesz nad", + "WATCHING_SECTION": "Obserwujesz" + }, + "PROJECTS": { + "PAGE_TITLE": "Moje projekty - Taiga", + "PAGE_DESCRIPTION": "Lista wszystkich Twoich projektów, możesz zmieniać ich kolejność lub tworzyć nowe.", + "MY_PROJECTS": "Moje projekty" + }, + "ATTACHMENT": { + "SECTION_NAME": "załączniki", + "TITLE": "{{ plik }} załadowany dnia {{ data }}", + "DESCRIPTION": "Wpisz krótki opis", + "DEPRECATED": "(przestarzały)", + "DEPRECATED_FILE": "Przestarzałe?", + "ADD": "Dodaj nowy załącznik. {{maxFileSizeMsg}}", + "MAX_FILE_SIZE": "[Maks. rozmiar: {{maxFileSize}}]", + "SHOW_DEPRECATED": "+ pokaż przestarzałe załączniki", + "HIDE_DEPRECATED": "- ukryj przestarzałe załączniki", + "COUNT_DEPRECATED": "({{ counter }} przestarzałych", + "MAX_UPLOAD_SIZE": "Maksymalny rozmiar wysyłania to {{maxFileSize}}", + "DATE": "DD MMM YYYY [at] hh:mm", + "ERROR_UPLOAD_ATTACHMENT": "Nie udało się przesłać pliku '{{fileName}}'. {{errorMessage}}", + "TITLE_LIGHTBOX_DELETE_ATTACHMENT": "Usuń załącznik...", + "MSG_LIGHTBOX_DELETE_ATTACHMENT": "załącznik '{{fileName}}'", + "ERROR_DELETE_ATTACHMENT": "Nie udało się usunąć załącznika w związku z następującym błędem: {{errorMessage}}", + "FIELDS": { + "IS_DEPRECATED": "jest przedawniony" + } + }, + "PAGINATION": { + "PREVIOUS": "Poprzedni", + "NEXT": "Następny" + }, + "ADMIN": { + "COMMON": { + "TITLE_ACTION_EDIT_VALUE": "Edytuj wartość", + "TITLE_ACTION_DELETE_VALUE": "Usuń wartość" + }, + "HELP": "Potrzebujesz pomocy ? Sprawdź naszą stronę wsparcia!", + "PROJECT_DEFAULT_VALUES": { + "TITLE": "Domyślne wartości", + "SUBTITLE": "Ustaw wartości domyślne dla wszystkich pól wyboru." + }, + "MEMBERSHIPS": { + "TITLE": "Zarządzaj członkami", + "PAGE_TITLE": "Członkostwa - {{projectName}}", + "ADD_BUTTON": "+ Nowy członek", + "ADD_BUTTON_TITLE": "Dodaj nowego członka" + }, + "PROJECT_EXPORT": { + "TITLE": "Eksport", + "SUBTITLE": "Wyeksportuj twój projekt aby utworzyć kopię zapasową lub stworzyć nowy bazujący na nim.", + "EXPORT_BUTTON": "Eksport", + "EXPORT_BUTTON_TITLE": "Eksport projektu", + "LOADING_TITLE": "Generujemy plik zrzutu", + "DUMP_READY": "Twój plik zrzutu jest gotowy!", + "LOADING_MESSAGE": "Proszę, nie zamykaj tej strony.", + "ASYNC_MESSAGE": "Wyślemy Ci wiadomość e-mail, kiedy będziemy gotowi.", + "SYNC_MESSAGE": "Jeśli pobieranie nie rozpocznie się automatycznie kliknij tutaj.", + "ERROR": "Umpa Lumpy mają problem z wygenerowaniem zrzutu. Spróbuj ponownie.", + "ERROR_BUSY": "Przepraszam, Umpa Lumpy są teraz bardzo zajęte, spróbuj ponownie za chwilę.", + "ERROR_MESSAGE": "Umpa Lumpy mają następujący problem z wygenerowaniem zrzutu: {{message}}" + }, + "MODULES": { + "TITLE": "Moduły", + "ENABLE": "Włącz", + "DISABLE": "Wyłącz", + "BACKLOG": "Dziennik", + "BACKLOG_DESCRIPTION": "Zarządzaj swoimi historyjkami użytkownika aby utrzymać zorganizowany widok i priorytety zadań", + "KANBAN": "Kanban", + "KANBAN_DESCRIPTION": "Organizuj swój projekt przy użyciu metody lean.", + "ISSUES": "Zgłoszenia", + "ISSUES_DESCRIPTION": "Śledź błędy, pytania i ulepszenia związane z projektem. Nie przegap niczego!", + "WIKI": "Wiki", + "WIKI_DESCRIPTION": "Dodawaj, modyfikuj lub usuwaj dane we współpracy z innymi. To jest właściwe miejsce dla Twojej dokumentacji projektowej.", + "MEETUP": "Spotkaj się", + "MEETUP_DESCRIPTION": "Wybierz system wideokonferencji. Nawet programiści potrzebują kontaktu twarzą w twarz.", + "SELECT_VIDEOCONFERENCE": "Wybierz system do wideokonferencji.", + "SALT_CHAT_ROOM": "Jeśli chcesz możesz dodać salt code do nazwy pokoju chatu.", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Niestandardowy", + "URL_CHAT_ROOM": "Link do chat roomu" + }, + "PROJECT_PROFILE": { + "PAGE_TITLE": "{{sectionName}} - Profil projektu - {{projectName}}", + "PROJECT_DETAILS": "Szczegóły projektu", + "PROJECT_NAME": "Nazwa projektu", + "PROJECT_SLUG": "Szczegóły projektu", + "NUMBER_SPRINTS": "Liczba sprintów", + "NUMBER_US_POINTS": "Ilość punktów historyjek użytkownika", + "TAGS": "Tagi", + "DESCRIPTION": "Opis", + "PUBLIC_PROJECT": "Projekt publiczny", + "PRIVATE_PROJECT": "Projekt prywatny", + "DELETE": "Usuń ten projekt" + }, + "REPORTS": { + "TITLE": "Raporty", + "SUBTITLE": "Wyeksportuj dane projektu w CSV i stwórz swoje własne projekty", + "DESCRIPTION": "Pobierz plik CSV lub skopiuj wygenerowany adres URL i otwórz go w edytorze tekstu lub arkuszu kalkulacyjnym, aby tworzyć własne raporty danych projektu. Będziesz mógł łatwo wizualizować i analizować wszystkie dane.", + "HELP": "Jak mogę tego użyć we własnym arkuszu kalkulacyjnym?", + "REGENERATE_TITLE": "Zmień link", + "REGENERATE_SUBTITLE": "Zamierzasz zmienić link dostępu do danych CSV. Poprzedni link będzie niedostępny. Czy jesteś pewien?" + }, + "CSV": { + "SECTION_TITLE_US": "raporty historii użytkownika", + "SECTION_TITLE_TASK": "Raporty zadań", + "SECTION_TITLE_ISSUE": "raporty zgłoszeń", + "DOWNLOAD": "Ściągnij CSV", + "URL_FIELD_PLACEHOLDER": "Proszę wygeneruj ponownie link do CSV", + "TITLE_REGENERATE_URL": "Wygeneruj ponownie link do CSV", + "ACTION_GENERATE_URL": "Wygeneruj link", + "ACTION_REGENERATE": "Wygeneruj ponownie" + }, + "CUSTOM_FIELDS": { + "TITLE": "Własne Pola", + "SUBTITLE": "Zdefiniuj własne dodatkowe pola dla historyjek użytkownika, zadań i zgłoszeń.", + "US_DESCRIPTION": "Własne pola dla historyjek użytkownika", + "US_ADD": "Dodaj własne pole dla historyjek użytkownika", + "TASK_DESCRIPTION": "Własne pola dla zadań", + "TASK_ADD": "Dodaj Własne pole dla zadań", + "ISSUE_DESCRIPTION": "Własne pola dla zgłoszeń", + "ISSUE_ADD": "Dodaj własne pole dla zgłoszeń", + "FIELD_TYPE_TEXT": "Tekst", + "FIELD_TYPE_MULTI": "Pole wielowierszowe" + }, + "PROJECT_VALUES": { + "PAGE_TITLE": "{{sectionName}} - Wartości projektu - {{projectName}}", + "REPLACEMENT": "Wszystkie wpisy z tą wartością zostaną zmienione na", + "ERROR_DELETE_ALL": "Nie możesz usunąć wszystkich wartości." + }, + "PROJECT_VALUES_POINTS": { + "TITLE": "Punkty", + "SUBTITLE": "Podaj możliwe estymaty dla historyjek użytkownika", + "US_TITLE": "punkty", + "ACTION_ADD": "Dodaj nową wartość" + }, + "PROJECT_VALUES_PRIORITIES": { + "TITLE": "Priorytety", + "SUBTITLE": "Zdefiniuj priorytety dla zgłoszeń", + "ISSUE_TITLE": "Priorytety zgłoszeń", + "ACTION_ADD": "Dodaj nowy priorytet" + }, + "PROJECT_VALUES_SEVERITIES": { + "TITLE": "Rygory", + "SUBTITLE": "Zdefiniuj rygory dla zgłoszeń", + "ISSUE_TITLE": "Rygory zgłoszeń", + "ACTION_ADD": "Dodaj nowy rygor" + }, + "PROJECT_VALUES_STATUS": { + "TITLE": "Status", + "SUBTITLE": "Zdefiniuj statusy dla historyjek użytkownika, zadań i zgłoszeń.", + "US_TITLE": "Statusy", + "TASK_TITLE": "Statusy zadań", + "ISSUE_TITLE": "Statusy zgłoszeń" + }, + "PROJECT_VALUES_TYPES": { + "TITLE": "Typy", + "SUBTITLE": "Zdefiniuj typy zgłoszeń", + "ISSUE_TITLE": "Typy zgłoszeń", + "ACTION_ADD": "Dodaj nowy {{objName}}" + }, + "ROLES": { + "PAGE_TITLE": "Role - {{projectName}}", + "WARNING_NO_ROLE": "Bez przydzielenia ról w projekcie nie ma możliwości oceniania historyjek użytkownika. Umpa Lumpy nie będą wiedziały komu wolno to zrobić :)", + "HELP_ROLE_ENABLED": "Jeśli aktywne użytkownicy pełniący tę rolę będą mogli szacować wartości historyjek", + "COUNT_MEMBERS": "{{ role.members_count }} użytkowników pełniących tę rolę w projekcie", + "TITLE_DELETE_ROLE": "Usuń rolę", + "REPLACEMENT_ROLE": "Wszyscy użytkownicy pełniący tę rolę zostaną przeniesieni do", + "WARNING_DELETE_ROLE": "Ostrożnie, wszystkie estymaty dodane przez ludzi pełniących tę rolę zostaną usunięte", + "ERROR_DELETE_ALL": "Nie możesz usunąć wszystkich wartości", + "EXTERNAL_USER": "Zewnętrzny użytkownik" + }, + "THIRD_PARTIES": { + "SECRET_KEY": "Tajny klucz", + "PAYLOAD_URL": "Payload URL", + "VALID_IPS": "Adresy IP(oddzielone przecinkami)" + }, + "BITBUCKET": { + "SECTION_NAME": "Bitbucket", + "PAGE_TITLE": "Bitbucket - {{projectName}}", + "INFO_VERIFYING_IP": "Zapytania Bitbucket nie są szyfrowane zatem najlepszym sposobem weryfikacji źródła jest sprawdzenie adresu IP.Jeśli pole pozostanie puste sprawdzanie IP nie będzie działać." + }, + "GITLAB": { + "SECTION_NAME": "Gitlab", + "PAGE_TITLE": "Gitlab - {{projectName}}", + "INFO_VERIFYING_IP": "Zapytania Gitlab nie są szyfrowane zatem najlepszym sposobem weryfikacji źródła jest sprawdzenie adresu IP.Jeśli pole pozostanie puste sprawdzanie IP nie będzie działać." + }, + "GITHUB": { + "SECTION_NAME": "Github", + "PAGE_TITLE": "Github - {{projectName}}" + }, + "WEBHOOKS": { + "PAGE_TITLE": "Webhooks - {{projectName}}", + "SECTION_NAME": "Webhooks", + "SUBTITLE": "Webhooks notify external services about events in Taiga, like comments, user stories....", + "ADD_NEW": "Add a New Webhook", + "TYPE_NAME": "Type the service name", + "TYPE_PAYLOAD_URL": "Type the service payload url", + "TYPE_SERVICE_SECRET": "Type the service secret key", + "SAVE": "Save Webhook", + "CANCEL": "Cancel Webhook", + "SHOW_HISTORY": "(Show history)", + "TEST": "Testuj Webhook", + "EDIT": "Zmień Webhook", + "DELETE": "Delete Webhook", + "REQUEST": "Żądanie", + "RESEND_REQUEST": "Resend request", + "HEADERS": "Headers", + "PAYLOAD": "Payload", + "RESPONSE": "Response", + "DATE": "DD MMM YYYY [at] hh:mm", + "ACTION_HIDE_HISTORY": "(Ukryj historię)", + "ACTION_HIDE_HISTORY_TITLE": "Ukryj szczegóły historii", + "ACTION_SHOW_HISTORY": "(Pokaż historię)", + "ACTION_SHOW_HISTORY_TITLE": "Pokaż szczegóły historii", + "WEBHOOK_NAME": "Webhook '{{name}}'" + }, + "CUSTOM_ATTRIBUTES": { + "PAGE_TITLE": "{{sectionName}} - Niestandardowe atrybuty - {{projectName}}", + "ADD": "Dodaj niestandardowe pole", + "EDIT": "Edytuj niestandardowe pole", + "DELETE": "Usuń niestandardowe pole", + "SAVE_TITLE": "Zapisz niestandardowe pole", + "CANCEL_TITLE": "Anuluj tworzenie", + "SET_FIELD_NAME": "podaj nazwę pola", + "SET_FIELD_DESCRIPTION": "podaj opis pola", + "ACTION_UPDATE": "Aktualizuj pole", + "ACTION_CANCEL_EDITION": "Anuluj edycję" + }, + "MEMBERSHIP": { + "COLUMN_MEMBER": "Członek", + "COLUMN_ADMIN": "Admin", + "COLUMN_ROLE": "Rola", + "COLUMN_STATUS": "Status", + "STATUS_ACTIVE": "Aktywny", + "STATUS_PENDING": "Niekatywny", + "DELETE_MEMBER": "Usuń członka", + "SUCCESS_SEND_INVITATION": "Ponownie wysłano zaproszenie do '{{e-mail}}'.", + "ERROR_SEND_INVITATION": "Zaproszenie nie zostało wysłane.", + "SUCCESS_DELETE": "Usunięto {{message}}.", + "ERROR_DELETE": "Nie usunięto {{message}}.", + "DEFAULT_DELETE_MESSAGE": "zaproszenie do {{e-mail}}" + }, + "DEFAULT_VALUES": { + "LABEL_POINTS": "Domyślna wartość dla selektora punktów", + "LABEL_US": "Domyślna wartość dla selektora statusu historyjek użytkownika", + "LABEL_TASK_STATUS": "Domyśla wartość dla selektora statusu zadań", + "LABEL_PRIORITY": "Domyślna wartość dla selektora priorytetu", + "LABEL_SEVERITY": "Domyślna wartość dla selektora rygoru", + "LABEL_ISSUE_TYPE": "Domyślna wartość dla selektora typu zgłoszenia", + "LABEL_ISSUE_STATUS": "Domyślna wartość dla selektora statusu zgłoszenia" + }, + "STATUS": { + "PLACEHOLDER_WRITE_STATUS_NAME": "Wpisz nazwę nowego statusu" + }, + "TYPES": { + "PLACEHOLDER_WRITE_NAME": "Wpisz nazwę nowego elementu" + }, + "US_STATUS": { + "ACTION_ADD_STATUS": "Dodaj nowy status", + "IS_ARCHIVED_COLUMN": "Zarchiwizowana?", + "WIP_LIMIT_COLUMN": "WIP Limit", + "PLACEHOLDER_WRITE_NAME": "Wpisz nazwę nowego statusu" + }, + "MENU": { + "TITLE": "Admin", + "PROJECT": "Projekt", + "ATTRIBUTES": "Atrybuty", + "MEMBERS": "Członkowie", + "PERMISSIONS": "Uprawnienia", + "INTEGRATIONS": "Integracje", + "PLUGINS": "Wtyczki" + }, + "SUBMENU_PROJECT_ATTRIBUTES": { + "TITLE": "Atrybuty" + }, + "SUBMENU_PROJECT_VALUES": { + "STATUS": "Status", + "POINTS": "Punkty", + "PRIORITIES": "Priorytety", + "SEVERITIES": "Rygory", + "TYPES": "Typy", + "CUSTOM_FIELDS": "Niestandardowe pola" + }, + "SUBMENU_PROJECT_PROFILE": { + "TITLE": "Profil projektu" + }, + "SUBMENU_ROLES": { + "TITLE": "Role", + "ACTION_NEW_ROLE": "+ Nowa rola", + "TITLE_ACTION_NEW_ROLE": "Dodaj nową rolę" + }, + "SUBMENU_THIDPARTIES": { + "TITLE": "Rygory" + } + }, + "USER": { + "PROFILE": { + "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", + "EDIT": "Edycja profilu", + "FOLLOW": "Obserwuj", + "PROJECTS": "Projekty", + "CLOSED_US": "Zamknięte historyjki użytkownika", + "CONTACTS": "Kontakty", + "REPORT": "Zgłoś naruszenie", + "ACTIVITY_TAB": "Zakładka Aktywność", + "PROJECTS_TAB": "Zakładka Projekty", + "CONTACTS_TAB": "Zakładka Kontakty", + "FAVORITES_TAB": "Zakładka Ulubione", + "CONTACTS_EMPTY": "{{username}} jeszcze nie ma kontaktów", + "CURRENT_USER_CONTACTS_EMPTY": "Jeszcze nie masz kontaktów", + "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "Ludzie z którymi pracujesz w Taiga staną się Twoimi kontaktami automatycznie.", + "PROJECTS_EMPTY": "{{username}} jeszcze nie uczestniczy w żadnym projekcie" + }, + "PROFILE_SIDEBAR": { + "TITLE": "Twój profil", + "DESCRIPTION": "Użytkownicy mogą zobaczyć wszystko co robisz i nad czym pracujesz. Dodaj jakieś ładne info o sobie, żeby dać im się poznać.", + "ADD_INFO": "Edytuj info o sobie" + } + }, + "PROJECT": { + "PAGE_TITLE": "{{projectName}}", + "WELCOME": "Witamy", + "SECTION_PROJECTS": "Projekty", + "HELP": "Ustal kolejność Twoich projektów tak, aby na górze znalazły się te najważniejsze.
Pierwsze 10 projektów pojawi się w liście projektów na górnym pasku nawigacji.", + "PRIVATE": "Projekt prywatny", + "STATS": { + "PROJECT": "projekt
punkty", + "DEFINED": "zdefiniowane
punkty", + "ASSIGNED": "przypisane
punkty", + "CLOSED": "zamknięte
punkty" + }, + "SECTION": { + "SEARCH": "Szukaj", + "TIMELINE": "Oś czasu", + "BACKLOG": "Dziennik", + "KANBAN": "Kanban", + "ISSUES": "Zgłoszenia", + "WIKI": "Wiki", + "TEAM": "Zespół", + "MEETUP": "Spotkaj się", + "ADMIN": "Admin" + }, + "NAVIGATION": { + "SECTION_TITLE": "Twoje projekty", + "PLACEHOLDER_SEARCH": "Szukaj w ...", + "ACTION_CREATE_PROJECT": "Stwórz projekt", + "ACTION_IMPORT_PROJECT": "Importuj projekt", + "SEE_MORE_PROJECTS": "Zobacz więcej projektów", + "TITLE_CREATE_PROJECT": "Utwórz projekt", + "TITLE_IMPORT_PROJECT": "Importuj projekt", + "TITLE_PRVIOUS_PROJECT": "Pokaż poprzedni projekt", + "TITLE_NEXT_PROJECT": "Pokaż kolejne projekty", + "HELP_TITLE": "Taiga strona wsparcia", + "HELP": "Pomoc", + "FEEDBACK_TITLE": "Prześlij opinię", + "FEEDBACK": "Feedback", + "NOTIFICATIONS_TITLE": "Edytuj ustawienia powiadomień", + "NOTIFICATIONS": "Powiadomienia", + "ORGANIZATIONS_TITLE": "Edytuj organizacje", + "ORGANIZATIONS": "Edytuj organizacje", + "SETTINGS_TITLE": "Edytuj ustawienia", + "SETTINGS": "Ustawienia", + "VIEW_PROFILE_TITLE": "Zobacz profil", + "VIEW_PROFILE": "Zobacz profil", + "EDIT_PROFILE_TITLE": "Edytuj profil", + "EDIT_PROFILE": "Edytuj profil", + "CHANGE_PASSWORD_TITLE": "Zmień hasło", + "CHANGE_PASSWORD": "Zmień hasło", + "DASHBOARD_TITLE": "Dashboard", + "DISCOVER_TITLE": "Odkryj projekty", + "DISCOVER": "Odkryj", + "ACTION_REORDER": "Przeciągnij i upuść żeby zmienić kolejność" + }, + "IMPORT": { + "TITLE": "Importowanie Projektu", + "UPLOADING_FILE": "Umpa Lumpy ładują plik zrzutu", + "DESCRIPTION": "Proces może zająć chwilkę, proszę nie zamykaj okna.", + "ASYNC_IN_PROGRESS_TITLE": "Umpa Lumpy importują projekt", + "ASYNC_IN_PROGRESS_MESSAGE": "To może zając kilka minut.
Otrzymasz mail gdy wszystko będzie gotowe.", + "UPLOAD_IN_PROGRESS_MESSAGE": "Wysłano {{uploadedSize}} z {{totalSize}}", + "ERROR": "Umpa Lumpy mają problem z importem. Spróbuj ponownie.", + "ERROR_TOO_MANY_REQUEST": "Umpa Lumpy są teraz zajęte a serwer ma zadyszkę. Spróbuj ponownie za chwilę.", + "ERROR_MESSAGE": "Przy imporcie wystąpił następujący problem: {{error_message}}", + "ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) plik jest za ciężki, maksymalna wartość to: ({{maxFileSize}})", + "SYNC_SUCCESS": "Twój projekt zaimportował się prawidłowo!" + } + }, + "LIGHTBOX": { + "DELETE_ACCOUNT": { + "SECTION_NAME": "Usuń konto z Taiga", + "CONFIRM": "Czy na pewno chcesz usunąć swoje konto z Taiga?", + "SUBTITLE": "Będziemy tęsknić! :(", + "NEWSLETTER_LABEL_TEXT": "Nie chcę więcej otrzymywać waszego newslettera" + }, + "DELETE_PROJECT": { + "TITLE": "Usuń projekt", + "QUESTION": "Czy masz pewność, że chcesz skasować ten projekt?", + "SUBTITLE": "Wszystkie dane projektu będą stracone! :(", + "CONFIRM": "Tak, jestem pewny" + }, + "ASSIGNED_TO": { + "SELECT": "Wybierz przypisane do", + "SEARCH": "Szukaj użytkowników" + }, + "ADD_MEMBER": { + "TITLE": "Nowy Członek", + "HELP_TEXT": "Jeżeli użytkownik jest już zarejestrowany w Taiga, będzie dodany automatycznie. W przeciwnym wypadku otrzyma zaproszenie." + }, + "CREATE_ISSUE": { + "TITLE": "Dodaj Zagadnienie" + }, + "FEEDBACK": { + "TITLE": "Powiedz nam coś...", + "COMMENT": "...błędy, sugestie, fajne propozycje..., nawet najgorsze koszmary z Taigi.", + "ACTION_SEND": "Prześlij opinię" + }, + "SEARCH": { + "TITLE": "Szukaj", + "PLACEHOLDER_SEARCH": "Czego szukasz?" + }, + "ADD_EDIT_SPRINT": { + "TITLE": "Nowy sprint", + "PLACEHOLDER_SPRINT_NAME": "Nazwa sprintu", + "PLACEHOLDER_SPRINT_START": "Oszacowany Początek", + "PLACEHOLDER_SPRINT_END": "Oszacowane Zakończenie", + "ACTION_DELETE_SPRINT": "Chcesz usunąć sprint?", + "TITLE_ACTION_DELETE_SPRINT": "usuń sprint", + "LAST_SPRINT_NAME": "ostatni sprint to: {{lastSprint}} ;-) " + }, + "CREATE_EDIT_TASK": { + "TITLE": "Nowe zadanie", + "PLACEHOLDER_SUBJECT": "Temat zadania", + "PLACEHOLDER_STATUS": "Status zadania", + "OPTION_UNASSIGNED": "Nieprzypisane", + "PLACEHOLDER_SHORT_DESCRIPTION": "Wpisz krótki opis", + "ACTION_EDIT": "Zmień zadanie" + }, + "CREATE_EDIT_US": { + "TITLE": "Nowa historyjka użytkownika", + "PLACEHOLDER_DESCRIPTION": "Dodaj proszę treściwy opis, który pomoże innym zrozumieć tę historyjkę", + "NEW_US": "Nowa historyjka użytkownika", + "EDIT_US": "Zmień historyjkę użytkownika" + }, + "DELETE_SPRINT": { + "TITLE": "Usuń sprint" + }, + "CREATE_MEMBER": { + "PLACEHOLDER_INVITATION_TEXT": "(Opcjonalne) Dodaj spersonalizowany tekst do zaproszenia. Napisz coś słodziachnego do nowego członka zespołu :)", + "PLACEHOLDER_TYPE_EMAIL": "Wpisz Email" + } + }, + "US": { + "PAGE_TITLE": "{{userStorySubject}} - Historyjka użytkownika {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Zakończono {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} z {{userStoryTotalTasks}} zadań). Punktów: {{userStoryPoints}}. Opis: {{userStoryDescription}}", + "SECTION_NAME": "Szczegóły historyjki użytkownika", + "LINK_TASKBOARD": "Tablica zadań", + "TITLE_LINK_TASKBOARD": "Idź do listy zadań", + "TOTAL_POINTS": "razem", + "ADD": "+ Dodaj nową historyjkę użytkownika", + "ADD_BULK": "Masowo dodaj nowe historyjki użytkownika", + "PROMOTED": "Ta historyjka awansowała ze zgłoszenia:", + "TITLE_LINK_GO_TO_ISSUE": "Idź do zgłoszenia", + "EXTERNAL_REFERENCE": "Ta historyjka została utworzona z", + "GO_TO_EXTERNAL_REFERENCE": "Idź do źródła", + "BLOCKED": "Ta historia użytkownika jest zablokowana", + "PREVIOUS": "poprzednia historia użytkownika", + "NEXT": "następna historia użytkownika", + "TITLE_DELETE_ACTION": "Usuń historyjkę użytkownika", + "LIGHTBOX_TITLE_BLOKING_US": "Blokuje nas", + "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} zadanie zakończone", + "ASSIGN": "Przypisz historyjkę użytkownika", + "NOT_ESTIMATED": "Nie oszacowane", + "TOTAL_US_POINTS": "Łącznie punktów", + "FIELDS": { + "TEAM_REQUIREMENT": "Wymaganie zespołu", + "CLIENT_REQUIREMENT": "Wymaganie klienta", + "FINISH_DATE": "Data zakończenia" + } + }, + "COMMENTS": { + "DELETED_INFO": "Komentarz usunięty przez {{user}} w dniu {{date}}", + "TITLE": "Komentarze", + "COMMENT": "Komentarz", + "TYPE_NEW_COMMENT": "Tutaj wpisz nowy komentarz", + "SHOW_DELETED": "Pokaż usunięty komentarz", + "HIDE_DELETED": "Ukryj skasowane komentarze", + "RESTORE": "Przywróć komentarz" + }, + "ACTIVITY": { + "SHOW_ACTIVITY": "Pokaż aktywność", + "DATETIME": "DD MMM YYYY HH:mm", + "SHOW_MORE": "+ Pokaż poprzednie wpisy ({{showMore}} więcej)", + "TITLE": "Aktywność", + "REMOVED": "usunięty", + "ADDED": "dodany", + "US_POINTS": "Punkty HU ({{name}})", + "NEW_ATTACHMENT": "nowy załącznik", + "DELETED_ATTACHMENT": "Usunięty załącznik", + "UPDATED_ATTACHMENT": "Zaktualizowany załącznik {{filename}}", + "DELETED_CUSTOM_ATTRIBUTE": "Usunięty niestandardowy atrybut", + "SIZE_CHANGE": "Dokonano {size, plural, one{one change} other{# changes}}", + "VALUES": { + "YES": "tak", + "NO": "nie", + "EMPTY": "pusty", + "UNASSIGNED": "nieprzypisany" + }, + "FIELDS": { + "SUBJECT": "temat", + "NAME": "imię", + "DESCRIPTION": "opis", + "CONTENT": "treść", + "STATUS": "status", + "IS_CLOSED": "zamknięty", + "FINISH_DATE": "data zakończenia", + "TYPE": "typ", + "PRIORITY": "priorytet", + "SEVERITY": "rygor", + "ASSIGNED_TO": "przypisane do", + "WATCHERS": "obserwatorzy", + "MILESTONE": "sprint", + "USER_STORY": "historyjka użytkownika", + "PROJECT": "projekt", + "IS_BLOCKED": "zablokowany", + "BLOCKED_NOTE": "notka blokady", + "POINTS": "punkty", + "CLIENT_REQUIREMENT": "wymaganie klienta", + "TEAM_REQUIREMENT": "wymaganie zespołu", + "IS_IOCAINE": "Iokaina", + "TAGS": "tagi", + "ATTACHMENTS": "załączniki", + "IS_DEPRECATED": "jest przedawniony", + "ORDER": "kolejność", + "BACKLOG_ORDER": "kolejność backlogu", + "SPRINT_ORDER": "kolejność sprintów", + "KANBAN_ORDER": "kolejność kanban", + "TASKBOARD_ORDER": "kolejność tablicy zadań", + "US_ORDER": "Kolejność HU" + } + }, + "BACKLOG": { + "PAGE_TITLE": "Backlog - {{projectName}}", + "PAGE_DESCRIPTION": "Panel backlogu zawierający historyjki użytkownika i sprinty {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Dziennik", + "MOVE_US_TO_CURRENT_SPRINT": "Przejdź do bieżącego sprintu", + "SHOW_FILTERS": "Pokaż filtry", + "SHOW_TAGS": "Pokaż tagi", + "EMPTY": "Nie masz zaległości", + "CREATE_NEW_US": "Utwórz nową HU", + "CREATE_NEW_US_EMPTY_HELP": "Możesz utworzyć nową historyjkę użytkownika", + "EXCESS_OF_POINTS": "Nadwyżka punktów", + "PENDING_POINTS": "Oczekujące punkty", + "CLOSED_POINTS": "zamknięte", + "COMPACT_SPRINT": "Kompaktuj sprint", + "GO_TO_TASKBOARD": "Idź do tablicy zadań{{::name}}", + "EDIT_SPRINT": "Edytuj sprint", + "TOTAL_POINTS": "razem", + "STATUS_NAME": "Nazwa statusu", + "SORTABLE_FILTER_ERROR": "Nie możesz przenosić do backlogu kiedy filtry są otwarte", + "DOOMLINE": "Zakres projektu [Doomline]", + "CHART": { + "XAXIS_LABEL": "Sprinty", + "YAXIS_LABEL": "Punkty", + "OPTIMAL": "Optymalna ilość puntów oczekujących w sprincie {{sprintName}} to {{value}}", + "REAL": "Faktyczna ilość punktów oczekujących w sprincie {{sprintName}} to {{value}}", + "INCREMENT_TEAM": "Punkty dodane na podstawie wymagań zespołu w sprincie {{sprintName}} to {{value}}", + "INCREMENT_CLIENT": "Punkty dodane na podstawie wymagań klienta w sprincie {{sprintName}} to {{value}}" + }, + "TAGS": { + "TOGGLE": "Przełącz widoczność tagów", + "SHOW": "Pokaż tagi", + "HIDE": "Ukryj tagi" + }, + "TABLE": { + "COLUMN_US": "Historyjki użytkownika", + "TITLE_COLUMN_POINTS": "Widok według ról" + }, + "SPRINT_SUMMARY": { + "TOTAL_POINTS": "łącznie
punktów", + "COMPLETED_POINTS": "wypalonych
punktów", + "OPEN_TASKS": "otwartych
zadań", + "CLOSED_TASKS": "zamkniętych
zadań", + "IOCAINE_DOSES": "dawek
Iokainy", + "SHOW_STATISTICS_TITLE": "Pokaż statystyki", + "TOGGLE_BAKLOG_GRAPH": "Pokaż/Ukryj wykres spalania" + }, + "SUMMARY": { + "PROJECT_POINTS": "punktów w
projekcie", + "DEFINED_POINTS": "zdefiniowanych
punktów", + "CLOSED_POINTS": "zamkniętych
punktów", + "POINTS_PER_SPRINT": "punktów na /
sprint" + }, + "FILTERS": { + "TOGGLE": "Przełącz widoczność filtrów", + "TITLE": "Filtry", + "REMOVE": "Usuń filtry", + "HIDE": "Ukryj filtry", + "SHOW": "Pokaż filtry", + "FILTER_CATEGORY_STATUS": "Status", + "FILTER_CATEGORY_TAGS": "Tagi" + }, + "SPRINTS": { + "TITLE": "SPRINTY", + "DATE": "DD MMM YYYY", + "LINK_TASKBOARD": "Tablica zadań sprintu", + "TITLE_LINK_TASKBOARD": "Idź do tablicy zadań użytkownika {{name}}", + "NUMBER_SPRINTS": "
sprintów", + "TITLE_ACTION_NEW_SPRINT": "+ Nowy sprint", + "ACTION_NEW_SPRINT": "+ Nowy sprint", + "ACTION_SHOW_CLOSED_SPRINTS": "Pokaż zamknięte sprinty", + "ACTION_HIDE_CLOSED_SPRINTS": "Ukryj zamknięte sprinty" + } + }, + "ERROR": { + "TEXT1": "Wystąpił błąd, nasze Umpa Lumpy będą pracować nad jego rozwiązaniem.", + "TEXT2": "Spróbuj przeładować za chwilę ponownie.", + "NOT_FOUND": "Nie znaleziono", + "NOT_FOUND_TEXT": "Błąd 404 - strona której szukasz nie istnieje. Wróć do strony głównej Taiga i zobacz, czy znajdziesz tam to, czego szukasz.", + "PERMISSION_DENIED": "Dostęp zabroniony", + "PERMISSION_DENIED_CODE": "Błąd 403.", + "VERSION_ERROR": "Odśwież i zastosuj zmiany ponownie gdyż może ktoś przed Tobą zapisał jakieś zmiany." + }, + "TASKBOARD": { + "PAGE_TITLE": "{{sprintName}} - Lista zadań sprintu - {{projectName}}", + "PAGE_DESCRIPTION": "Sprint {{sprintName}} (od {{startDate}} do {{endDate}}) z {{projectName}}. Ukończono {{completedPercentage}}% ({{completedPoints}} z {{totalPoints}} punktów). {{openTasks}} otwartych zadań z {{totalTasks}}.", + "SECTION_NAME": "Tablica zadań", + "TITLE_ACTION_ADD": "Dodaj nowe zadanie", + "TITLE_ACTION_ADD_BULK": "Dodaj nowe zadania zbiorczo", + "TITLE_ACTION_ASSIGN": "Przydziel zadanie", + "TITLE_ACTION_EDIT": "Zmień zadanie", + "TABLE": { + "COLUMN": "Historyjka użytkownika", + "TITLE_ACTION_FOLD": "Zwiń kolumnę", + "TITLE_ACTION_UNFOLD": "Rozwiń kolumnę", + "TITLE_ACTION_FOLD_ROW": "Zwiń wiersz", + "TITLE_ACTION_UNFOLD_ROW": "Rozwiń wiersz", + "FIELD_POINTS": "punkty", + "ROW_UNASSIGED_TASKS_TITLE": "Nieprzypisane zadania" + }, + "CHARTS": { + "XAXIS_LABEL": "Dni", + "YAXIS_LABEL": "Punkty", + "OPTIMAL": "Optymalna ilość oczekujących punktów na dzień {{formattedDate}} to {{roundedValue}}", + "REAL": "Faktyczna ilość punktów oczekujących na dzień {{formattedDate}} to {{roundedValue}}", + "DATE": "DD MMMM YYYY" + } + }, + "TASK": { + "PAGE_TITLE": "{{taskSubject}} - Zadanie {{taskRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Status: {{taskStatus }}. Opis: {{taskDescription}}", + "SECTION_NAME": "Szczegóły zadania", + "LINK_TASKBOARD": "Tablica zadań", + "TITLE_LINK_TASKBOARD": "Idź do listy zadań", + "PLACEHOLDER_SUBJECT": "Wpisz temat zadania", + "TITLE_SELECT_STATUS": "SNazwa statusu", + "OWNER_US": "To zadanie należy do", + "TITLE_LINK_GO_OWNER": "Idź do historyjki użytkownika", + "ORIGIN_US": "Źródło tego zadania to", + "TITLE_LINK_GO_ORIGIN": "Idź do historyjki użytkownika", + "BLOCKED": "To zadanie jest zablokowane", + "PREVIOUS": "poprzednie zadanie", + "NEXT": "następne zadanie", + "TITLE_DELETE_ACTION": "Usuń zadanie", + "LIGHTBOX_TITLE_BLOKING_TASK": "Blokowanie zadania", + "FIELDS": { + "MILESTONE": "Sprint", + "USER_STORY": "Historyjka użytkownika", + "IS_IOCAINE": "Iocaina" + }, + "ACTION_IOCAINE": "Iocaina", + "TITLE_ACTION_IOCAINE": "Czujesz się trochę przytłoczony zadaniem? Daj znać innym klikając na ikonę Iokainy podczas edycji zadania. Jest szansa, że staniesz się odporny na tą (fikcyjną ;) ) śmiertelną truciznę biorąc małe dawki. Z pewnością jednak da Ci ona dodatkowego kopa, który pomoże w pokonaniu nowego wyzwania i staniu się lepszym w tym co robisz!" + }, + "NOTIFICATION": { + "OK": "Wszystko ok", + "WARNING": "Ups, coś się stało...", + "WARNING_TEXT": "Twoje zmiany nie zostały zapisane z powodu błędu!", + "SAVED": "Wszystkie zmiany zapisane!", + "CLOSE": "Zamknij powiadomienie", + "MAIL": "Powiadomienia na e-mail", + "ASK_DELETE": "Czy na pewno chcesz usunąć?" + }, + "CANCEL_ACCOUNT": { + "TITLE": "Unieważnij swoje konto", + "SUBTITLE": "Przykro nam, że opuszczasz Taiga. Mamy nadzieję, że było miło :)", + "PLACEHOLDER_INPUT_TOKEN": "unieważnij token konta", + "ACTION_LEAVING": "Tak, odchodzę!", + "SUCCESS": "Nasze Umpa Lumpy usunęły twoje konto" + }, + "CHANGE_EMAIL_FORM": { + "TITLE": "Zmień swój e-mail", + "SUBTITLE": "Jeszcze tylko jeden klik i twój email będzie zaktualizowany!", + "PLACEHOLDER_INPUT_TOKEN": "zmień token e-maila", + "ACTION_CHANGE_EMAIL": "Zmień e-mail", + "SUCCESS": "Nasze Umpa Lumpy zaktualizowały Twój e-mail" + }, + "ISSUES": { + "PAGE_TITLE": "Zgłoszenia - {{projectName}}", + "PAGE_DESCRIPTION": "Lista zgłoszeń w projekcie {{projectName}}: {{projectDescription}}", + "LIST_SECTION_NAME": "Zgłoszenia", + "SECTION_NAME": "Szczegóły zgłoszenia", + "ACTION_NEW_ISSUE": "+ NOWE ZGŁOSZENIE", + "ACTION_PROMOTE_TO_US": "Awansuj na historyjkę użytkownika", + "PLACEHOLDER_FILTER_NAME": "Wpisz nazwę filtru i kliknij enter", + "PROMOTED": "To zgłoszenie zostało wypromowane na HU:", + "EXTERNAL_REFERENCE": "Źródło zgłoszenia", + "GO_TO_EXTERNAL_REFERENCE": "Idź do źródła", + "BLOCKED": "To zgłoszenie jest zablokowane", + "TITLE_PREVIOUS_ISSUE": "poprzednie zgłoszenie", + "TITLE_NEXT_ISSUE": "następne zgłoszenie", + "ACTION_DELETE": "Usuń zgłoszenie", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Blokowanie zgłoszenia", + "FIELDS": { + "PRIORITY": "Priorytet", + "SEVERITY": "Rygor", + "TYPE": "Typ" + }, + "CONFIRM_PROMOTE": { + "TITLE": "Awansuj to zgłoszenie na historyjkę użytkownika", + "MESSAGE": "Jesteś pewny, że chcesz wypromować to zgłoszenie na historyjkę użytkownika?" + }, + "FILTERS": { + "TITLE": "Filtry", + "INPUT_SEARCH_PLACEHOLDER": "Temat lub referencja", + "TITLE_ACTION_SEARCH": "Szukaj", + "ACTION_SAVE_CUSTOM_FILTER": "zapisz jako filtr niestandardowy", + "BREADCRUMB": "Filtry", + "TITLE_BREADCRUMB": "Filtry", + "CATEGORIES": { + "TYPE": "Typy", + "STATUS": "Statusy", + "SEVERITY": "Rygory", + "PRIORITIES": "Priorytety", + "TAGS": "Tagi", + "ASSIGNED_TO": "Przypisane do", + "CREATED_BY": "Stworzona przez", + "CUSTOM_FILTERS": "Filtry niestandardowe" + }, + "CONFIRM_DELETE": { + "TITLE": "Usuń filtr niestandardowy", + "MESSAGE": "filtr niestandardowy '{{customFilterName}}'" + } + }, + "TABLE": { + "COLUMNS": { + "TYPE": "Typ", + "SEVERITY": "Rygor", + "PRIORITY": "Priorytet", + "SUBJECT": "Temat", + "STATUS": "Status", + "CREATED": "Utworzone", + "ASSIGNED_TO": "Przypisane do" + }, + "TITLE_ACTION_CHANGE_STATUS": "Zmień status", + "TITLE_ACTION_ASSIGNED_TO": "Przypisane do", + "EMPTY": { + "TITLE": "Brak zgłoszeń :-)", + "SUBTITLE": "MAsz zgłoszenie?", + "ACTION_CREATE_ISSUE": "Utwórz nowe zgłoszenie" + } + } + }, + "ISSUE": { + "PAGE_TITLE": "{{issueSubject}} - Zgłoszenie {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priorytet: {{issuePriority}}. Rygor: {{issueSeverity}}. Opis: {{issueDescription}}" + }, + "KANBAN": { + "PAGE_TITLE": "Kanban - {{projectName}}", + "PAGE_DESCRIPTION": "Panel kanban zawierający historyjki użytkownika wchodzące w skład projektu {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Kanaban", + "TITLE_ACTION_FOLD": "Zwiń kolumnę", + "TITLE_ACTION_UNFOLD": "Rozwiń kolumnę", + "TITLE_ACTION_FOLD_CARDS": "Zwiń karty", + "TITLE_ACTION_UNFOLD_CARDS": "Rozwiń karty", + "TITLE_ACTION_ADD_US": "Dodaj nową HU", + "TITLE_ACTION_ADD_BULK": "Dodaj zbiorczo HU", + "ACTION_SHOW_ARCHIVED": "Pokaż archiwalne", + "ACTION_HIDE_ARCHIVED": "Ukryj archiwalne", + "HIDDEN_USER_STORIES": "Historyjki użytkownika o tym statusie są domyślnie ukryte", + "ARCHIVED": "Zarchiwizowano", + "UNDO_ARCHIVED": "Przeciągnij i upuść ponownie aby cofnąć" + }, + "SEARCH": { + "PAGE_TITLE": "Szukaj - {{projectName}}", + "PAGE_DESCRIPTION": "Możesz przeszukiwać wszystko, historyjki użytkownika, zgłoszenia, zadania oraz strony Wiki w projekcie {{projectName}}: {{projectDescription}}", + "FILTER_USER_STORIES": "Historyjki użytkownika", + "FILTER_ISSUES": "Zgłoszenia", + "FILTER_TASKS": "Zadania", + "FILTER_WIKI": "Strony Wiki", + "PLACEHOLDER_SEARCH": "Szukaj w ...", + "TITLE_ACTION_SEARCH": "szukaj", + "EMPTY_TITLE": "Nie znaleziono niczego, co spełniałoby podane kryteria.", + "EMPTY_DESCRIPTION": "Spróbuj użyć zakładek powyżej przy ponownym wyszukiwaniu" + }, + "TEAM": { + "PAGE_TITLE": "Zespół - {{projectName}}", + "PAGE_DESCRIPTION": "Panel zespołu w którym zebrani są wszyscy jego członkowie pracujący przy projekcie {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Zespół", + "APP_TITLE": "ZESPÓŁ - {{projectName}}", + "PLACEHOLDER_INPUT_SEARCH": "Szukaj po imieniu...", + "COLUMN_MR_WOLF": "Mr. Wolf", + "EXPLANATION_COLUMN_MR_WOLF": "Zamknięte zgłoszenia", + "COLUMN_IOCAINE": "Iokainista", + "EXPLANATION_COLUMN_IOCAINE": "Spożyte dawki", + "COLUMN_CERVANTES": "Cervantes", + "EXPLANATION_COLUMN_CERVANTES": "Edytowane strony Wiki", + "COLUMN_BUG_HUNTER": "Łowca Bugów", + "EXPLANATION_COLUMN_BUG_HUNTER": "Zgłoszone zadania", + "COLUMN_NIGHT_SHIFT": "Niezłomny", + "EXPLANATION_COLUMN_NIGHT_SHIFT": "Zamknięte zadania", + "COLUMN_TOTAL_POWER": "Ogólna potęga", + "EXPLANATION_COLUMN_TOTAL_POWER": "Punktów łącznie", + "SECTION_TITLE_TEAM": "Zespół >", + "SECTION_FILTER_ALL": "Wszystko", + "CONFIRM_LEAVE_PROJECT": "Na pewno chcesz opuścić projekt?", + "ACTION_LEAVE_PROJECT": "Opuść projekt" + }, + "USER_SETTINGS": { + "AVATAR_MAX_SIZE": "[Maks. rozmiar: {{maxFileSize}}]", + "MENU": { + "SECTION_TITLE": "Ustawienia użytkownika", + "USER_PROFILE": "Profil użytkownika", + "CHANGE_PASSWORD": "Zmień hasło", + "EMAIL_NOTIFICATIONS": "Powiadomienia e-mail" + }, + "NOTIFICATIONS": { + "SECTION_NAME": "Powiadomienia przez e-mail", + "COLUMN_PROJECT": "Projekt", + "COLUMN_RECEIVE_ALL": "Otrzymuj wszystkie", + "COLUMN_ONLY_INVOLVED": "Tylko te, w których bierzesz udział", + "COLUMN_NO_NOTIFICATIONS": "Nie otrzymuj żadnych", + "OPTION_ALL": "Wszystkie", + "OPTION_INVOLVED": "Z moim udziałem", + "OPTION_NONE": "Żadne" + }, + "POPOVER": { + "USER_PROFILE": "Profil użytkownika", + "CHANGE_PASSWORD": "Zmień hasło", + "NOTIFICATIONS": "Powiadomienia", + "FEEDBACK": "Feedback", + "TITLE_AVATAR": "Preferencje użytkownika" + } + }, + "USER_PROFILE": { + "IMAGE_HELP": "Obraz zostanie przeskalowany do wielkości 80x80px.
", + "ACTION_CHANGE_IMAGE": "Zmień", + "ACTION_USE_GRAVATAR": "Użyj Gravatara", + "ACTION_DELETE_ACCOUNT": "Usuń konto Taiga", + "CHANGE_EMAIL_SUCCESS": "Sprawdź swoją skrzynkę e-mail!
Wysłaliśmy wiadomość z instrukcjami.", + "CHANGE_PHOTO": "Zmień zdjęcie", + "FIELD": { + "USERNAME": "Nazwa użytkownika", + "EMAIL": "Email", + "FULL_NAME": "Imię i nazwisko", + "PLACEHOLDER_FULL_NAME": "Podaj swoje imię i nazwisko", + "BIO": "Bio (max. 210 znaków)", + "PLACEHOLDER_BIO": "Powiedz coś o sobie", + "LANGUAGE": "Język", + "LANGUAGE_DEFAULT": "-- używaj domyślnego języka --", + "THEME": "Szablon strony", + "THEME_DEFAULT": "-- używaj domyślnego szablonu --" + } + }, + "WIZARD": { + "SECTION_TITLE_CHOOSE_TEMPLATE": "Wybierz szablon", + "CHOOSE_TEMPLATE_TEXT": "Który szablon lepiej pasuje do Twojego projektu?", + "SECTION_TITLE_CREATE_PROJECT": "Utwórz projekt", + "CREATE_PROJECT_TEXT": "Nowy, zwinny! To takie ekscytujące!", + "PROGRESS_TEMPLATE_SELECTION": "Wybór szablonu", + "PROGRESS_NAME_DESCRIPTION": "Nazwa i opis" + }, + "WIKI": { + "PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}", + "PAGE_DESCRIPTION": "Ostatnio edytowane dnia {{lastModifiedDate}} ({{totalEditions}} edycji łącznie) Zawartość: {{ wikiPageContent }}", + "DATETIME": "DD MMM YYYY HH:mm", + "PLACEHOLDER_PAGE": "Napisz swoje Wiki", + "REMOVE": "Usuń tą stronę Wiki", + "DELETE_LIGHTBOX_TITLE": "Usuń tą stronę Wiki", + "NAVIGATION": { + "SECTION_NAME": "Linki", + "ACTION_ADD_LINK": "Dodaj link" + }, + "SUMMARY": { + "TIMES_EDITED": "razy
edytowano", + "LAST_EDIT": "ostatnia
edycja", + "LAST_MODIFICATION": "ostatnia modyfikacja" + } + }, + "HINTS": { + "SECTION_NAME": "Wskazówka", + "LINK": "Jeśli chcesz się dowiedzieć jak tego używać odwiedź nasz support", + "LINK_TITLE": "Odwiedź nasz support", + "HINT1_TITLE": "Czy wiesz, że możesz eksportować i importować projekty?", + "HINT1_TEXT": "Dzięki temu możesz przenieść wszystkie swoje dane z jednej instalacji Taiga do drugiej.", + "HINT2_TITLE": "Czy wiesz, że możesz tworzyć niestandardowe pola?", + "HINT2_TEXT": "Zespoły mogą tworzyć niestandardowe pola co pozwala dopasować formularze do sposobu pracy.", + "HINT3_TITLE": "Zmieniaj kolejność projektów aby wyróżnić te najbardziej istotne dla Ciebie", + "HINT3_TEXT": "Pierwsze 10 projektów będzie wyświetlane w górnym menu", + "HINT4_TITLE": "Zapomniałeś nad czym pracujesz?", + "HINT4_TEXT": "Nie martw się, na Twojej tablicy znajdziesz otwarte zadania, zgłoszenia i historyjki użytkownika w takiej kolejności, w jakiej nad nimi pracowałeś." + }, + "TIMELINE": { + "UPLOAD_ATTACHMENT": "Użytkownik {{username}} wysłał nowy załącznik do {{obj_name}}", + "US_CREATED": "Użytkownik {{username}} utworzył nową historyjkę użytkownika {{obj_name}} w projekcie {{project_name}}", + "ISSUE_CREATED": "Użytkownik {{username}} utworzył nowe zgłoszenie {{obj_name}} w projekcie {{project_name}}", + "TASK_CREATED": "Użytkownik {{username}} utworzył nowe zadanie {{obj_name}} w projekcie {{project_name}}", + "TASK_CREATED_WITH_US": "Użytkownik {{username}} utworzył nowe zadanie {{obj_name}} w projekcie {{project_name}} należące do HU {{us_name}}", + "WIKI_CREATED": "Użytkownik {{username}} utworzył nową stronę Wiki {{obj_name}} w projekcie {{project_name}}", + "MILESTONE_CREATED": "Użytkownik {{username}} utworzył nowy sprint {{obj_name}} w projekcie {{project_name}}", + "NEW_PROJECT": "Użytkownik {{username}} utworzył projekt {{project_name}}", + "MILESTONE_UPDATED": "Użytkownik {{username}} zaktualizował sprint {{obj_name}}", + "US_UPDATED": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} historyjki użytkownika {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} historyjki użytkownika {{obj_name}} na {{new_value}}", + "US_UPDATED_POINTS": "Użytkownik {{username}} zaktualizował '{{role_name}}' punkty w historyjce użytkownika {{obj_name}} na {{new_value}}", + "ISSUE_UPDATED": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zgłoszenia {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zgłoszenia {{obj_name}} na {{new_value}}", + "TASK_UPDATED": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zadania {{obj_name}} na {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zadania {{obj_name}} na {{new_value}}", + "TASK_UPDATED_WITH_US": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zadania {{obj_name}} należącego do HU {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "Użytkownik {{username}} zaktualizował atrybut {{field_name}} zadania {{obj_name}} należącego do HU {{us_name}} na {{new_value}}", + "WIKI_UPDATED": "Użytkownik {{username}} zaktualizował stronę Wiki {{obj_name}}", + "NEW_COMMENT_US": "Użytkownik {{username}} skomentował historyjkę użytkownika {{obj_name}}", + "NEW_COMMENT_ISSUE": "Użytkownik {{username}} skomentował zgłoszenie {{obj_name}}", + "NEW_COMMENT_TASK": "Użytkownik {{username}} skomentował zadanie {{obj_name}}", + "NEW_MEMBER": "Projekt {{project_name}} ma nowego członka", + "US_ADDED_MILESTONE": "Użytkownik{{username}} dodał HU {{obj_name}} do {{sprint_name}}", + "US_REMOVED_FROM_MILESTONE": "Użytkownik {{username}} dodał HU {{obj_name}} do backlogu", + "BLOCKED": "Użytkownik {{username}} zablokował {{obj_name}}", + "UNBLOCKED": "Użytkownik {{username}} odblokował {{obj_name}}", + "NEW_USER": "Nowy użytkownik{{username}} dołączył do Taiga" + } +} \ No newline at end of file From 74193e681fc6b689f0ac6ef7fde324a287e27b13 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 11 Jun 2015 12:20:56 +0200 Subject: [PATCH 075/403] same behavior for issues filters and backlog filters all filter attributes are OR except tags related #2648 test with taiga-back refactoring-filter-data-API --- app/coffee/modules/backlog/filters.coffee | 45 ++++-- app/coffee/modules/backlog/main.coffee | 153 +++++++++--------- app/coffee/modules/issues/list.coffee | 68 +++++--- app/coffee/modules/resources.coffee | 2 + app/coffee/modules/resources/issues.coffee | 4 +- .../modules/resources/userstories.coffee | 3 + app/partials/backlog/backlog.jade | 4 +- .../includes/components/backlog-row.jade | 2 +- .../includes/modules/backlog-filters.jade | 2 +- .../includes/modules/issues-filters.jade | 2 +- 10 files changed, 160 insertions(+), 125 deletions(-) diff --git a/app/coffee/modules/backlog/filters.coffee b/app/coffee/modules/backlog/filters.coffee index bf6a4186..59b219fe 100644 --- a/app/coffee/modules/backlog/filters.coffee +++ b/app/coffee/modules/backlog/filters.coffee @@ -40,6 +40,8 @@ BacklogFiltersDirective = ($log, $location, $templates) -> templateSelected = $templates.get("backlog/filter-selected.html", true) link = ($scope, $el, $attrs) -> + currentFiltersType = '' + $ctrl = $el.closest(".wrapper").controller() selectedFilters = [] @@ -50,16 +52,18 @@ BacklogFiltersDirective = ($log, $location, $templates) -> $el.find("h2 a.subfilter span.title").html(title) $el.find("h2 a.subfilter span.title").prop("data-type", type) + currentFiltersType = getFiltersType() + showCategories = -> $el.find(".filters-cats").show() $el.find(".filter-list").addClass("hidden") $el.find("h2.breadcrumb").addClass("hidden") - initializeSelectedFilters = (filters) -> + initializeSelectedFilters = () -> showCategories() selectedFilters = [] - for name, values of filters + for name, values of $scope.filters for val in values selectedFilters.push(val) if val.selected @@ -81,26 +85,39 @@ BacklogFiltersDirective = ($log, $location, $templates) -> html = template({filters:filters}) $el.find(".filter-list").html(html) + getFiltersType = () -> + return $el.find("h2 a.subfilter span.title").prop('data-type') + toggleFilterSelection = (type, id) -> + currentFiltersType = getFiltersType() + filters = $scope.filters[type] - filter = _.find(filters, {id: taiga.toString(id)}) + filter = _.find(filters, {id: id}) filter.selected = (not filter.selected) + if filter.selected selectedFilters.push(filter) $scope.$apply -> $ctrl.selectFilter(type, id) else - selectedFilters = _.reject(selectedFilters, filter) - $scope.$apply -> - $ctrl.unselectFilter(type, id) + selectedFilters = _.reject selectedFilters, (selected) -> + return filter.type == selected.type && filter.id == selected.id + + $ctrl.unselectFilter(type, id) renderSelectedFilters(selectedFilters) - currentFiltersType = $el.find("h2 a.subfilter span.title").prop('data-type') if type == currentFiltersType renderFilters(_.reject(filters, "selected")) $ctrl.loadUserstories() + .then () -> + # reload the tags when a tag is select or unselected + # and the filters/tags is open + if currentFiltersType == 'tags' + $ctrl.generateFilters().then () -> + tags = $scope.filters["tags"] + renderFilters(_.reject(tags, "selected")) selectQFilter = debounceLeading 100, (value) -> return if value is undefined @@ -113,11 +130,15 @@ BacklogFiltersDirective = ($log, $location, $templates) -> $scope.$watch("filtersQ", selectQFilter) ## Angular Watchers - $scope.$on "filters:loaded", (ctx, filters) -> - initializeSelectedFilters(filters) + $scope.$on "backlog:loaded", (ctx) -> + initializeSelectedFilters() - $scope.$on "filters:update", (ctx, filters) -> - renderFilters(filters) + $scope.$on "filters:update", (ctx) -> + $ctrl.generateFilters().then () -> + filters = $scope.filters[currentFiltersType] + + if currentFiltersType + renderFilters(_.reject(filters, "selected")) ## Dom Event Handlers $el.on "click", ".filters-cats > ul > li > a", (event) -> @@ -126,7 +147,7 @@ BacklogFiltersDirective = ($log, $location, $templates) -> tags = $scope.filters[target.data("type")] renderFilters(_.reject(tags, "selected")) - showFilters(target.attr("title"), target.data("type")) + showFilters(target.attr("title"), target.data('type')) $el.on "click", ".filters-inner > .filters-step-cat > .breadcrumb > .back", (event) -> event.preventDefault() diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 75bafc3e..fdcc1974 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -96,6 +96,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.$on "usform:new:success", => @.loadUserstories() @.loadProjectStats() + + @rootscope.$broadcast("filters:update") @analytics.trackEvent("userstory", "create", "create userstory on backlog", 1) @scope.$on "sprintform:edit:success", => @@ -105,9 +107,11 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @.loadSprints() @.loadProjectStats() @.loadUserstories() + @rootscope.$broadcast("filters:update") @scope.$on "usform:edit:success", => @.loadUserstories() + @rootscope.$broadcast("filters:update") @scope.$on("sprint:us:move", @.moveUs) @scope.$on("sprint:us:moved", @.loadSprints) @@ -182,7 +186,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F resetFilters: -> selectedTags = _.filter(@scope.filters.tags, "selected") - selectedStatuses = _.filter(@scope.filters.statuses, "selected") + selectedStatuses = _.filter(@scope.filters.status, "selected") @scope.filtersQ = "" @@ -195,6 +199,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @.unselectFilter(item.type, item.id) @.loadUserstories() + @rootscope.$broadcast("filters:update") loadUserstories: -> @scope.httpParams = @.getUrlFilters() @@ -208,10 +213,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.userstories = _.sortBy(userstories, "backlog_order") @.setSearchDataFilters() - @.filterVisibleUserstories() - @.generateFilters() - @rootscope.$broadcast("filters:loaded", @scope.filters) # The broadcast must be executed when the DOM has been fully reloaded. # We can't assure when this exactly happens so we need a defer scopeDefer @scope, => @@ -247,22 +249,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @.fillUsersAndRoles(project.members, project.roles) @.initializeSubscription() - return promise.then(=> @.loadBacklog()) - - filterVisibleUserstories: -> - @scope.visibleUserstories = [] - - # Filter by tags - @scope.visibleUserstories = _.reject @scope.userstories, (us) => - return _.some us.tags, (tag) => - return @isFilterSelected("tag", tag) - - # Filter by status - @scope.visibleUserstories = _.filter @scope.visibleUserstories, (us) => - if @searchdata["statuses"] && Object.keys(@searchdata["statuses"]).length - return @isFilterSelected("statuses", taiga.toString(us.status)) - - return true + return promise + .then(=> @.loadBacklog()) + .then(=> @.generateFilters()) + .then(=> @scope.$emit("backlog:loaded")) prepareBulkUpdateData: (uses, field="backlog_order") -> return _.map(uses, (x) -> {"us_id": x.id, "order": x[field]}) @@ -333,13 +323,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.$apply => # Add new us to backlog userstories list # @scope.userstories.splice(newUsIndex, 0, us) - # @scope.visibleUserstories.splice(newUsIndex, 0, us) args = [newUsIndex, 0].concat(usList) Array.prototype.splice.apply(@scope.userstories, args) - Array.prototype.splice.apply(@scope.visibleUserstories, args) - - # Execute the prefiltering of user stories - @.filterVisibleUserstories() # Remove the us from the sprint list. sprint = @scope.sprintsById[oldSprintId] @@ -376,8 +361,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F # Remove moving us from backlog userstories lists. for us, key in usList - r = @scope.visibleUserstories.indexOf(us) - @scope.visibleUserstories.splice(r, 1) + r = @scope.userstories.indexOf(us) + @scope.userstories.splice(r, 1) r = @scope.userstories.indexOf(us) @scope.userstories.splice(r, 1) @@ -439,74 +424,82 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @searchdata[name][val] = true getUrlFilters: -> - return _.pick(@location.search(), "statuses", "tags", "q") + return _.pick(@location.search(), "status", "tags", "q") generateFilters: -> urlfilters = @.getUrlFilters() - @scope.filters = {} + @scope.filters = {} - #tags - plainTags = _.flatten(_.filter(_.map(@scope.visibleUserstories, "tags"))) - plainTags.sort() + loadFilters = {} + loadFilters.project = @scope.projectId + loadFilters.tags = urlfilters.tags - if plainTags.length == 0 and urlfilters["tags"] - plainTags.push(urlfilters["tags"]) + return @rs.userstories.filtersData(loadFilters).then (data) => + choicesFiltersFormat = (choices, type, byIdObject) => + _.map choices, (t) -> + return { + id: t[0], + name: byIdObject[t[0]].name, + color: byIdObject[t[0]].color, + count: t[1], + type: type} - @scope.filters.tags = _.map _.countBy(plainTags), (v, k) => - obj = { - id: k, - type: "tags", - name: k, - color: @scope.project.tags_colors[k], - count: v - } - obj.selected = true if @isFilterSelected("tags", obj.id) - return obj + tagsFilterFormat = (tags) => + return _.map tags, (t) => + return { + id: t[0], + name: t[0], + color: @scope.project.tags_colors[t[0]], + count: t[1], + type: "tags" + } - selectedTags = _.filter(@scope.filters.tags, "selected") - selectedTags = _.map(selectedTags, "name") + # Build filters data structure + @scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.usStatusById) + @scope.filters.tags = tagsFilterFormat(data.tags) - #status - plainStatuses = _.map(@scope.visibleUserstories, "status") + selectedTags = _.filter(@scope.filters.tags, "selected") + selectedTags = _.map(selectedTags, "id") - plainStatuses = _.filter plainStatuses, (status) => - if status - return status + selectedStatuses = _.filter(@scope.filters.status, "selected") + selectedStatuses = _.map(selectedStatuses, "id") - if plainStatuses.length == 0 and urlfilters["statuses"] - plainStatuses.push(urlfilters["statuses"]) + @.markSelectedFilters(@scope.filters, urlfilters) - @scope.filters.statuses = _.map _.countBy(plainStatuses), (v, k) => - obj = { - id: k, - type: "statuses", - name: @scope.usStatusById[k].name, - color: @scope.usStatusById[k].color, - count:v - } - obj.selected = true if @isFilterSelected("statuses", obj.id) + #store query params + @rs.userstories.storeQueryParams(@scope.projectId, { + "status": selectedStatuses, + "tags": selectedTags, + "project": @scope.projectId + "milestone": null + }) - return obj + markSelectedFilters: (filters, urlfilters) -> + # Build selected filters (from url) fast lookup data structure + searchdata = {} + for name, value of _.omit(urlfilters, "page", "orderBy") + if not searchdata[name]? + searchdata[name] = {} - selectedStatuses = _.filter(@scope.filters.statuses, "selected") - selectedStatuses = _.map(selectedStatuses, "id") + for val in "#{value}".split(",") + searchdata[name][val] = true - #store query params - @rs.userstories.storeQueryParams(@scope.projectId, { - "status": selectedStatuses, - "tags": selectedTags, - "project": @scope.projectId - "milestone": null - }) + isSelected = (type, id) -> + if searchdata[type]? and searchdata[type][id] + return true + return false + + for key, value of filters + for obj in value + obj.selected = if isSelected(obj.type, obj.id) then true else undefined ## Template actions updateUserStoryStatus: () -> @.setSearchDataFilters() - @.filterVisibleUserstories() - @.generateFilters() - @rootscope.$broadcast("filters:update", @scope.filters['statuses']) - @.loadProjectStats() + @.generateFilters().then () -> + @rootscope.$broadcast("filters:update") + @.loadProjectStats() editUserStory: (us) -> @rootscope.$broadcast("usform:edit", us) @@ -519,7 +512,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @confirm.askOnDelete(title, message).then (finish) => # We modify the userstories in scope so the user doesn't see the removed US for a while @scope.userstories = _.without(@scope.userstories, us) - @filterVisibleUserstories() promise = @.repo.remove(us) promise.then => finish() @@ -560,9 +552,9 @@ BacklogDirective = ($repo, $rootscope, $translate) -> total_points = stats.total_points current_sum = stats.assigned_points - return if not $scope.visibleUserstories + return if not $scope.userstories - for us, i in $scope.visibleUserstories + for us, i in $scope.userstories current_sum += us.total_points if current_sum > total_points @@ -603,7 +595,6 @@ BacklogDirective = ($repo, $rootscope, $translate) -> # Update the total of points $scope.sprints[0].total_points += totalExtraPoints - $ctrl.filterVisibleUserstories() $repo.saveAll(selectedUss).then -> $ctrl.loadSprints() $ctrl.loadProjectStats() @@ -725,7 +716,7 @@ BacklogDirective = ($repo, $rootscope, $translate) -> $el.find(".backlog-table-body").disableSelection() filters = $ctrl.getUrlFilters() - if filters.statuses || + if filters.status || filters.tags || filters.q showHideFilter($scope, $el, $ctrl) diff --git a/app/coffee/modules/issues/list.coffee b/app/coffee/modules/issues/list.coffee index d6fbf588..20c6cdc2 100644 --- a/app/coffee/modules/issues/list.coffee +++ b/app/coffee/modules/issues/list.coffee @@ -83,8 +83,6 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.$on "issueform:new:success", => @analytics.trackEvent("issue", "create", "create issue on issues list", 1) @.loadIssues() - @.loadFilters() - initializeSubscription: -> routingKey = "changes.project.#{@scope.projectId}.issues" @@ -115,9 +113,10 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi return project getUrlFilters: -> - filters = _.pick(@location.search(), "page", "tags", "statuses", "types", + filters = _.pick(@location.search(), "page", "tags", "status", "types", "q", "severities", "priorities", "assignedTo", "createdBy", "orderBy") + filters.page = 1 if not filters.page return filters @@ -180,9 +179,13 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.filters.myFilters = myFilters return myFilters + loadFilters = {} + loadFilters.project = @scope.projectId + loadFilters.tags = urlfilters.tags + # Load default filters data promise = promise.then => - return @rs.issues.filtersData(@scope.projectId) + return @rs.issues.filtersData(loadFilters) # Format filters and set them on scope return promise.then (data) => @@ -220,16 +223,17 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi } # Build filters data structure - @scope.filters.statuses = choicesFiltersFormat(data.statuses, "statuses", @scope.issueStatusById) + @scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.issueStatusById) @scope.filters.severities = choicesFiltersFormat(data.severities, "severities", @scope.severityById) @scope.filters.priorities = choicesFiltersFormat(data.priorities, "priorities", @scope.priorityById) @scope.filters.assignedTo = usersFiltersFormat(data.assigned_to, "assignedTo", "Unassigned") - @scope.filters.createdBy = usersFiltersFormat(data.created_by, "createdBy", "Unknown") + @scope.filters.createdBy = usersFiltersFormat(data.owners, "createdBy", "Unknown") @scope.filters.types = choicesFiltersFormat(data.types, "types", @scope.issueTypeById) @scope.filters.tags = tagsFilterFormat(data.tags) @.removeNotExistingFiltersFromUrl() @.markSelectedFilters(@scope.filters, urlfilters) + @rootscope.$broadcast("filters:loaded", @scope.filters) # We need to guarantee that the last petition done here is the finally used @@ -257,7 +261,7 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi name = "assigned_to" else if name == "createdBy" name = "owner" - else if name == "statuses" + else if name == "status" name = "status" else if name == "types" name = "type" @@ -272,14 +276,19 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi @scope.page = data.current @scope.count = data.count @scope.paginatedBy = data.paginatedBy + return data + return promise + loadInitialData: -> promise = @.loadProject() return promise.then (project) => - @.fillUsersAndRoles(project.members, project.roles) + @.fillUsersAndRoles(project.users, project.roles) @.initializeSubscription() - return @q.all([@.loadFilters(), @.loadIssues()]) + @.loadFilters() + + return @.loadIssues() saveCurrentFiltersTo: (newFilter) -> deferred = @q.defer() @@ -445,6 +454,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ link = ($scope, $el, $attrs) -> $ctrl = $el.closest(".wrapper").controller() + selectedFilters = [] showFilters = (title, type) -> @@ -506,7 +516,6 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ filters = $scope.filters[type] filterId = if type == 'tags' then taiga.toString(id) else id filter = _.find(filters, {id: filterId}) - filter.selected = (not filter.selected) # Convert id to null as string for properly @@ -515,18 +524,27 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ if filter.selected selectedFilters.push(filter) - $scope.$apply -> - $ctrl.selectFilter(type, id) - $ctrl.selectFilter("page", 1) - $ctrl.storeFilters() - $ctrl.loadIssues() + $ctrl.selectFilter(type, id) + $ctrl.selectFilter("page", 1) + $ctrl.storeFilters() else - selectedFilters = _.reject(selectedFilters, filter) - $scope.$apply -> - $ctrl.unselectFilter(type, id) - $ctrl.selectFilter("page", 1) - $ctrl.storeFilters() - $ctrl.loadIssues() + selectedFilters = _.reject selectedFilters, (f) -> + return f.id == filter.id && f.type == filter.type + + $ctrl.unselectFilter(type, id) + $ctrl.selectFilter("page", 1) + $ctrl.storeFilters() + + $ctrl.loadIssues() + .then () -> + # reload the tags when a tag is select or unselected + # and the filters/tags is open + if filter.type == 'tags' + $ctrl.loadFilters().then () -> + # re-render the tags if the tags filter is open + if currentFiltersType == 'tags' + tags = $scope.filters[filter.type] + renderFilters(_.reject(tags, "selected")) renderSelectedFilters(selectedFilters) @@ -539,7 +557,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ initializeSelectedFilters(filters) $scope.$on "filters:issueupdate", (ctx, filters) -> - html = template({filters:filters.statuses}) + html = template({filters:filters.status}) html = $compile(html)($scope) $el.find(".filter-list").html(html) @@ -708,7 +726,7 @@ IssueStatusInlineEditionDirective = ($repo, $template, $rootscope) -> event.stopPropagation() target = angular.element(event.currentTarget) - for filter in $scope.filters.statuses + for filter in $scope.filters.status if filter.id == issue.status filter.count-- @@ -720,13 +738,13 @@ IssueStatusInlineEditionDirective = ($repo, $template, $rootscope) -> $repo.save(issue).then -> $ctrl.loadIssues() - for filter in $scope.filters.statuses + for filter in $scope.filters.status if filter.id == issue.status filter.count++ $rootscope.$broadcast("filters:issueupdate", $scope.filters) - for filter in $scope.filters.statuses + for filter in $scope.filters.status if filter.id == issue.status filter.count++ $rootscope.$broadcast("filters:issueupdate", $scope.filters) diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index 991133c9..0bfd7199 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -82,6 +82,7 @@ urls = { "bulk-update-us-backlog-order": "/userstories/bulk_update_backlog_order" "bulk-update-us-sprint-order": "/userstories/bulk_update_sprint_order" "bulk-update-us-kanban-order": "/userstories/bulk_update_kanban_order" + "userstories-filters": "/userstories/filters_data" # Tasks "tasks": "/tasks" @@ -91,6 +92,7 @@ urls = { # Issues "issues": "/issues" "bulk-create-issues": "/issues/bulk_create" + "issues-filters": "/issues/filters_data" # Wiki pages "wiki": "/wiki" diff --git a/app/coffee/modules/resources/issues.coffee b/app/coffee/modules/resources/issues.coffee index bf7c27df..22cb0f05 100644 --- a/app/coffee/modules/resources/issues.coffee +++ b/app/coffee/modules/resources/issues.coffee @@ -58,8 +58,8 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) -> service.stats = (projectId) -> return $repo.queryOneRaw("projects", "#{projectId}/issues_stats") - service.filtersData = (projectId) -> - return $repo.queryOneRaw("projects", "#{projectId}/issue_filters_data") + service.filtersData = (params) -> + return $repo.queryOneRaw("issues-filters", null, params) service.listValues = (projectId, type) -> params = {"project": projectId} diff --git a/app/coffee/modules/resources/userstories.coffee b/app/coffee/modules/resources/userstories.coffee index de2f8c9b..0d0fbd3d 100644 --- a/app/coffee/modules/resources/userstories.coffee +++ b/app/coffee/modules/resources/userstories.coffee @@ -41,6 +41,9 @@ resourceProvider = ($repo, $http, $urls, $storage) -> service.listInAllProjects = (filters) -> return $repo.queryMany("userstories", filters) + service.filtersData = (params) -> + return $repo.queryOneRaw("userstories-filters", null, params) + service.listUnassigned = (projectId, filters) -> params = {"project": projectId, "milestone": "null"} params = _.extend({}, params, filters or {}) diff --git a/app/partials/backlog/backlog.jade b/app/partials/backlog/backlog.jade index a4862387..c45275ef 100644 --- a/app/partials/backlog/backlog.jade +++ b/app/partials/backlog/backlog.jade @@ -34,10 +34,10 @@ div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl", span.text(translate="BACKLOG.TAGS.SHOW") include ../includes/components/addnewus - section.backlog-table(ng-class="{'hidden': !visibleUserstories.length}") + section.backlog-table(ng-class="{'hidden': !userstories.length}") include ../includes/modules/backlog-table - div.empty.empty-backlog(ng-class="{'hidden': visibleUserstories.length}", tg-backlog-empty-sortable) + div.empty.empty-backlog(ng-class="{'hidden': userstories.length}", tg-backlog-empty-sortable) span.icon.icon-backlog span.title(translate="BACKLOG.EMPTY") a(href="", title="{{'BACKLOG.CREATE_NEW_US' | translate}}", diff --git a/app/partials/includes/components/backlog-row.jade b/app/partials/includes/components/backlog-row.jade index fb8ebfc0..f375076b 100644 --- a/app/partials/includes/components/backlog-row.jade +++ b/app/partials/includes/components/backlog-row.jade @@ -1,4 +1,4 @@ -div.row.us-item-row(ng-repeat="us in visibleUserstories track by us.id", tg-bind-scope, ng-class="{blocked: us.is_blocked}", tg-class-permission="{'readonly': '!modify_us'}") +div.row.us-item-row(ng-repeat="us in userstories track by us.id", tg-bind-scope, ng-class="{blocked: us.is_blocked}", tg-class-permission="{'readonly': '!modify_us'}") div.user-stories div.tags-block(tg-colorize-tags="us.tags", tg-colorize-tags-type="backlog") div.user-story-name diff --git a/app/partials/includes/modules/backlog-filters.jade b/app/partials/includes/modules/backlog-filters.jade index 5533851d..056f65a0 100644 --- a/app/partials/includes/modules/backlog-filters.jade +++ b/app/partials/includes/modules/backlog-filters.jade @@ -18,7 +18,7 @@ section.filters div.filters-cats ul li - a(href="", title="{{'BACKLOG.FILTERS.FILTER_CATEGORY_STATUS' | translate}}", data-type="statuses") + a(href="", title="{{'BACKLOG.FILTERS.FILTER_CATEGORY_STATUS' | translate}}", data-type="status") span.title(translate="BACKLOG.FILTERS.FILTER_CATEGORY_STATUS") span.icon.icon-arrow-right li diff --git a/app/partials/includes/modules/issues-filters.jade b/app/partials/includes/modules/issues-filters.jade index 3b427086..ab735773 100644 --- a/app/partials/includes/modules/issues-filters.jade +++ b/app/partials/includes/modules/issues-filters.jade @@ -22,7 +22,7 @@ section.filters span.title(translate="ISSUES.FILTERS.CATEGORIES.TYPE") span.icon.icon-arrow-right li - a(href="", title="{{ 'ISSUES.FILTERS.CATEGORIES.STATUS' | translate}}", data-type="statuses") + a(href="", title="{{ 'ISSUES.FILTERS.CATEGORIES.STATUS' | translate}}", data-type="status") span.title(translate="ISSUES.FILTERS.CATEGORIES.STATUS") span.icon.icon-arrow-right li From f98bb43c1d90eeebd28b494568853e8f849c4092 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 22 Jul 2015 10:13:53 +0200 Subject: [PATCH 076/403] new baclklog/issues filters implementation - all filter attributes are OR except tags --- app/coffee/modules/backlog/filters.coffee | 24 ++++---- app/coffee/modules/backlog/main.coffee | 32 ++++------- app/coffee/modules/issues/list.coffee | 69 ++++++++++++----------- app/partials/backlog/filters.jade | 4 ++ 4 files changed, 63 insertions(+), 66 deletions(-) diff --git a/app/coffee/modules/backlog/filters.coffee b/app/coffee/modules/backlog/filters.coffee index 59b219fe..eda23e8b 100644 --- a/app/coffee/modules/backlog/filters.coffee +++ b/app/coffee/modules/backlog/filters.coffee @@ -35,7 +35,7 @@ module = angular.module("taigaBacklog") ## Issues Filters Directive ############################################################################# -BacklogFiltersDirective = ($log, $location, $templates) -> +BacklogFiltersDirective = ($q, $log, $location, $templates) -> template = $templates.get("backlog/filters.html", true) templateSelected = $templates.get("backlog/filter-selected.html", true) @@ -88,6 +88,13 @@ BacklogFiltersDirective = ($log, $location, $templates) -> getFiltersType = () -> return $el.find("h2 a.subfilter span.title").prop('data-type') + reloadUserstories = () -> + currentFiltersType = getFiltersType() + + $q.all([$ctrl.loadUserstories(), $ctrl.generateFilters()]).then () -> + currentFilters = $scope.filters[currentFiltersType] + renderFilters(_.reject(currentFilters, "selected")) + toggleFilterSelection = (type, id) -> currentFiltersType = getFiltersType() @@ -110,22 +117,17 @@ BacklogFiltersDirective = ($log, $location, $templates) -> if type == currentFiltersType renderFilters(_.reject(filters, "selected")) - $ctrl.loadUserstories() - .then () -> - # reload the tags when a tag is select or unselected - # and the filters/tags is open - if currentFiltersType == 'tags' - $ctrl.generateFilters().then () -> - tags = $scope.filters["tags"] - renderFilters(_.reject(tags, "selected")) + reloadUserstories() selectQFilter = debounceLeading 100, (value) -> return if value is undefined + if value.length == 0 $ctrl.replaceFilter("q", null) else $ctrl.replaceFilter("q", value) - $ctrl.loadUserstories() + + reloadUserstories() $scope.$watch("filtersQ", selectQFilter) @@ -174,4 +176,4 @@ BacklogFiltersDirective = ($log, $location, $templates) -> return {link:link} -module.directive("tgBacklogFilters", ["$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective]) +module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective]) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index fdcc1974..ac50729c 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -149,10 +149,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F return stats - refreshTagsColors: -> - return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) => - @scope.project.tags_colors = tags_colors - unloadClosedSprints: -> @scope.$apply => @scope.closedSprints = [] @@ -205,10 +201,9 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.httpParams = @.getUrlFilters() @rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams) - promise = @q.all([@.refreshTagsColors(), @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams)]) + promise = @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams) - return promise.then (data) => - userstories = data[1] + return promise.then (userstories) => # NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files @scope.userstories = _.sortBy(userstories, "backlog_order") @@ -433,26 +428,21 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F loadFilters = {} loadFilters.project = @scope.projectId loadFilters.tags = urlfilters.tags + loadFilters.status = urlfilters.status + loadFilters.q = urlfilters.q + loadFilters.milestone = 'null' return @rs.userstories.filtersData(loadFilters).then (data) => choicesFiltersFormat = (choices, type, byIdObject) => _.map choices, (t) -> - return { - id: t[0], - name: byIdObject[t[0]].name, - color: byIdObject[t[0]].color, - count: t[1], - type: type} + t.type = type + return t tagsFilterFormat = (tags) => - return _.map tags, (t) => - return { - id: t[0], - name: t[0], - color: @scope.project.tags_colors[t[0]], - count: t[1], - type: "tags" - } + return _.map tags, (t) -> + t.id = t.name + t.type = 'tags' + return t # Build filters data structure @scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.usStatusById) diff --git a/app/coffee/modules/issues/list.coffee b/app/coffee/modules/issues/list.coffee index 20c6cdc2..0435e870 100644 --- a/app/coffee/modules/issues/list.coffee +++ b/app/coffee/modules/issues/list.coffee @@ -182,6 +182,13 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi loadFilters = {} loadFilters.project = @scope.projectId loadFilters.tags = urlfilters.tags + loadFilters.status = urlfilters.status + loadFilters.q = urlfilters.q + loadFilters.types = urlfilters.types + loadFilters.severities = urlfilters.severities + loadFilters.priorities = urlfilters.priorities + loadFilters.assigned_to = urlfilters.assignedTo + loadFilters.owner = urlfilters.createdBy # Load default filters data promise = promise.then => @@ -191,12 +198,11 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi return promise.then (data) => usersFiltersFormat = (users, type, unknownOption) => reformatedUsers = _.map users, (t) => - return { - id: t[0], - count: t[1], - type: type - name: if t[0] then @scope.usersById[t[0]].full_name_display else unknownOption - } + t.type = type + t.name = if t.full_name then t.full_name else unknownOption + + return t + unknownItem = _.remove(reformatedUsers, (u) -> not u.id) reformatedUsers = _.sortBy(reformatedUsers, (u) -> u.name.toUpperCase()) if unknownItem.length > 0 @@ -205,22 +211,14 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi choicesFiltersFormat = (choices, type, byIdObject) => _.map choices, (t) -> - return { - id: t[0], - name: byIdObject[t[0]].name, - color: byIdObject[t[0]].color, - count: t[1], - type: type} + t.type = type + return t tagsFilterFormat = (tags) => - return _.map tags, (t) => - return { - id: t[0], - name: t[0], - color: @scope.project.tags_colors[t[0]], - count: t[1], - type: "tags" - } + return _.map tags, (t) -> + t.id = t.name + t.type = 'tags' + return t # Build filters data structure @scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.issueStatusById) @@ -448,7 +446,7 @@ module.directive("tgIssues", ["$log", "$tgLocation", "$tgTemplate", "$compile", ## Issues Filters Directive ############################################################################# -IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $translate, $compile, $auth) -> +IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $template, $translate, $compile, $auth) -> template = $template.get("issue/issues-filters.html", true) templateSelected = $template.get("issue/issues-filters-selected.html", true) @@ -500,6 +498,16 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ html = $compile(html)($scope) $el.find(".filter-list").html(html) + getFiltersType = () -> + return $el.find("h2 a.subfilter span.title").prop('data-type') + + reloadIssues = () -> + currentFiltersType = getFiltersType() + + $q.all([$ctrl.loadIssues(), $ctrl.loadFilters()]).then () -> + filters = $scope.filters[currentFiltersType] + renderFilters(_.reject(filters, "selected")) + toggleFilterSelection = (type, id) -> if type == "myFilters" $rs.issues.getMyFilters($scope.projectId).then (data) -> @@ -535,20 +543,12 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ $ctrl.selectFilter("page", 1) $ctrl.storeFilters() - $ctrl.loadIssues() - .then () -> - # reload the tags when a tag is select or unselected - # and the filters/tags is open - if filter.type == 'tags' - $ctrl.loadFilters().then () -> - # re-render the tags if the tags filter is open - if currentFiltersType == 'tags' - tags = $scope.filters[filter.type] - renderFilters(_.reject(tags, "selected")) + reloadIssues() renderSelectedFilters(selectedFilters) - currentFiltersType = $el.find("h2 a.subfilter span.title").prop('data-type') + currentFiltersType = getFiltersType() + if type == currentFiltersType renderFilters(_.reject(filters, "selected")) @@ -572,7 +572,8 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ else $ctrl.replaceFilter("q", value) $ctrl.storeFilters() - $ctrl.loadIssues() + + reloadIssues() $scope.$watch("filtersQ", selectQFilter) @@ -679,7 +680,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $ return {link:link} -module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", +module.directive("tgIssuesFilters", ["$q", "$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading", "$tgTemplate", "$translate", "$compile", "$tgAuth", IssuesFiltersDirective]) diff --git a/app/partials/backlog/filters.jade b/app/partials/backlog/filters.jade index 05faf672..1d504108 100644 --- a/app/partials/backlog/filters.jade +++ b/app/partials/backlog/filters.jade @@ -3,11 +3,15 @@ a.single-filter.active(data-type!="<%- f.type %>", data-id!="<%- f.id %>") span.name(style!="<%- f.style %>") | <%- f.name %> + <% if (f.count){ %> span.number <%- f.count %> + <% } %> <% } else { %> a.single-filter(data-type!="<%- f.type %>", data-id!="<%- f.id %>") span.name(style!="<%- f.style %>") | <%- f.name %> + <% if (f.count){ %> span.number <%- f.count %> + <% } %> <% } %> <% }) %> \ No newline at end of file From 75137404e31d1caf15b2592a8c396d73204c662b Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 29 Jul 2015 11:36:55 +0200 Subject: [PATCH 077/403] fix issue #3089 distores timeline image --- app/modules/user-timeline/user-timeline/user-timeline.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/app/modules/user-timeline/user-timeline/user-timeline.scss b/app/modules/user-timeline/user-timeline/user-timeline.scss index 38cb644a..6446d82a 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.scss +++ b/app/modules/user-timeline/user-timeline/user-timeline.scss @@ -29,7 +29,6 @@ img { max-height: 640px; max-width: 640px; - width: 100%; } .activity-info { align-items: center; From 8b2ac40c42993e1cb8e30d5a50f42c1a3fbcb590 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 29 Jul 2015 11:39:08 +0200 Subject: [PATCH 078/403] fix timeline attachments --- .../user-timeline-item/user-timeline-item.controller.coffee | 5 +++-- .../user-timeline-item.controller.spec.coffee | 3 ++- .../user-timeline/user-timeline-item/user-timeline-item.jade | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee index 9228cf37..f73b1545 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.coffee @@ -20,8 +20,9 @@ class UserTimelineItemController if type.member @.timeline = @.timeline.set('member', type.member(@.timeline)) - if @.timeline.hasIn(['data', 'value_diff', 'attachments', 'new']) - @.timeline = @.timeline.set('attachments', @.timeline.getIn(['data', 'value_diff', 'attachments', 'new'])) + if @.timeline.getIn(['data', 'value_diff', 'key']) == 'attachments' && + @.timeline.hasIn(['data', 'value_diff', 'value', 'new']) + @.timeline = @.timeline.set('attachments', @.timeline.getIn(['data', 'value_diff', 'value', 'new'])) getObject: (timeline, event) -> if timeline.get('data').get(event.obj) diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee index 28a3f15d..bbad8f5b 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.controller.spec.coffee @@ -54,7 +54,8 @@ describe "UserTimelineItemController", -> id: 2 }, value_diff: { - attachments: { + key: 'attachments', + value: { new: "fakeAttachment" } } diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade index 6ed8f7f9..f549c8a2 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item.jade @@ -25,5 +25,5 @@ div.activity-item span {{::vm.timeline.getIn(['member','user', 'name'])}} p {{::vm.timeline.getIn(['member','role', 'name'])}} - div(ng-repeat="attachment in vm.timeline.get('attachments')") + div(tg-repeat="attachment in vm.timeline.get('attachments')") div(tg-user-timeline-attachment="attachment") From ec04907d4474885373e7ce4ab7de8d1692380f91 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 21 Jul 2015 08:21:44 +0200 Subject: [PATCH 079/403] issue 3074 - the new sprint date starts at the end of the last open sprint --- app/coffee/modules/backlog/lightboxes.coffee | 27 +++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/app/coffee/modules/backlog/lightboxes.coffee b/app/coffee/modules/backlog/lightboxes.coffee index cd72905e..cf952c4e 100644 --- a/app/coffee/modules/backlog/lightboxes.coffee +++ b/app/coffee/modules/backlog/lightboxes.coffee @@ -105,6 +105,15 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading, $confirm.notify("error") $repo.remove($scope.sprint).then(onSuccess, onError) + getLastSprint = -> + openSprints = _.filter $scope.sprints, (sprint) -> + return !sprint.closed + + sortedSprints = _.sortBy openSprints, (sprint) -> + return moment(sprint.estimated_finish, 'YYYY-MM-DD').format('X') + + return sortedSprints[sortedSprints.length - 1] + $scope.$on "sprintform:create", (event, projectId) -> form = $el.find("form").checksley() form.reset() @@ -115,20 +124,24 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading, $scope.sprint.name = null $scope.sprint.slug = null - lastSprint = $scope.sprints[0] + lastSprint = getLastSprint() estimatedStart = moment() - if $scope.sprint.estimated_start - estimatedStart = moment($scope.sprint.estimated_start) - else if lastSprint? + + if lastSprint estimatedStart = moment(lastSprint.estimated_finish) + else if $scope.sprint.estimated_start + estimatedStart = moment($scope.sprint.estimated_start) + $scope.sprint.estimated_start = estimatedStart.format(prettyDate) estimatedFinish = moment().add(2, "weeks") - if $scope.sprint.estimated_finish - estimatedFinish = moment($scope.sprint.estimated_finish) - else if lastSprint? + + if lastSprint estimatedFinish = moment(lastSprint.estimated_finish).add(2, "weeks") + else if $scope.sprint.estimated_finish + estimatedFinish = moment($scope.sprint.estimated_finish) + $scope.sprint.estimated_finish = estimatedFinish.format(prettyDate) lastSprintNameDom = $el.find(".last-sprint-name") From 62137e6f885eba83721e93fd47ad32372ba639a6 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 29 Jul 2015 14:59:09 +0200 Subject: [PATCH 080/403] don't throw object:updated with the related detail objects --- app/coffee/modules/userstories/detail.coffee | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index c4a5dfa7..814dab5b 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -87,21 +87,10 @@ class UserStoryDetailController extends mixOf(taiga.Controller, taiga.PageMixin) initializeEventHandlers: -> @scope.$on "related-tasks:update", => - @.loadUs() @scope.tasks = _.clone(@scope.tasks, false) @scope.$on "attachment:create", => @analytics.trackEvent("attachment", "create", "create attachment on userstory", 1) - @rootscope.$broadcast("object:updated") - - @scope.$on "attachment:edit", => - @rootscope.$broadcast("object:updated") - - @scope.$on "attachment:delete", => - @rootscope.$broadcast("object:updated") - - @scope.$on "custom-attributes-values:edit", => - @rootscope.$broadcast("object:updated") @scope.$on "comment:new", => @.loadUs() From b8c440d723ed1be06cab3b6de0f96c7238814988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Wed, 29 Jul 2015 20:32:25 +0200 Subject: [PATCH 081/403] [i18n] Update locales --- app/locales/locale-ca.json | 54 +++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index af143261..de0f018e 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -32,7 +32,7 @@ "ONE_ITEM_LINE": "In item per línia", "NEW_BULK": "Nova inserció en grup", "RELATED_TASKS": "Tasques relacionades", - "LOGOUT": "Logout", + "LOGOUT": "Surt", "EXTERNAL_USER": "un usuari extern", "GENERIC_ERROR": "Un Oompa Loompas diu {{error}}.", "IOCAINE_TEXT": "Un poc saturat per una tasca? Fes-ho saber als teus companys clicant a Iocaina quan edites la tasca. Es possible ser inmune a aquesta (fictícia) poció mortal consumint xicotetes dòsis poc a poc, així com es possible millorar amb xicotets nous desafiaments!", @@ -222,9 +222,9 @@ "ISSUES": { "NAME": "Incidències", "VIEW_ISSUES": "Vore incidències", - "ADD_ISSUES": "Afegir incidències", - "MODIFY_ISSUES": "Modificar incidències", - "DELETE_ISSUES": "Esborrar incidències" + "ADD_ISSUES": "Afegeix incidències", + "MODIFY_ISSUES": "Modifica incidències", + "DELETE_ISSUES": "Elimina incidències" }, "WIKI": { "NAME": "Wiki", @@ -326,8 +326,8 @@ }, "HOME": { "PAGE_TITLE": "Home - Taiga", - "PAGE_DESCRIPTION": "La home de Taiga amb els teus projectes principals, totes les històries d'usuari, tasques e incidències que tens assignades i aquelles que estàs Watching", - "EMPTY_WATCHING": "Segueix els projectes, històries d'usuari, tasques e incidències... de les que vols conèixer la evolució.", + "PAGE_DESCRIPTION": "La home de Taiga amb els teus projectes principals, totes les històries d'usuari, tasques i incidències que tens assignades i aquelles que estàs Watching", + "EMPTY_WATCHING": "Segueix els projectes, històries d'usuari, tasques i incidències... de les que vols conèixer l'evolució :)", "EMPTY_PROJECT_LIST": "No tens cap projecte encara", "WORKING_ON_SECTION": "En Progrés", "WATCHING_SECTION": "Observant" @@ -447,7 +447,7 @@ }, "CUSTOM_FIELDS": { "TITLE": "Camps personalitzats", - "SUBTITLE": "Especifica els camps personalitzats del les teues históries d'usuari, tasques e incidències", + "SUBTITLE": "Especifiqueu els camps personalitzats del les vostres històries d'usuari, tasques i incidències", "US_DESCRIPTION": "Camps personalitzats d'històries d'usuari", "US_ADD": "Afegeix camps personalitzats en històries d'usuari", "TASK_DESCRIPTION": "Camps personalitzats de tasques", @@ -476,13 +476,13 @@ }, "PROJECT_VALUES_SEVERITIES": { "TITLE": "Severities", - "SUBTITLE": "Especifica les severitats que tindran les teues incidències", + "SUBTITLE": "Especifiqueu les severitats que tindran les vostres incidències", "ISSUE_TITLE": "Issue severities", "ACTION_ADD": "Add new severity" }, "PROJECT_VALUES_STATUS": { "TITLE": "Estat", - "SUBTITLE": "Especifica els estats del les teues históries d'usuari, tasques e incidències", + "SUBTITLE": "Especifica els estats de les vostres històries d'usuari, tasques i incidències", "US_TITLE": "Estats d'US", "TASK_TITLE": "Estats de tasques", "ISSUE_TITLE": "Estats d'incidències" @@ -631,10 +631,10 @@ "USER": { "PROFILE": { "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", - "EDIT": "Editar perfil", + "EDIT": "Edita el perfil", "FOLLOW": "Follow", "PROJECTS": "Projectes", - "CLOSED_US": "Closed US", + "CLOSED_US": "HU tancada", "CONTACTS": "Contacts", "REPORT": "Report Abuse", "ACTIVITY_TAB": "Activity Tab", @@ -680,28 +680,28 @@ "PLACEHOLDER_SEARCH": "Cerca en...", "ACTION_CREATE_PROJECT": "Crear projecte", "ACTION_IMPORT_PROJECT": "Import project", - "SEE_MORE_PROJECTS": "See more projects", + "SEE_MORE_PROJECTS": "Visualitza més projectes", "TITLE_CREATE_PROJECT": "Create project", "TITLE_IMPORT_PROJECT": "Import project", "TITLE_PRVIOUS_PROJECT": "Mostra projectes previs", "TITLE_NEXT_PROJECT": "Mostrar próxims projectes", "HELP_TITLE": "Taiga Support Page", - "HELP": "Help", - "FEEDBACK_TITLE": "Enviar sugerències", - "FEEDBACK": "Sugerències", + "HELP": "Ajuda", + "FEEDBACK_TITLE": "Enviar suggerències", + "FEEDBACK": "Suggerències", "NOTIFICATIONS_TITLE": "Edit your notification settings", "NOTIFICATIONS": "Notificacions", "ORGANIZATIONS_TITLE": "Edit your organizations", "ORGANIZATIONS": "Edit organizations", "SETTINGS_TITLE": "Edit your settings", "SETTINGS": "Settings", - "VIEW_PROFILE_TITLE": "View Profile", - "VIEW_PROFILE": "View Profile", - "EDIT_PROFILE_TITLE": "Edit your profile", - "EDIT_PROFILE": "Edit Profile", + "VIEW_PROFILE_TITLE": "Visualitza el perfil", + "VIEW_PROFILE": "Visualitza el perfil", + "EDIT_PROFILE_TITLE": "Editeu el vostre perfil", + "EDIT_PROFILE": "Edita el perfil", "CHANGE_PASSWORD_TITLE": "Canvi de contrasenya", "CHANGE_PASSWORD": "Canvi de contrasenya", - "DASHBOARD_TITLE": "Dashboard", + "DASHBOARD_TITLE": "Tauler", "DISCOVER_TITLE": "Discover trending projects", "DISCOVER": "Discover", "ACTION_REORDER": "Drag & drop to reorder" @@ -747,7 +747,7 @@ "FEEDBACK": { "TITLE": "Contans...", "COMMENT": "...un bug, una sugerència, algo bonic... inclús el teu pitjor malson amb Taiga.", - "ACTION_SEND": "Enviar sugerències" + "ACTION_SEND": "Enviar suggerències" }, "SEARCH": { "TITLE": "Cerca", @@ -791,7 +791,7 @@ "LINK_TASKBOARD": "Panell de tasques", "TITLE_LINK_TASKBOARD": "Anar a panell de tasques", "TOTAL_POINTS": "total", - "ADD": "+ Afegir nova història d'usuari", + "ADD": "+ Afegeix una nova història d'usuari", "ADD_BULK": "Afegeix noves històries d'usuari en grup", "PROMOTED": "Aquesta US ha sigut promocionada desde:", "TITLE_LINK_GO_TO_ISSUE": "Anar a la incidència", @@ -1006,7 +1006,7 @@ "TITLE_ACTION_IOCAINE": "Un poc saturat per una tasca? Fes-ho saber als teus companys clicant a Iocaina quan edites la tasca. Es possible ser inmune a aquesta (fictícia) poció mortal consumint xicotetes dòsis poc a poc, així com es possible millorar amb xicotets nous desafiaments!" }, "NOTIFICATION": { - "OK": "Tot està ok", + "OK": "Tot està bé", "WARNING": "Oops, ha passat algo...", "WARNING_TEXT": "Els teus canvis no s'han salvat!", "SAVED": "Els Oompa Loompas han salvat els teus canvis!", @@ -1106,7 +1106,7 @@ "TITLE_ACTION_UNFOLD": "Desplegar columna", "TITLE_ACTION_FOLD_CARDS": "Plegar targeta", "TITLE_ACTION_UNFOLD_CARDS": "Desplegar targetes", - "TITLE_ACTION_ADD_US": "Afegir història d'usuari", + "TITLE_ACTION_ADD_US": "Afegeix una nova història d'usuari", "TITLE_ACTION_ADD_BULK": "Afegir en grup", "ACTION_SHOW_ARCHIVED": "Mostrar arxivats", "ACTION_HIDE_ARCHIVED": "Amagar arxivats", @@ -1171,7 +1171,7 @@ "USER_PROFILE": "Perfil d'usuari", "CHANGE_PASSWORD": "Canvi de contrasenya", "NOTIFICATIONS": "Notificacions", - "FEEDBACK": "Sugerències", + "FEEDBACK": "Suggerències", "TITLE_AVATAR": "Preferències d'usuari" } }, @@ -1238,10 +1238,10 @@ "US_CREATED": "{{username}} has created a new US {{obj_name}} in {{project_name}}", "ISSUE_CREATED": "{{username}} has created a new issue {{obj_name}} in {{project_name}}", "TASK_CREATED": "{{username}} has created a new task {{obj_name}} in {{project_name}}", - "TASK_CREATED_WITH_US": "{{username}} has created a new task {{obj_name}} in {{project_name}} which belongs to the US {{us_name}}", + "TASK_CREATED_WITH_US": "{{username}} ha creat una nova tasca {{obj_name}} a {{project_name}} provinent de US {{us_name}}", "WIKI_CREATED": "{{username}} has created a new wiki page {{obj_name}} in {{project_name}}", "MILESTONE_CREATED": "{{username}} has created a new sprint {{obj_name}} in {{project_name}}", - "NEW_PROJECT": "{{username}} created the project {{project_name}}", + "NEW_PROJECT": "{{username}} ha creat el projecte {{project_name}}", "MILESTONE_UPDATED": "{{username}} has updated the sprint {{obj_name}}", "US_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", From f0f640575d9362a8c1a9063567fd47cdce432f78 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 31 Jul 2015 14:18:09 +0200 Subject: [PATCH 082/403] fix change password error message --- app/coffee/modules/user-settings/change-password.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/user-settings/change-password.coffee b/app/coffee/modules/user-settings/change-password.coffee index 4ea8c65c..ba1d19d0 100644 --- a/app/coffee/modules/user-settings/change-password.coffee +++ b/app/coffee/modules/user-settings/change-password.coffee @@ -89,4 +89,4 @@ UserChangePasswordDirective = ($rs, $confirm, $loading, $translate) -> link:link } -module.directive("tgUserChangePassword", ["$tgResources", "$tgConfirm", "$tgLoading", UserChangePasswordDirective]) +module.directive("tgUserChangePassword", ["$tgResources", "$tgConfirm", "$tgLoading", "$translate", UserChangePasswordDirective]) From da5a80796889746e58bd839397f95f74a4d7ae3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sun, 2 Aug 2015 10:40:56 +0200 Subject: [PATCH 083/403] [i18n] Update locles --- app/locales/locale-pl.json | 12 +++++------ app/locales/locale-zh-hant.json | 38 ++++++++++++++++----------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index 32d63f19..ce720f0b 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -885,21 +885,21 @@ "CREATE_NEW_US_EMPTY_HELP": "Możesz utworzyć nową historyjkę użytkownika", "EXCESS_OF_POINTS": "Nadwyżka punktów", "PENDING_POINTS": "Oczekujące punkty", - "CLOSED_POINTS": "zamknięte", + "CLOSED_POINTS": "zamkniętych", "COMPACT_SPRINT": "Kompaktuj sprint", "GO_TO_TASKBOARD": "Idź do tablicy zadań{{::name}}", "EDIT_SPRINT": "Edytuj sprint", - "TOTAL_POINTS": "razem", + "TOTAL_POINTS": "w sumie", "STATUS_NAME": "Nazwa statusu", "SORTABLE_FILTER_ERROR": "Nie możesz przenosić do backlogu kiedy filtry są otwarte", "DOOMLINE": "Zakres projektu [Doomline]", "CHART": { "XAXIS_LABEL": "Sprinty", "YAXIS_LABEL": "Punkty", - "OPTIMAL": "Optymalna ilość puntów oczekujących w sprincie {{sprintName}} to {{value}}", - "REAL": "Faktyczna ilość punktów oczekujących w sprincie {{sprintName}} to {{value}}", - "INCREMENT_TEAM": "Punkty dodane na podstawie wymagań zespołu w sprincie {{sprintName}} to {{value}}", - "INCREMENT_CLIENT": "Punkty dodane na podstawie wymagań klienta w sprincie {{sprintName}} to {{value}}" + "OPTIMAL": "Optymalna ilość puntów oczekujących w sprincie {{xval}} to {{yval}}", + "REAL": "Faktyczna ilość punktów oczekujących w sprincie {{xval}} to {{yval}}", + "INCREMENT_TEAM": "Punkty dodane na podstawie wymagań zespołu w sprincie {{xval}} to {{yval}}", + "INCREMENT_CLIENT": "Punkty dodane na podstawie wymagań klienta w sprincie {{xval}} to {{yval}}" }, "TAGS": { "TOGGLE": "Przełącz widoczność tagów", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 9db6916a..0354b9b8 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -343,7 +343,7 @@ "DESCRIPTION": "輸入一段簡短描述", "DEPRECATED": "(被棄用)", "DEPRECATED_FILE": "棄用?", - "ADD": "Add new attachment. {{maxFileSizeMsg}}", + "ADD": "加入新附件 {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. size: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ 顯示棄用的附件", "HIDE_DEPRECATED": "+ 隱藏棄用的附件", @@ -411,8 +411,8 @@ "JITSI_CHAT_ROOM": "Jitsi", "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", - "CUSTOM_CHAT_ROOM": "Custom", - "URL_CHAT_ROOM": "URL of your chat room" + "CUSTOM_CHAT_ROOM": "自定", + "URL_CHAT_ROOM": "聊天室之網址" }, "PROJECT_PROFILE": { "PAGE_TITLE": "{{sectionName}} - 專案檔案 - {{projectName}}", @@ -430,7 +430,7 @@ "REPORTS": { "TITLE": "Reports", "SUBTITLE": "以 CSV 格式匯出你的專案資料,並製作你的專屬報告", - "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", + "DESCRIPTION": "下載CSV檔案格式是複制生成網址到常用的文字編輯軟體/試算表,以保存你的專案資料報告。你可以輕易地視覺化和分析你的資料。", "HELP": "使用者故事預設欄位", "REGENERATE_TITLE": "改變網址", "REGENERATE_SUBTITLE": "你將要改變CSV資料的連結網址,之前的網址將失效。你確定要這樣做嗎?" @@ -454,8 +454,8 @@ "TASK_ADD": "在任務中加入客制欄位", "ISSUE_DESCRIPTION": "問題客製化欄位", "ISSUE_ADD": "在問題中加入客制欄位", - "FIELD_TYPE_TEXT": "Text", - "FIELD_TYPE_MULTI": "Multi-line" + "FIELD_TYPE_TEXT": "單行文字", + "FIELD_TYPE_MULTI": "多行" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - 專案數值 - {{projectName}}", @@ -896,10 +896,10 @@ "CHART": { "XAXIS_LABEL": "衝刺任務", "YAXIS_LABEL": "點數", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", - "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" + "OPTIMAL": "最適化的衝刺任務\"{{sprintName}}\"待定點數應為 {{value}}", + "REAL": "真實的衝刺任務\"{{sprintName}}\"待定點數為 {{value}}", + "INCREMENT_TEAM": "團隊要求的衝刺任務\"{{sprintName}}\"漸增點數為 {{value}}", + "INCREMENT_CLIENT": "客戶要求的衝刺任務\"{{sprintName}}\"漸增點數為 {{value}}" }, "TAGS": { "TOGGLE": "切換標籤可見度", @@ -917,7 +917,7 @@ "CLOSED_TASKS": "已關閉
任務", "IOCAINE_DOSES": "毒物(全新任務挑戰)
劑量", "SHOW_STATISTICS_TITLE": "顯示統計", - "TOGGLE_BAKLOG_GRAPH": "Show/Hide burndown graph" + "TOGGLE_BAKLOG_GRAPH": "顯示/隱藏 剩餘工作量圖" }, "SUMMARY": { "PROJECT_POINTS": "專案
點數", @@ -1191,8 +1191,8 @@ "PLACEHOLDER_BIO": "請自我介紹", "LANGUAGE": "語言", "LANGUAGE_DEFAULT": "-- 使用設預語言 -- ", - "THEME": "Theme", - "THEME_DEFAULT": "-- use default theme --" + "THEME": "主題", + "THEME_DEFAULT": "-- 使用預設主題--" } }, "WIZARD": { @@ -1244,14 +1244,14 @@ "NEW_PROJECT": "{{username}} 創建專案 {{project_name}}", "MILESTONE_UPDATED": "{{username}}更新衝刺任務 {{obj_name}} ", "US_UPDATED": "{{username}} 已更新 {{obj_name}}使用者故事之 \"{{field_name}}\"屬性。", - "US_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the US {{obj_name}} to {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} 已更新了 {{obj_name}} 使用者故事的\"{{field_name}}\"屬性到{{new_value}}", + "US_UPDATED_POINTS": "{{username}} 已更新了 {{obj_name}} 的使用者故事\"{{field_name}}\"點數為{{new_value}}", "ISSUE_UPDATED": "{{username}} 更新了{{obj_name}}問題的 \"{{field_name}}\" 屬性", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the issue {{obj_name}} to {{new_value}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", - "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} 已更新了 {{obj_name}} 問題的\"{{field_name}}\"屬性到{{new_value}}", + "TASK_UPDATED": "{{username}} 已更新了 {{obj_name}} 使用者故事的\"{{field_name}}\"屬性到{{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} 已更新了 {{obj_name}} 任務\"{{field_name}}\"的屬性到{{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} 更新了 {{obj_name}} 任務之\"{{field_name}}\" 屬性,其為 {{us_name}} 之使用者故事", - "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} 已更新了 {{obj_name}} 下的 {{us_name}} 使用者故事\"{{field_name}}\"屬性到{{new_value}}", "WIKI_UPDATED": "\n{{username}} 更新了維基頁{{obj_name}}", "NEW_COMMENT_US": "{{username}} 評論了 {{obj_name}}使用者故事", "NEW_COMMENT_ISSUE": "{{username}}評論了此問題 {{obj_name}}", From 7e760488f2ae2fad508c29ab5cfbba3b68505348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 3 Aug 2015 11:19:17 +0200 Subject: [PATCH 084/403] [i18n] Add ru --- CHANGELOG.md | 1 + app/locales/locale-ru.json | 1266 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1267 insertions(+) create mode 100644 app/locales/locale-ru.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e36f04aa..5fdcaf68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Ability to choose a theme (thanks to [@astagi](https://github.com/astagi)) - i18n. - Add polish (pl) translation. + - Add russian (ru) translation. ### Misc - Improve performance: Show cropped images in timelines. diff --git a/app/locales/locale-ru.json b/app/locales/locale-ru.json new file mode 100644 index 00000000..f8ef6be4 --- /dev/null +++ b/app/locales/locale-ru.json @@ -0,0 +1,1266 @@ +{ + "COMMON": { + "YES": "Да", + "NO": "Нет", + "LOADING": "Пожалуйста, подождите...", + "LOADING_PROJECT": "Проект загружается...", + "DATE": "ДД МММ ГГГГ", + "DATETIME": "ДД МММ ГГГГ ЧЧ:мм", + "SAVE": "Сохранить", + "CANCEL": "Отмена", + "ACCEPT": "Принимаю", + "DELETE": "Удалить", + "CREATE": "Создать", + "ADD": "Добавить", + "COPY_TO_CLIPBOARD": "Копировать: Ctrl+C", + "EDIT": "Редактировать", + "DRAG": "Перетащите", + "TAG_LINE": "Ваш свободный, agile инструмент управления проектами с открытым исходным кодом", + "TAG_LINE_2": "НРАВИТСЯ ВАШ ПРОЕКТ", + "BLOCK": "Блокировать", + "UNBLOCK": "Разблокировать", + "BLOCKED": "Заблокирован", + "CREATED_BY": "Создано {{fullDisplayName}}", + "FROM": "от", + "TO": "к", + "CLOSE": "закрыть", + "BLOCKED_NOTE": "Почему эта пользовательская история заблокирована?", + "BLOCKED_REASON": "Пожалуйста разъясните причину", + "GO_HOME": "Домой", + "PLUGINS": "Плагины", + "BETA": "Программа тестируется!", + "ONE_ITEM_LINE": "Один объект на строку...", + "NEW_BULK": "Добавить пакетно", + "RELATED_TASKS": "Связанные задачи", + "LOGOUT": "Выйти", + "EXTERNAL_USER": "внешний пользователь", + "GENERIC_ERROR": "Один из Умпа-Лумп говорит {{error}}.", + "IOCAINE_TEXT": "Чувствуете, что задание берет верх над вами? Дайте другим знать об этом, нажав на \"Иокаин\", когда редактируете задание. Возможно стать неуязвимым к этому (выдуманному) смертельном яду, потребляя небольшие количества время от времени, так же как возможно стать лучше в том, что вы делаете, временами беря на себя дополнительные препятствия!", + "FORM_ERRORS": { + "DEFAULT_MESSAGE": "Кажется, это значение некорректно.", + "TYPE_EMAIL": "Это значение должно быть корректным email-адресом.", + "TYPE_URL": "Это значение должно быть корректным URL-адресом.", + "TYPE_URLSTRICT": "Это значение должно быть корректным URL-адресом.", + "TYPE_NUMBER": "Это значение должно быть правильным числом", + "TYPE_DIGITS": "Это значение должно состоять из цифр.", + "TYPE_DATEISO": "Это значение должно быть корректной датой (в формате ГГГГ-ММ-ДД).", + "TYPE_ALPHANUM": "Это значение должно состоять только из букв и цифр.", + "TYPE_PHONE": "Это значение должно быть корректным номером телефона.", + "NOTNULL": "Это значение не должно быть пустым.", + "NOT_BLANK": "Это значение не должно быть пустым.", + "REQUIRED": "Это значение обязательно.", + "REGEXP": "Кажется, это значение некорректно.", + "MIN": "Это значение должно быть больше или равно %s.", + "MAX": "Значение должно быть меньше либо равно %s.", + "RANGE": "Это значение должно быть между %s и %s.", + "MIN_LENGTH": "Это значение слишком короткое. Оно должно иметь %s символов или больше.", + "MAX_LENGTH": "Это значение слишком длинное. Оно должно иметь %s символов или меньше.", + "RANGE_LENGTH": "Длина этого значения некорректна. Оно должно быть от %s до %s символов в длину.", + "MIN_CHECK": "Вы должны выбрать хотя бы %s вариантов.", + "MAX_CHECK": "Вы должны выбрать %s вариантов или меньше.", + "RANGE_CHECK": "Вы должны выбрать от %s до %s вариантов.", + "EQUAL_TO": "Это значение должно быть таким же." + }, + "PICKERDATE": { + "FORMAT": "ДД МММ ГГГГ", + "IS_RTL": "false", + "FIRST_DAY_OF_WEEK": "1", + "PREV_MONTH": "Предыдущий Месяц", + "NEXT_MONTH": "Следующий Месяц", + "MONTHS": { + "JAN": "Январь", + "FEB": "Февраль", + "MAR": "Март", + "APR": "Апрель", + "MAY": "Май", + "JUN": "Июнь", + "JUL": "Июль", + "AUG": "Август", + "SEP": "Сентябрь", + "OCT": "Октябрь", + "NOV": "Ноябрь", + "DEC": "Декабрь" + }, + "WEEK_DAYS": { + "SUN": "Воскресенье", + "MON": "Понедельник", + "TUE": "Вторник", + "WED": "Среда", + "THU": "Черверг", + "FRI": "Пятница", + "SAT": "Суббота" + }, + "WEEK_DAYS_SHORT": { + "SUN": "Вск", + "MON": "Пнд", + "TUE": "Втр", + "WED": "Срд", + "THU": "Чтв", + "FRI": "Птн", + "SAT": "Сбт" + } + }, + "SEE_USER_PROFILE": "Посмотреть профиль {{username }}", + "USER_STORY": "Пользовательская история", + "TASK": "Задача", + "ISSUE": "Проблема", + "TAGS": { + "PLACEHOLDER": "Назначьте тэг", + "DELETE": "Удалить тэг", + "ADD": "Добавить тэг" + }, + "DESCRIPTION": { + "EMPTY": "Пустые места удручают... не стесняйтесь, напишите описание...", + "NO_DESCRIPTION": "Описания ещё нет" + }, + "FIELDS": { + "SUBJECT": "Тема", + "NAME": "Имя", + "URL": "URL", + "DESCRIPTION": "Описание", + "VALUE": "Значение", + "SLUG": "Ссылочное имя", + "COLOR": "Цвет", + "IS_CLOSED": "Закрыто?", + "STATUS": "Статус", + "TYPE": "Тип", + "SEVERITY": "Важность", + "PRIORITY": "Приоритет", + "ASSIGNED_TO": "Назначено", + "POINTS": "Очки", + "BLOCKED_NOTE": "Пояснение блокировки", + "IS_BLOCKED": "заблокирован", + "REF": "Ссылка" + }, + "ROLES": { + "ALL": "Все" + }, + "ASSIGNED_TO": { + "NOT_ASSIGNED": "Не назначен", + "DELETE_ASSIGNMENT": "Удалить назначение", + "REMOVE_ASSIGNED": "Удалить назначение", + "TOO_MANY": "...слишком много пользователей, продолжайте фильтровать", + "CONFIRM_UNASSIGNED": "Вы уверены что не хотите назначить ответственного?", + "TITLE_ACTION_EDIT_ASSIGNMENT": "Изменить назначение" + }, + "STATUS": { + "CLOSED": "Закрыт", + "OPEN": "Открыть" + }, + "WATCHERS": { + "ADD": "Добавить наблюдателя", + "TITLE": "наблюдатели", + "DELETE": "Удалить наблюдателя", + "TITLE_LIGHTBOX_DELETE_WARTCHER": "Удалить наблюдателя..." + }, + "CUSTOM_ATTRIBUTES": { + "CUSTOM_FIELDS": "Пользовательские поля", + "SAVE": "Сохранить поле", + "EDIT": "Редактировать поле", + "DELETE": "Удалить атрибут", + "CONFIRM_DELETE": "Не забудьте, что все значения для этого специального поля будут удалены.
Вы действительно хотите продолжить?" + }, + "FILTERS": { + "TITLE": "фильтры", + "INPUT_PLACEHOLDER": "Название ссылки", + "TITLE_ACTION_FILTER_BUTTON": "поиск", + "BREADCRUMB_TITLE": "назад к категориям", + "BREADCRUMB_FILTERS": "Фильтры", + "BREADCRUMB_STATUS": "cтатус" + }, + "WYSIWYG": { + "H1_BUTTON": "Заголовок первого уровня", + "H1_SAMPLE_TEXT": "Ваш заголовок здесь...", + "H2_BUTTON": "Заголовок второго уровня", + "H2_SAMPLE_TEXT": "Ваш заголовок здесь...", + "H3_BUTTON": "Заголовок третьего уровня", + "H3_SAMPLE_TEXT": "Ваш заголовок здесь...", + "BOLD_BUTTON": "Полужирный", + "BOLD_BUTTON_SAMPLE_TEXT": "Ваш текст здесь...", + "ITALIC_BUTTON": "Курсив", + "ITALIC_SAMPLE_TEXT": "Ваш текст здесь...", + "STRIKE_BUTTON": "Зачёркнутый", + "STRIKE_SAMPLE_TEXT": "Ваш текст здесь...", + "BULLETED_LIST_BUTTON": "Маркированный список", + "BULLETED_LIST_SAMPLE_TEXT": "Ваш текст здесь...", + "NUMERIC_LIST_BUTTON": "Нумерованный список", + "NUMERIC_LIST_SAMPLE_TEXT": "Ваш текст здесь...", + "PICTURE_BUTTON": "Изображение", + "PICTURE_SAMPLE_TEXT": "Альтернативный текст для изображения...", + "LINK_BUTTON": "Ссылка", + "LINK_SAMPLE_TEXT": "Ваш текст для ссылки здесь...", + "QUOTE_BLOCK_BUTTON": "Блок с цитатой", + "QUOTE_BLOCK_SAMPLE_TEXT": "Ваш текст здесь...", + "CODE_BLOCK_BUTTON": "Блок кода", + "CODE_BLOCK_SAMPLE_TEXT": "Ваш текст здесь...", + "PREVIEW_BUTTON": "Предварительный просмотр", + "EDIT_BUTTON": "Редактировать", + "MARKDOWN_HELP": "Помощь по синтаксису Markdown" + }, + "PERMISIONS_CATEGORIES": { + "SPRINTS": { + "NAME": "Спринты", + "VIEW_SPRINTS": "Посмотреть спринты", + "ADD_SPRINTS": "Добавить спринты", + "MODIFY_SPRINTS": "Изменить спринты", + "DELETE_SPRINTS": "Удалить спринты" + }, + "USER_STORIES": { + "NAME": "Истории от Пользователей", + "VIEW_USER_STORIES": "Посмотреть истории от пользователей", + "ADD_USER_STORIES": "Добавить истории от пользователей", + "MODIFY_USER_STORIES": "Изменить истории от пользователей", + "DELETE_USER_STORIES": "Удалить истории от пользователей" + }, + "TASKS": { + "NAME": "Задачи", + "VIEW_TASKS": "Просмотреть задачи", + "ADD_TASKS": "Добавить задачи", + "MODIFY_TASKS": "Редактировать задачи", + "DELETE_TASKS": "Удалить задачи" + }, + "ISSUES": { + "NAME": "Проблемы", + "VIEW_ISSUES": "Посмотреть проблемы", + "ADD_ISSUES": "Добавить проблемы", + "MODIFY_ISSUES": "Изменить проблемы", + "DELETE_ISSUES": "Удалить проблемы" + }, + "WIKI": { + "NAME": "Вики", + "VIEW_WIKI_PAGES": "Посмотреть wiki-страницы", + "ADD_WIKI_PAGES": "Добавить wiki-страницы", + "MODIFY_WIKI_PAGES": "Модифицировать wiki-страницы", + "DELETE_WIKI_PAGES": "Удалить wiki-страницы", + "VIEW_WIKI_LINKS": "Посмотреть wiki-ссылки", + "ADD_WIKI_LINKS": "Добавить wiki-ссылки", + "DELETE_WIKI_LINKS": "Удалить wiki-ссылки" + } + }, + "META": { + "PAGE_TITLE": "Taiga", + "PAGE_DESCRIPTION": "Taiga - это платформа по управлению проектами для стартапов и agile-разработчиков/дизайнеров, которые хотят пользоваться простым и красивым инструментом, делающим их жизнь по-настоящему приятной." + } + }, + "LOGIN": { + "PAGE_TITLE": "Вход - Taiga", + "PAGE_DESCRIPTION": "Выполняется вход в Taiga, платформу для управления проектами стартапов, сделанную для разработчиков и дизайнеров, которые хотят простой и красивый инструмент превращающий работу в удовольствие." + }, + "AUTH": { + "INVITED_YOU": "пригласил Вас присоединиться к проекту", + "NOT_REGISTERED_YET": "Еще не зарегистрированы?", + "REGISTER": "Зарегистрироваться", + "CREATE_ACCOUNT": "Создать бесплатный аккаунт" + }, + "LOGIN_COMMON": { + "HEADER": "У меня уже есть логин в Taiga", + "PLACEHOLDER_AUTH_NAME": "Логин или email (с учетом регистра)", + "LINK_FORGOT_PASSWORD": "Забыли?", + "TITLE_LINK_FORGOT_PASSWORD": "Вы забыли пароль?", + "ACTION_ENTER": "Ввод", + "ACTION_SIGN_IN": "Войти", + "PLACEHOLDER_AUTH_PASSWORD": "Пароль (чувствителен к регистру)" + }, + "LOGIN_FORM": { + "ERROR_AUTH_INCORRECT": "Oompa Loompas считает, что Ваш логин, email или пароль неправильный.", + "SUCCESS": "Oompa Loompas счастлив, добро пожаловать в Тайгу!" + }, + "REGISTER": { + "PAGE_TITLE": "Зарегистрироваться", + "PAGE_DESCRIPTION": "Создайте аккаунт в Taiga — платформе для управления проектами стартапов, agile разработчиков и дизайнеров, которые хотят простой и красивый инструмент превращающий работу в удовольствие." + }, + "REGISTER_FORM": { + "TITLE": "Зарегистрируйте аккаунт Taiga (бесплатно)", + "PLACEHOLDER_NAME": "Выберите имя учётной записи (с учётом регистра)", + "PLACEHOLDER_FULL_NAME": "Введите Ваше полное имя", + "PLACEHOLDER_EMAIL": "Ваш email", + "PLACEHOLDER_PASSWORD": "Задайте новый пароль (с учетом регистра)", + "ACTION_SIGN_UP": "Зарегистрироваться", + "TITLE_LINK_LOGIN": "Войти", + "LINK_LOGIN": "Уже зарегистрированы? Авторизуйтесь" + }, + "FORGOT_PASSWORD": { + "PAGE_TITLE": "Забыли пароль?", + "PAGE_DESCRIPTION": "Введите Ваш логин или email для получения нового пароля и Вы сможете получить доступ к Taiga снова." + }, + "FORGOT_PASSWORD_FORM": { + "TITLE": "Упс, забыли пароль?", + "SUBTITLE": "Введите Ваш логин или email для получения нового пароля", + "PLACEHOLDER_FIELD": "Логин или e-mail", + "ACTION_RESET_PASSWORD": "Сбросить пароль", + "LINK_CANCEL": "Не, давай назад, думаю я вспомню.", + "SUCCESS": "Проверьте почту!
Мы выслали Вам письмо с инструкцией по установке нового пароля", + "ERROR": "Умпа-Лумпы говорят, что вы еще не зарегистрированы." + }, + "CHANGE_PASSWORD": { + "PAGE_TITLE": "Изменить пароль - Taiga", + "PAGE_DESCRIPTION": "Введите новый пароль для Вашего Taiga аккаунта и кстати, может быть Вам будет полезна еда богатая железом — она укрепляет память :P", + "SECTION_NAME": "Изменить пароль", + "FIELD_CURRENT_PASSWORD": "Текущий пароль", + "PLACEHOLDER_CURRENT_PASSWORD": "Ваш текущий пароль (или оставьте пустым, если пароль еще не задан)", + "FIELD_NEW_PASSWORD": "Новый пароль", + "PLACEHOLDER_NEW_PASSWORD": "Введите новый пароль", + "FIELD_RETYPE_PASSWORD": "Введите повторно новый пароль", + "PLACEHOLDER_RETYPE_PASSWORD": "Введите повторно новый пароль", + "ERROR_PASSWORD_MATCH": "Пароли не совпадают" + }, + "CHANGE_PASSWORD_RECOVERY_FORM": { + "TITLE": "Задать новый пароль", + "SUBTITLE": "И кстати, может быть Вам будет полезна еда богатая железом — она укрепляет память :P", + "PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Восстановить токен пароля", + "LINK_NEED_TOKEN": "Создать?", + "TITLE_LINK_NEED_TOKEN": "Вам нужен был токен для восстановления пароля потому что Вы его забыли?", + "PLACEHOLDER_NEW_PASSWORD": "Новый пароль", + "PLACEHOLDER_RE_TYPE_NEW_PASSWORD": "Введите повторно новый пароль", + "ACTION_RESET_PASSWORD": "Сбросить пароль", + "SUCCESS": "Наши Умпа Лумпы сохранили ваш новый пароль.
Попробуйте войти, используя его." + }, + "INVITATION": { + "PAGE_TITLE": "Приглашение принято - Taiga", + "PAGE_DESCRIPTION": "Принять приглашение и присоединиться к Taiga — платформе для управления проектами стартапов, agile разработчиков и дизайнеров, которые хотят простой и красивый инструмент превращающий работу в удовольствие." + }, + "INVITATION_LOGIN_FORM": { + "NOT_FOUND": "Ой, у нас проблема!
Умпа-лумпы не могут найти ваше приглашение.", + "SUCCESS": "Вы успешно добавлены к проекту. Добро пожаловать в {{project_name}}", + "ERROR": "Умпа-Лумпы говорят, что вы не зарегистрированы или ввели неверный пароль." + }, + "HOME": { + "PAGE_TITLE": "Домашняя страница - Taiga", + "PAGE_DESCRIPTION": "Главная страница Тайги, с вашими основными проектами, назначенными и отслеживаемыми задачами, проблемами и историями от пользователей", + "EMPTY_WATCHING": "Следите за проектами, историями от пользователей, задачами, проблемами... о которых хотите знать :)", + "EMPTY_PROJECT_LIST": "У Вас пока нет проектов", + "WORKING_ON_SECTION": "Работает над", + "WATCHING_SECTION": "Отслеживаемые" + }, + "PROJECTS": { + "PAGE_TITLE": "Мои проекты", + "PAGE_DESCRIPTION": "Список Ваших проектов, отсортируйте их или создайте новый.", + "MY_PROJECTS": "Мои проекты" + }, + "ATTACHMENT": { + "SECTION_NAME": "Вложения", + "TITLE": "{{ fileName }} загружен {{ date }}", + "DESCRIPTION": "Введите краткое описание", + "DEPRECATED": "(устаревший)", + "DEPRECATED_FILE": "Устаревший?", + "ADD": "Добавить вложение. {{maxFileSizeMsg}}", + "MAX_FILE_SIZE": "[Макс. размер: {{maxFileSize}}]", + "SHOW_DEPRECATED": "Показать устаревшие приложения", + "HIDE_DEPRECATED": "- спрятать устаревшие приложения", + "COUNT_DEPRECATED": "({{ counter }} устарело)", + "MAX_UPLOAD_SIZE": "Максимальный объем для загрузки {{maxFileSize}}", + "DATE": "ДД МММ ГГГГ [в] чч:мм", + "ERROR_UPLOAD_ATTACHMENT": "Мы не смогли загрузить '{{fileName}}'. {{errorMessage}}", + "TITLE_LIGHTBOX_DELETE_ATTACHMENT": "Удалить вложение...", + "MSG_LIGHTBOX_DELETE_ATTACHMENT": "приложение '{{fileName}}'", + "ERROR_DELETE_ATTACHMENT": "Мы не смогли провести удаление: {{errorMessage}}", + "FIELDS": { + "IS_DEPRECATED": "рекомендовано" + } + }, + "PAGINATION": { + "PREVIOUS": "Пред.", + "NEXT": "Следующий" + }, + "ADMIN": { + "COMMON": { + "TITLE_ACTION_EDIT_VALUE": "Изменить значение", + "TITLE_ACTION_DELETE_VALUE": "Удалить значение" + }, + "HELP": "Вам нужна помощь? Проверьте нашу страницу техподдержки!", + "PROJECT_DEFAULT_VALUES": { + "TITLE": "Значения по умолчанию", + "SUBTITLE": "Задать начальные значения для всех полей" + }, + "MEMBERSHIPS": { + "TITLE": "Управление участниками", + "PAGE_TITLE": "Участие - {{projectName}}", + "ADD_BUTTON": "+ Новый участник", + "ADD_BUTTON_TITLE": "Добавить нового участника" + }, + "PROJECT_EXPORT": { + "TITLE": "Экспорт", + "SUBTITLE": "Экспортируйте ваш проект, чтобы сохранить резервную копию или создать новый, основываясь на текущем.", + "EXPORT_BUTTON": "Экспорт", + "EXPORT_BUTTON_TITLE": "Экспортировать проект", + "LOADING_TITLE": "Мы создали ваш файл резервной копии", + "DUMP_READY": "Файл резервной копии готов!", + "LOADING_MESSAGE": "Пожалуйста, не закрывайте эту страницу", + "ASYNC_MESSAGE": "Мы отправим вам email когда будет готово.", + "SYNC_MESSAGE": "Если загрузка не начинается самостоятельно, нажмите здесь.", + "ERROR": "У Oompa Loompas возникли проблемы при создании резервной копии. Повторите еще раз.", + "ERROR_BUSY": "Извините, Oompa Loompas очень загружен сейчас. Повторите через несколько минут.", + "ERROR_MESSAGE": "Умпа-Лумпы не смогли создать для вас дамп: {{message}}" + }, + "MODULES": { + "TITLE": "Модули", + "ENABLE": "Включить", + "DISABLE": "Выключить", + "BACKLOG": "Список задач", + "BACKLOG_DESCRIPTION": "Управляйте историями от пользователей, чтобы организовывать вашу ближайшую и приоритетную работу", + "KANBAN": "Kanban", + "KANBAN_DESCRIPTION": "Организуйте эффективную работу с проектом с помощью этой панели", + "ISSUES": "Проблемы", + "ISSUES_DESCRIPTION": "Следите за ошибками, вопросами и улучшениями вашего проекта. Ничего не пропустите!", + "WIKI": "Вики", + "WIKI_DESCRIPTION": "Добавляйте, изменяйте или удаляйте контент совместно с остальными. Это самое правильное место для документации вашего проекта.", + "MEETUP": "Созвониться", + "MEETUP_DESCRIPTION": "Выберите вашу систему для видеоконференций. Даже разработчикам нужны митинги \"лицом к лицу\"", + "SELECT_VIDEOCONFERENCE": "Выберите систему видеоконференций", + "SALT_CHAT_ROOM": "Если хотите, можете добавить \"соль\" к имени чат-комнаты", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Другое", + "URL_CHAT_ROOM": "Ссылка на Ваш чат" + }, + "PROJECT_PROFILE": { + "PAGE_TITLE": "{{sectionName}} - профиль Проекта - {{projectName}}", + "PROJECT_DETAILS": "Детали проекта", + "PROJECT_NAME": "Название проекта", + "PROJECT_SLUG": "Ссылочное имя проекта", + "NUMBER_SPRINTS": "Количество спринтов", + "NUMBER_US_POINTS": "Количество ПИ очков", + "TAGS": "Тэги", + "DESCRIPTION": "Описание", + "PUBLIC_PROJECT": "Публичный проект", + "PRIVATE_PROJECT": "Закрытый проект", + "DELETE": "Удалить проект" + }, + "REPORTS": { + "TITLE": "Отчеты", + "SUBTITLE": "Экспортируйте данные вашего проекта в формате CSV и создавайте ваши собственные отчёты", + "DESCRIPTION": "Скачайте файл CSV или скопируйте сгенерированную ссылку, затем откройте в любом текстовом редакторе или редакторе таблиц, чтобы создать ваши собственные отчёты о проекте. Вы сможете легко визуализировать и анализировать ваши данные.", + "HELP": "Как использовать это в моей таблице?", + "REGENERATE_TITLE": "Изменить URL", + "REGENERATE_SUBTITLE": "Вы собираетесь изменить ссылку доступа к данным CSV. Прежний вариант ссылки перестанет работать. Вы уверены?" + }, + "CSV": { + "SECTION_TITLE_US": "Отчёты об историях от пользователей", + "SECTION_TITLE_TASK": "отчёты о задачах", + "SECTION_TITLE_ISSUE": "отчёты о проблемах", + "DOWNLOAD": "Скачать CSV", + "URL_FIELD_PLACEHOLDER": "Упс, забыли пароль?", + "TITLE_REGENERATE_URL": " Сделать CSV ссылку ещё раз", + "ACTION_GENERATE_URL": "Сгенерировать ссылку", + "ACTION_REGENERATE": "Создать заново" + }, + "CUSTOM_FIELDS": { + "TITLE": "Пользовательские поля", + "SUBTITLE": "Укажите специальные поля для ваших задач, историй от пользователей и проблем", + "US_DESCRIPTION": "Специальные поля для историй от пользователей", + "US_ADD": "Добавить специальное поле для историй от пользователей", + "TASK_DESCRIPTION": "Специальные поля задач", + "TASK_ADD": "Добавить новые типы задач", + "ISSUE_DESCRIPTION": "Специальные поля проблем", + "ISSUE_ADD": "Добавить специальное поле для проблем", + "FIELD_TYPE_TEXT": "Текст", + "FIELD_TYPE_MULTI": "Многостроковое" + }, + "PROJECT_VALUES": { + "PAGE_TITLE": "{{sectionName}} - Значения атрибутов проекта - {{projectName}}", + "REPLACEMENT": "Все объекты с этим значением будут заменены на", + "ERROR_DELETE_ALL": "Невозможно удалить все значения" + }, + "PROJECT_VALUES_POINTS": { + "TITLE": "Очки", + "SUBTITLE": "Введите приблизительное количество очков для пользовательских историй", + "US_TITLE": "Очки ПИ", + "ACTION_ADD": "Добавить очки" + }, + "PROJECT_VALUES_PRIORITIES": { + "TITLE": "Приоритеты", + "SUBTITLE": "Укажите, какие приоритеты будут иметь ваши проблемы", + "ISSUE_TITLE": "Приоритеты проблем", + "ACTION_ADD": "Добавить новый приоритет" + }, + "PROJECT_VALUES_SEVERITIES": { + "TITLE": "Степени важности", + "SUBTITLE": "Укажите степени важности, которые будут иметь ваши проблемы", + "ISSUE_TITLE": "Степени важности проблем", + "ACTION_ADD": "Добавить новую степень важности" + }, + "PROJECT_VALUES_STATUS": { + "TITLE": "Статус", + "SUBTITLE": "Укажите, какие статусы будут принимать ваши задачи, истории от пользователей и проблемы", + "US_TITLE": "Статусы ПИ", + "TASK_TITLE": "Статус задач", + "ISSUE_TITLE": "Статусы проблем" + }, + "PROJECT_VALUES_TYPES": { + "TITLE": "Типы", + "SUBTITLE": "Укажите, какие типы смогут иметь ваши проблемы", + "ISSUE_TITLE": "Типы проблем", + "ACTION_ADD": "Добавить новый" + }, + "ROLES": { + "PAGE_TITLE": "Роли - {{projectName}}", + "WARNING_NO_ROLE": "Осторожнее: ни с какими ролями на вашем проекте участники не смогут оценить очки для историй от пользователей.", + "HELP_ROLE_ENABLED": "Когда включено, участники, назначенные на эту роль, смогут оценивать очки для Историй от Пользователей", + "COUNT_MEMBERS": "{{ role.members_count }} участников с этой ролью", + "TITLE_DELETE_ROLE": "Удалить Роль", + "REPLACEMENT_ROLE": "Все пользователи этой роли будут перемещены в", + "WARNING_DELETE_ROLE": "Осторожнее, все оценки, связанные с этой будут удалены", + "ERROR_DELETE_ALL": "Вы не можете удалить все значения", + "EXTERNAL_USER": "Внешний пользователь" + }, + "THIRD_PARTIES": { + "SECRET_KEY": "Секретный ключ", + "PAYLOAD_URL": "Ссылка на полезную нагрузку", + "VALID_IPS": "Правильные IP-адреса (через ,)" + }, + "BITBUCKET": { + "SECTION_NAME": "Bitbucket", + "PAGE_TITLE": "Bitbucket - {{projectName}}", + "INFO_VERIFYING_IP": "Запросы к Bitbucket не подписаны, так что лучший способ их проверки - через IP-адрес. Если это поле пустое, то проверка по IP-адресу не будет проводиться." + }, + "GITLAB": { + "SECTION_NAME": "Gitlab", + "PAGE_TITLE": "Gitlab - {{projectName}}", + "INFO_VERIFYING_IP": "Запросы к Gitlab не подписаны, так что лучший способ их проверки - это проверка по IP-адресу. Если это поле пустое, IP-адрес не будет проверяться." + }, + "GITHUB": { + "SECTION_NAME": "Github", + "PAGE_TITLE": "Github - {{projectName}}" + }, + "WEBHOOKS": { + "PAGE_TITLE": "Web-зацепки - {{projectName}}", + "SECTION_NAME": "Web-зацепки", + "SUBTITLE": "Web-зацепки рассказывают внешним сервисам о событиях в Taiga, таких как комментарии, новые истории от пользователей и т.д.", + "ADD_NEW": "Добавить новую Web-зацепку", + "TYPE_NAME": "Укажите имя сервиса", + "TYPE_PAYLOAD_URL": "Укажите нагрузочную ссылку сервиса", + "TYPE_SERVICE_SECRET": "Введите секретный код сервиса", + "SAVE": "Сохранить Web-зацепку", + "CANCEL": "Отменить Web-зацепку", + "SHOW_HISTORY": "(Показать историю)", + "TEST": "Протестировать Web-зацепку", + "EDIT": "Редактировать Web-зацепку", + "DELETE": "Удалить Web-зацепку", + "REQUEST": "Запрос", + "RESEND_REQUEST": "Переслать запрос", + "HEADERS": "Заголовки", + "PAYLOAD": "Нагрузка", + "RESPONSE": "Ответ", + "DATE": "ДД МММ ГГГГ [в] чч:мм:сс", + "ACTION_HIDE_HISTORY": "(Спрятать историю)", + "ACTION_HIDE_HISTORY_TITLE": "Скрыть детали истории", + "ACTION_SHOW_HISTORY": "(Показать историю)", + "ACTION_SHOW_HISTORY_TITLE": "Показать детали истории", + "WEBHOOK_NAME": "Web-зацепка '{{name}}'" + }, + "CUSTOM_ATTRIBUTES": { + "PAGE_TITLE": "{{sectionName}} - Специальные Атрибуты - {{projectName}}", + "ADD": "Добавить поле", + "EDIT": "Редактировать специальное поле", + "DELETE": "Удалить поле", + "SAVE_TITLE": "Сохранить поле", + "CANCEL_TITLE": "Отменить создание", + "SET_FIELD_NAME": "Введите имя поля", + "SET_FIELD_DESCRIPTION": "Назначьте описание специальному полю", + "ACTION_UPDATE": "Обновить поле", + "ACTION_CANCEL_EDITION": "Отменить правку" + }, + "MEMBERSHIP": { + "COLUMN_MEMBER": "Участник", + "COLUMN_ADMIN": "Админ", + "COLUMN_ROLE": "Роль", + "COLUMN_STATUS": "Статус", + "STATUS_ACTIVE": "Активный", + "STATUS_PENDING": "В ожидании", + "DELETE_MEMBER": "Удалить участника", + "SUCCESS_SEND_INVITATION": "Мы отправили ещё одно приглашение на адрес '{{email}}'.", + "ERROR_SEND_INVITATION": "Мы не выслали приглашение.", + "SUCCESS_DELETE": "Мы удалили {{message}}.", + "ERROR_DELETE": "Мы не смогли удалить {{message}}", + "DEFAULT_DELETE_MESSAGE": "приглашение на {{email}}" + }, + "DEFAULT_VALUES": { + "LABEL_POINTS": "Значения по умолчанию для выбора очков", + "LABEL_US": "Значение по умолчанию для статуса ПИ", + "LABEL_TASK_STATUS": "Значение по умолчанию для статуса задачи", + "LABEL_PRIORITY": "Значение по умолчанию для выбора приоритета", + "LABEL_SEVERITY": "Значение важности по умолчанию", + "LABEL_ISSUE_TYPE": "Значение по умолчанию для типа проблемы", + "LABEL_ISSUE_STATUS": "Значение по умолчанию для статуса проблемы" + }, + "STATUS": { + "PLACEHOLDER_WRITE_STATUS_NAME": "Укажите название для нового статуса" + }, + "TYPES": { + "PLACEHOLDER_WRITE_NAME": "Введите имя нового элемента" + }, + "US_STATUS": { + "ACTION_ADD_STATUS": "Добавить новый статус", + "IS_ARCHIVED_COLUMN": "В архиве?", + "WIP_LIMIT_COLUMN": "Лимит текущей работы", + "PLACEHOLDER_WRITE_NAME": "Укажите название для нового статуса" + }, + "MENU": { + "TITLE": "Админ", + "PROJECT": "Проект", + "ATTRIBUTES": "Атрибуты", + "MEMBERS": "Участники", + "PERMISSIONS": "Разрешения", + "INTEGRATIONS": "Интеграции", + "PLUGINS": "Плагины" + }, + "SUBMENU_PROJECT_ATTRIBUTES": { + "TITLE": "Атрибуты" + }, + "SUBMENU_PROJECT_VALUES": { + "STATUS": "Статус", + "POINTS": "Очки", + "PRIORITIES": "Приоритет", + "SEVERITIES": "Степени важности", + "TYPES": "Типы", + "CUSTOM_FIELDS": "Собственные поля" + }, + "SUBMENU_PROJECT_PROFILE": { + "TITLE": "Профиль проекта" + }, + "SUBMENU_ROLES": { + "TITLE": "Роли", + "ACTION_NEW_ROLE": "+ Новая роль", + "TITLE_ACTION_NEW_ROLE": "Добавить новую роль" + }, + "SUBMENU_THIDPARTIES": { + "TITLE": "Сервисы" + } + }, + "USER": { + "PROFILE": { + "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", + "EDIT": "Изменить профиль", + "FOLLOW": "Следить", + "PROJECTS": "Проекты", + "CLOSED_US": "Закрытые ПИ", + "CONTACTS": "Контакты", + "REPORT": "Пожаловаться", + "ACTIVITY_TAB": "Вкладка Активность", + "PROJECTS_TAB": "Вкладка Проекты", + "CONTACTS_TAB": "Вкладка Контакты", + "FAVORITES_TAB": "Вкладка с Избранным", + "CONTACTS_EMPTY": "{{username}} ещё не имеет контактов", + "CURRENT_USER_CONTACTS_EMPTY": "У вас пока нет контактов", + "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "Люди, с которыми вы работаете в Taiga, будут отмечены как ваши контакты автоматически", + "PROJECTS_EMPTY": "{{username}} пока не имеет проектов" + }, + "PROFILE_SIDEBAR": { + "TITLE": "Ваш профиль", + "DESCRIPTION": "Люди могут видеть всё что Вы делаете и всё над чем Вы работаете. Вы также можете добавить краткую биографию.", + "ADD_INFO": "Изменить Ваши данные" + } + }, + "PROJECT": { + "PAGE_TITLE": "{{projectName}}", + "WELCOME": "Добро пожаловать", + "SECTION_PROJECTS": "Проекты", + "HELP": "Реорганизуйте свои проекты так чтобы часто используемые были бы наверху.
Первые 10 проектов будут находится вверху списка проектов.", + "PRIVATE": "Закрытый проект", + "STATS": { + "PROJECT": "проекта
очки", + "DEFINED": "заданные
очки", + "ASSIGNED": "назначенные
очки", + "CLOSED": "закрытые
очки" + }, + "SECTION": { + "SEARCH": "Поиск", + "TIMELINE": "График работ", + "BACKLOG": "Список задач", + "KANBAN": "Kanban", + "ISSUES": "Проблемы", + "WIKI": "Wiki", + "TEAM": "Команда", + "MEETUP": "Созвониться", + "ADMIN": "Админ" + }, + "NAVIGATION": { + "SECTION_TITLE": "Ваши проекты", + "PLACEHOLDER_SEARCH": "Искать в...", + "ACTION_CREATE_PROJECT": "Создать проект", + "ACTION_IMPORT_PROJECT": "Импортировать проект", + "SEE_MORE_PROJECTS": "Смотрите другие проекты", + "TITLE_CREATE_PROJECT": "Создать проект", + "TITLE_IMPORT_PROJECT": "Импортировать проект", + "TITLE_PRVIOUS_PROJECT": "Показать предыдущие проекты", + "TITLE_NEXT_PROJECT": "Показать следующие проекты", + "HELP_TITLE": "Страница поддержки Taiga", + "HELP": "Помощь", + "FEEDBACK_TITLE": "Оставить отзыв", + "FEEDBACK": "Обратная связь", + "NOTIFICATIONS_TITLE": "Настроить уведомления", + "NOTIFICATIONS": "Уведомления", + "ORGANIZATIONS_TITLE": "Редактировать Ваши организации", + "ORGANIZATIONS": "Настроить организации", + "SETTINGS_TITLE": "Редактировать настройки", + "SETTINGS": "Настройки", + "VIEW_PROFILE_TITLE": "Посмотреть профиль", + "VIEW_PROFILE": "Посмотреть профиль", + "EDIT_PROFILE_TITLE": "Править свой профиль", + "EDIT_PROFILE": "Править профиль", + "CHANGE_PASSWORD_TITLE": "Изменить пароль", + "CHANGE_PASSWORD": "Изменить пароль", + "DASHBOARD_TITLE": "Рабочий стол", + "DISCOVER_TITLE": "Найти проекты в тренде", + "DISCOVER": "Найти", + "ACTION_REORDER": "Можно перетаскивать мышкой" + }, + "IMPORT": { + "TITLE": "Импорт проекта", + "UPLOADING_FILE": "Загрузить свалочный файл", + "DESCRIPTION": "Этот процесс может занять некоторое время. Пожалуйста, сохраняйте это окно открытым.", + "ASYNC_IN_PROGRESS_TITLE": "Oompa Loompas импортирует ваш проект", + "ASYNC_IN_PROGRESS_MESSAGE": "Этот процесс может занять несколько минут
Мы отправим вам email, когда всё будет готово", + "UPLOAD_IN_PROGRESS_MESSAGE": "Загружено {{uploadedSize}} размера {{totalSize}}", + "ERROR": "У Oompa Loompas возникли проблемы при импорте резервной копии. Попробуйте еще раз.", + "ERROR_TOO_MANY_REQUEST": "Извините, Oompa Loompas очень загружен сейчас. Повторите через несколько минут.", + "ERROR_MESSAGE": "У Oompa Loompas возникли проблемы при импорте резервной копии: {{error_message}}", + "ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) это слишком много для наших Умпа-Лумп, попробуйте еще раз с размером меньшим, чем ({{maxFileSize}})", + "SYNC_SUCCESS": "Импорт проекта выполнен успешно" + } + }, + "LIGHTBOX": { + "DELETE_ACCOUNT": { + "SECTION_NAME": "Удалить аккаунт", + "CONFIRM": "Вы уверены, что хотите удалить ваш аккаунт?", + "SUBTITLE": "Мы будем скучать по вам! :-(", + "NEWSLETTER_LABEL_TEXT": "Я больше не хочу получать вашу новостную рассылку" + }, + "DELETE_PROJECT": { + "TITLE": "Удалить проект", + "QUESTION": "Вы уверены, что хотите удалить данный проект?", + "SUBTITLE": "Все данные проекта (истории от пользователей, задачи, проблемы, спринты и вики страницы) будут утрачены! :-(", + "CONFIRM": "Да, я уверен" + }, + "ASSIGNED_TO": { + "SELECT": "Назначить", + "SEARCH": "Найти пользователей" + }, + "ADD_MEMBER": { + "TITLE": "Новый участник", + "HELP_TEXT": "Если пользователи уже зарегистрированы в Тайге они добавятся автоматически. В противном случае им будет отправлено приглашение." + }, + "CREATE_ISSUE": { + "TITLE": "Добавить проблему" + }, + "FEEDBACK": { + "TITLE": "Расскажи что-нибудь...", + "COMMENT": "... ошибки, предложения, что-нибудь клёвое... или даже Ваш самый страшный кошмар с Taiga", + "ACTION_SEND": "Оставить отзыв" + }, + "SEARCH": { + "TITLE": "Поиск", + "PLACEHOLDER_SEARCH": "Что вы ищете?" + }, + "ADD_EDIT_SPRINT": { + "TITLE": "Новый спринт", + "PLACEHOLDER_SPRINT_NAME": "Название спринта", + "PLACEHOLDER_SPRINT_START": "Начало - примерно", + "PLACEHOLDER_SPRINT_END": "Окончание - примерно", + "ACTION_DELETE_SPRINT": "Вы уверены, что хотите удалить данный спринт?", + "TITLE_ACTION_DELETE_SPRINT": "удалить спринт", + "LAST_SPRINT_NAME": "последний этап sprint - {{lastSprint}} ;-) " + }, + "CREATE_EDIT_TASK": { + "TITLE": "Новая задача", + "PLACEHOLDER_SUBJECT": "Название задачи", + "PLACEHOLDER_STATUS": "Статус задачи", + "OPTION_UNASSIGNED": "Не назначено", + "PLACEHOLDER_SHORT_DESCRIPTION": "Введите краткое описание", + "ACTION_EDIT": "Редактировать задачу" + }, + "CREATE_EDIT_US": { + "TITLE": "Новая ПИ", + "PLACEHOLDER_DESCRIPTION": "Пожалуйста, добавьте описание, чтобы другие лучше поняли эту ПИ", + "NEW_US": "Новая пользовательская история", + "EDIT_US": "Изменить пользовательскую историю" + }, + "DELETE_SPRINT": { + "TITLE": "Удалить спринт" + }, + "CREATE_MEMBER": { + "PLACEHOLDER_INVITATION_TEXT": "(Необязательно) Добавьте персональный текст в приглашение. Скажите что-нибудь приятное вашим новым участникам ;-)", + "PLACEHOLDER_TYPE_EMAIL": "Укажите e-mail" + } + }, + "US": { + "PAGE_TITLE": "{{userStorySubject}} - История от Пользователя {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Статус: {{userStoryStatus }}. Выполнено {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} из {{userStoryTotalTasks}} задач). Очки: {{userStoryPoints}}. Описание: {{userStoryDescription}}", + "SECTION_NAME": "Детали пользовательских историй", + "LINK_TASKBOARD": "Панель задач", + "TITLE_LINK_TASKBOARD": "Перейти к панели задач", + "TOTAL_POINTS": "всего", + "ADD": "+ Добавить Пользовательскую Историю", + "ADD_BULK": "Добавить несколько Историй от Пользователей пакетно", + "PROMOTED": "Эта ПИ была сформирована из Проблемы:", + "TITLE_LINK_GO_TO_ISSUE": "Перейти к проблеме", + "EXTERNAL_REFERENCE": "Эта ПИ была создана из:", + "GO_TO_EXTERNAL_REFERENCE": "Перейти в начало", + "BLOCKED": "Эта пользовательская история заблокирована ", + "PREVIOUS": "предыдущая пользовательская история", + "NEXT": "следующая пользовательская история", + "TITLE_DELETE_ACTION": "Удалить пользовательскую историю", + "LIGHTBOX_TITLE_BLOKING_US": "Блокирующая ПИ", + "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} задач выполнено", + "ASSIGN": "Поручить пользовательскую историю", + "NOT_ESTIMATED": "Не оценено", + "TOTAL_US_POINTS": "Всего очков за ПИ", + "FIELDS": { + "TEAM_REQUIREMENT": "Требование от Команды", + "CLIENT_REQUIREMENT": "Требование клиента", + "FINISH_DATE": "Дата завершения" + } + }, + "COMMENTS": { + "DELETED_INFO": "Комментарий удален {{user}} {{date}}", + "TITLE": "Комментарии", + "COMMENT": "Комментарий", + "TYPE_NEW_COMMENT": "Добавить комментарий", + "SHOW_DELETED": "Показать удаленный комментарий", + "HIDE_DELETED": "Скрыть удаленный комментарий", + "RESTORE": "Показать удаленный комментарий" + }, + "ACTIVITY": { + "SHOW_ACTIVITY": "Показать действия", + "DATETIME": "ДД МММ ГГГГ ЧЧ:мм", + "SHOW_MORE": "+ Показать предыдущие записи (ещё {{showMore}})", + "TITLE": "Действия", + "REMOVED": "удален", + "ADDED": "добавлено", + "US_POINTS": "ПИ очки ({{name}})", + "NEW_ATTACHMENT": "новое вложение", + "DELETED_ATTACHMENT": "удаленное вложение", + "UPDATED_ATTACHMENT": "обновлено приложение {{filename}}", + "DELETED_CUSTOM_ATTRIBUTE": "удалить атрибут", + "SIZE_CHANGE": "Сделано {size, plural, one{изменение} other{# изменений}}", + "VALUES": { + "YES": "да", + "NO": "нет", + "EMPTY": "пусто", + "UNASSIGNED": "нет ответственного" + }, + "FIELDS": { + "SUBJECT": "название", + "NAME": "имя", + "DESCRIPTION": "описание", + "CONTENT": "контент", + "STATUS": "cтатус", + "IS_CLOSED": "закрыто", + "FINISH_DATE": "дата окончания", + "TYPE": "тип", + "PRIORITY": "приоритет", + "SEVERITY": "важность", + "ASSIGNED_TO": "назначено на", + "WATCHERS": "наблюдатели", + "MILESTONE": "спринт", + "USER_STORY": "пользовательская история", + "PROJECT": "проект", + "IS_BLOCKED": "заблокирован", + "BLOCKED_NOTE": "Пояснение блокировки", + "POINTS": "очков", + "CLIENT_REQUIREMENT": "требование клиента", + "TEAM_REQUIREMENT": "требование команды", + "IS_IOCAINE": "- иокаин", + "TAGS": "тэги", + "ATTACHMENTS": "Вложения", + "IS_DEPRECATED": "рекомендовано", + "ORDER": "порядок", + "BACKLOG_ORDER": "порядок списка задач", + "SPRINT_ORDER": "порядок спринтов", + "KANBAN_ORDER": "порядок kanban", + "TASKBOARD_ORDER": "порядок панели задач", + "US_ORDER": "порядок ПИ" + } + }, + "BACKLOG": { + "PAGE_TITLE": "Список задач - {{projectName}}", + "PAGE_DESCRIPTION": "Список задач с историями от пользователей и спринтами проекта {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Список задач", + "MOVE_US_TO_CURRENT_SPRINT": "Перейти к текущему спринту", + "SHOW_FILTERS": "Показать фильтры", + "SHOW_TAGS": "Показать теги", + "EMPTY": "Ваш список задач пуст!", + "CREATE_NEW_US": "Создать новую ПИ", + "CREATE_NEW_US_EMPTY_HELP": "Возможно будет лучше создать пользовательскую историю?", + "EXCESS_OF_POINTS": "Избыток очков", + "PENDING_POINTS": "Текущие очки", + "CLOSED_POINTS": "закрыта", + "COMPACT_SPRINT": "Компактный Спринт", + "GO_TO_TASKBOARD": "Перейти на панель задач: {{::name}}", + "EDIT_SPRINT": "Изменить Спринт", + "TOTAL_POINTS": "всего", + "STATUS_NAME": "Статус", + "SORTABLE_FILTER_ERROR": "Вы не можете перетаскивать на список задач, когда фильтры открыты", + "DOOMLINE": "Рамки Проекта [Крайний срок]", + "CHART": { + "XAXIS_LABEL": "Спринты", + "YAXIS_LABEL": "Очки", + "OPTIMAL": "Оптимальное число очков для работы по спринту \"{{sprintName}}\" должно быть {{value}}", + "REAL": "Реальные очки для работы по спринту \"{{sprintName}}\" - {{value}}", + "INCREMENT_TEAM": "Для спринта \"{{sprintName}}\" очки увеличены на {{value}} засчёт требований от команды", + "INCREMENT_CLIENT": "Для спринта \"{{sprintName}}\" очки увеличены на {{value}} засчёт требований от клиентов" + }, + "TAGS": { + "TOGGLE": "Переключить видимость тэга", + "SHOW": "Показать теги", + "HIDE": "Скрыть тэги" + }, + "TABLE": { + "COLUMN_US": "Истории от Пользователей", + "TITLE_COLUMN_POINTS": "Выберите вид для Роли" + }, + "SPRINT_SUMMARY": { + "TOTAL_POINTS": "всего
очков", + "COMPLETED_POINTS": "получено
очков", + "OPEN_TASKS": "открыть
задачи", + "CLOSED_TASKS": "завершённые
задачи", + "IOCAINE_DOSES": "иокаина
дозы", + "SHOW_STATISTICS_TITLE": "Показать статистику", + "TOGGLE_BAKLOG_GRAPH": "Показать/Скрыть график решения проблем" + }, + "SUMMARY": { + "PROJECT_POINTS": "проектные
очки", + "DEFINED_POINTS": "определено
очков", + "CLOSED_POINTS": "закрытые
очки", + "POINTS_PER_SPRINT": "очков на /
спринт" + }, + "FILTERS": { + "TOGGLE": "Переключить видимость фильтров", + "TITLE": "Фильтры", + "REMOVE": "Сбросить фильтры", + "HIDE": "Спрятать фильтры", + "SHOW": "Показать фильтры", + "FILTER_CATEGORY_STATUS": "Статус", + "FILTER_CATEGORY_TAGS": "Тэги" + }, + "SPRINTS": { + "TITLE": "СПРИНТЫ", + "DATE": "ДД МММ ГГГГ", + "LINK_TASKBOARD": "Панель задач Спринта", + "TITLE_LINK_TASKBOARD": "Перейти к Панели Задач \"{{name}}\"", + "NUMBER_SPRINTS": "
спринты", + "TITLE_ACTION_NEW_SPRINT": "+ Новый спринт", + "ACTION_NEW_SPRINT": "+ Новый спринт", + "ACTION_SHOW_CLOSED_SPRINTS": "Показать закрытые спринты", + "ACTION_HIDE_CLOSED_SPRINTS": "Спрятать закрытые спринты" + } + }, + "ERROR": { + "TEXT1": "Что-то случилось, Oompa Loompas работает над этим.", + "TEXT2": "Попробуйте обновить страницу чуть позже.", + "NOT_FOUND": "Не найдено", + "NOT_FOUND_TEXT": "Ошибка 404. Страница не найдена.", + "PERMISSION_DENIED": "Доступ закрыт", + "PERMISSION_DENIED_CODE": "Ошибка 403.", + "VERSION_ERROR": "Кто-то в Тайге изменил это раньше вас и Умпа-Лумпы не могут применить ваши изменения. Пожалуйста обновите страницу (Внимание! При обновлении страницы текущие правки будут утеряны) и внесите правки еще раз." + }, + "TASKBOARD": { + "PAGE_TITLE": "{{sprintName}} - панель задач спринта - {{projectName}}", + "PAGE_DESCRIPTION": "Спринт {{sprintName}} (с {{startDate}} по {{endDate}}) проекта {{projectName}}. Выполнено {{completedPercentage}}% ({{completedPoints}} из {{totalPoints}} очков). Открытые задачи: {{openTasks}} из {{totalTasks}}.", + "SECTION_NAME": "Панель задач", + "TITLE_ACTION_ADD": "Добавить новую Задачу", + "TITLE_ACTION_ADD_BULK": "Добавить новые задачи пакетно", + "TITLE_ACTION_ASSIGN": "Назначить задачу", + "TITLE_ACTION_EDIT": "Редактировать задачу", + "TABLE": { + "COLUMN": "Пользовательская история", + "TITLE_ACTION_FOLD": "Свернуть колонку", + "TITLE_ACTION_UNFOLD": "Развернуть колонку", + "TITLE_ACTION_FOLD_ROW": "Свернуть ряд", + "TITLE_ACTION_UNFOLD_ROW": "Развернуть ряд", + "FIELD_POINTS": "очков", + "ROW_UNASSIGED_TASKS_TITLE": "Не назначенные задачи" + }, + "CHARTS": { + "XAXIS_LABEL": "Дней", + "YAXIS_LABEL": "Очки", + "OPTIMAL": "Оптимальное количество очков для работы на день {{formattedDate}}: {{roundedValue}}", + "REAL": "Реальные очки для работы на день: {{formattedDate}} - {{roundedValue}}", + "DATE": "ДД МММ ГГГГ" + } + }, + "TASK": { + "PAGE_TITLE": "{{taskSubject}} - Задача {{taskRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Статус: {{taskStatus }}. Описание: {{taskDescription}}", + "SECTION_NAME": "Детали задачи", + "LINK_TASKBOARD": "Панель задач", + "TITLE_LINK_TASKBOARD": "Перейти к панели задач", + "PLACEHOLDER_SUBJECT": "Укажите новое название задачи", + "TITLE_SELECT_STATUS": "Статус", + "OWNER_US": "Эта задача принадлежит:", + "TITLE_LINK_GO_OWNER": "Перейти к пользовательской истории", + "ORIGIN_US": "Эта задача была создана из", + "TITLE_LINK_GO_ORIGIN": "Перейти к пользовательской истории", + "BLOCKED": "Эта задача заблокирована", + "PREVIOUS": "предыдущая задача", + "NEXT": "следующая задача", + "TITLE_DELETE_ACTION": "Удалить задачу", + "LIGHTBOX_TITLE_BLOKING_TASK": "Блокирующее задание", + "FIELDS": { + "MILESTONE": "Спринт", + "USER_STORY": "Пользовательская история", + "IS_IOCAINE": "- иокаин" + }, + "ACTION_IOCAINE": "иокаин", + "TITLE_ACTION_IOCAINE": "Чувствуете, что задание берет верх над вами? Дайте другим знать об этом, нажав на \"Иокаин\", когда редактируете задание. Возможно стать неуязвимым к этому (выдуманному) смертельном яду, потребляя небольшие количества время от времени, так же как возможно стать лучше в том, что вы делаете, временами беря на себя дополнительные препятствия!" + }, + "NOTIFICATION": { + "OK": "Всё хорошо", + "WARNING": "Упс, что-то случилось...", + "WARNING_TEXT": "Oompa Loompas сказал, что ваши изменения не сохранились!", + "SAVED": "Oompa Loompas сохранил изменения!", + "CLOSE": "закрыть уведомление", + "MAIL": "Уведомления почтой", + "ASK_DELETE": "Вы уверены, что хотите удалить?" + }, + "CANCEL_ACCOUNT": { + "TITLE": "Аннулировать ваш аккаунт", + "SUBTITLE": "Жаль, что вы покидаете taiga, надеемся, вам здесь понравилось :)", + "PLACEHOLDER_INPUT_TOKEN": "идентификатор аннулирования аккаунта", + "ACTION_LEAVING": "Да, я ухожу!", + "SUCCESS": "Oompa Loompas удалил ваш аккаунт" + }, + "CHANGE_EMAIL_FORM": { + "TITLE": "Изменить e-mail", + "SUBTITLE": "Ещё один клик и Ваш email будет обновлён!", + "PLACEHOLDER_INPUT_TOKEN": "изменить идентификатор email", + "ACTION_CHANGE_EMAIL": "изменить почту", + "SUCCESS": "Oompa Loompas обновил ваш e-mail" + }, + "ISSUES": { + "PAGE_TITLE": "Проблемы - {{projectName}}", + "PAGE_DESCRIPTION": "Панель проблем проекта {{projectName}}: {{projectDescription}}", + "LIST_SECTION_NAME": "Проблемы", + "SECTION_NAME": "Детали проблемы", + "ACTION_NEW_ISSUE": "+НОВАЯ ПРОБЛЕМА", + "ACTION_PROMOTE_TO_US": "Повысить до пользовательской истории", + "PLACEHOLDER_FILTER_NAME": "Введите название фильтра и нажмите \"ввод\"", + "PROMOTED": "Эта проблема была переделана в ПИ", + "EXTERNAL_REFERENCE": "Эта проблема была создана из:", + "GO_TO_EXTERNAL_REFERENCE": "Перейти в начало", + "BLOCKED": "Эта проблема заблокирована", + "TITLE_PREVIOUS_ISSUE": "предыдущая проблема", + "TITLE_NEXT_ISSUE": "следующая проблема", + "ACTION_DELETE": "Удалить проблему", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Блокирующая проблема", + "FIELDS": { + "PRIORITY": "Приоритет", + "SEVERITY": "Важность", + "TYPE": "Тип" + }, + "CONFIRM_PROMOTE": { + "TITLE": "Превратить эту проблему в новую история от пользователя", + "MESSAGE": "Вы уверены, что хотите создать новую ПИ из этой проблемы?" + }, + "FILTERS": { + "TITLE": "Фильтры", + "INPUT_SEARCH_PLACEHOLDER": "Название ссылки", + "TITLE_ACTION_SEARCH": "Поиск", + "ACTION_SAVE_CUSTOM_FILTER": "сохранить как специальный фильтр", + "BREADCRUMB": "Фильтры", + "TITLE_BREADCRUMB": "Фильтры", + "CATEGORIES": { + "TYPE": "Тип", + "STATUS": "Статус", + "SEVERITY": "Важность", + "PRIORITIES": "Приоритет", + "TAGS": "Тэги", + "ASSIGNED_TO": "Назначено", + "CREATED_BY": "Создано", + "CUSTOM_FILTERS": "Собственные фильтры" + }, + "CONFIRM_DELETE": { + "TITLE": "Удалить фильтр", + "MESSAGE": "специальный фильтр '{{customFilterName}}'" + } + }, + "TABLE": { + "COLUMNS": { + "TYPE": "Тип", + "SEVERITY": "Важность", + "PRIORITY": "Приоритет", + "SUBJECT": "Тема", + "STATUS": "Статус", + "CREATED": "Создан", + "ASSIGNED_TO": "Назначено" + }, + "TITLE_ACTION_CHANGE_STATUS": "Изменить статус", + "TITLE_ACTION_ASSIGNED_TO": "Назначено", + "EMPTY": { + "TITLE": "Нет проблем для отчёта :-)", + "SUBTITLE": "Вы нашли проблему?", + "ACTION_CREATE_ISSUE": "Создать новую проблему" + } + } + }, + "ISSUE": { + "PAGE_TITLE": "{{issueSubject}} - Проблема {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Статус: {{issueStatus }}. Тип: {{issueType}}, Приоритет: {{issuePriority}}. Важность: {{issueSeverity}}. Описание: {{issueDescription}}" + }, + "KANBAN": { + "PAGE_TITLE": "Kanban - {{projectName}}", + "PAGE_DESCRIPTION": "Панель kanban, с Историями от Пользователей для проекта {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Kanban", + "TITLE_ACTION_FOLD": "Свернуть колонку", + "TITLE_ACTION_UNFOLD": "Развернуть колонку", + "TITLE_ACTION_FOLD_CARDS": "Свернуть карточки", + "TITLE_ACTION_UNFOLD_CARDS": "Развернуть карточки", + "TITLE_ACTION_ADD_US": "Добавить Пользовательскую Историю", + "TITLE_ACTION_ADD_BULK": "Добавить пакетно", + "ACTION_SHOW_ARCHIVED": "Показать архивные", + "ACTION_HIDE_ARCHIVED": "Спрятать архив", + "HIDDEN_USER_STORIES": "Истории от Пользователей в этом статусе скрыты по умолчанию", + "ARCHIVED": "Вы заархивировали", + "UNDO_ARCHIVED": "Для отмены надо перетащить и сбросить ещё раз" + }, + "SEARCH": { + "PAGE_TITLE": "Поиск - {{projectName}}", + "PAGE_DESCRIPTION": "Ищите что угодно, задачи, истории от пользователей, проблемы и вики-страницы, в проекте {{projectName}}: {{projectDescription}}", + "FILTER_USER_STORIES": "Истории от Пользователей", + "FILTER_ISSUES": "Проблемы", + "FILTER_TASKS": "Задачи", + "FILTER_WIKI": "Вики страницы", + "PLACEHOLDER_SEARCH": "Искать в...", + "TITLE_ACTION_SEARCH": "поиск", + "EMPTY_TITLE": "Кажется, по вашему запросу ничего не найдено.", + "EMPTY_DESCRIPTION": "Попробуйте одну из вкладок выше и запустите поиск ещё раз" + }, + "TEAM": { + "PAGE_TITLE": "Команда - {{projectName}}", + "PAGE_DESCRIPTION": "Панель команды показывает всех участников проекта {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Команда", + "APP_TITLE": "КОМАНДА - {{projectName}}", + "PLACEHOLDER_INPUT_SEARCH": "Искать по имени", + "COLUMN_MR_WOLF": "Мр. Вульф", + "EXPLANATION_COLUMN_MR_WOLF": "Решёные проблемы", + "COLUMN_IOCAINE": "Употребляющий иокаин", + "EXPLANATION_COLUMN_IOCAINE": "потреблено доз иокаина", + "COLUMN_CERVANTES": "Сервантес", + "EXPLANATION_COLUMN_CERVANTES": "Отредактировано вики-страниц", + "COLUMN_BUG_HUNTER": "Охотник за ошибками", + "EXPLANATION_COLUMN_BUG_HUNTER": "Сообщенные проблемы", + "COLUMN_NIGHT_SHIFT": "Ночная смена", + "EXPLANATION_COLUMN_NIGHT_SHIFT": "Задача закрыта", + "COLUMN_TOTAL_POWER": "Могущество", + "EXPLANATION_COLUMN_TOTAL_POWER": "Всего очков", + "SECTION_TITLE_TEAM": "Команда", + "SECTION_FILTER_ALL": "Все", + "CONFIRM_LEAVE_PROJECT": "Вы уверены, что хотите покинуть данный проект?", + "ACTION_LEAVE_PROJECT": "Покинуть проект" + }, + "USER_SETTINGS": { + "AVATAR_MAX_SIZE": "[макс. размер: {{maxFileSize}}]", + "MENU": { + "SECTION_TITLE": "Настройки пользователя", + "USER_PROFILE": "Профиль пользователя", + "CHANGE_PASSWORD": "Изменить пароль", + "EMAIL_NOTIFICATIONS": "Уведомления почтой" + }, + "NOTIFICATIONS": { + "SECTION_NAME": "Уведомления почтой", + "COLUMN_PROJECT": "Проект", + "COLUMN_RECEIVE_ALL": "Получать Всё", + "COLUMN_ONLY_INVOLVED": "Только задействованные", + "COLUMN_NO_NOTIFICATIONS": "Уведомлений нет", + "OPTION_ALL": "Все", + "OPTION_INVOLVED": "Вовлечен", + "OPTION_NONE": "Нет" + }, + "POPOVER": { + "USER_PROFILE": "Профиль пользователя", + "CHANGE_PASSWORD": "Изменить пароль", + "NOTIFICATIONS": "Уведомления", + "FEEDBACK": "Обратная связь", + "TITLE_AVATAR": "Настройки пользователя" + } + }, + "USER_PROFILE": { + "IMAGE_HELP": "Изображение будет отмасштабировано до 80x80px.
", + "ACTION_CHANGE_IMAGE": "Изменить", + "ACTION_USE_GRAVATAR": "Испольвать аватар из gravatar", + "ACTION_DELETE_ACCOUNT": "Удалить аккаунт", + "CHANGE_EMAIL_SUCCESS": "Проверьте входящие письма!
Мы послали письмо на ваш аккаунт
с инструкциями по установке вашего нового адреса.", + "CHANGE_PHOTO": "Изменить фото", + "FIELD": { + "USERNAME": "Имя пользователя", + "EMAIL": "Email", + "FULL_NAME": "Полное имя", + "PLACEHOLDER_FULL_NAME": "Установите ваше полное имя (например, Игорь Николаев)", + "BIO": "Биография (не более 210 символов)", + "PLACEHOLDER_BIO": "Расскажите нам что-нибудь о себе", + "LANGUAGE": "Язык", + "LANGUAGE_DEFAULT": "-- использовать язык по умолчанию --", + "THEME": "Тема", + "THEME_DEFAULT": "-- использовать тему по умолчанию --" + } + }, + "WIZARD": { + "SECTION_TITLE_CHOOSE_TEMPLATE": "Выберете шаблон", + "CHOOSE_TEMPLATE_TEXT": "Какой шаблон лучше всего подойдет для Вашего проекта?", + "SECTION_TITLE_CREATE_PROJECT": "Создать проект", + "CREATE_PROJECT_TEXT": "Свежий и чистый! Так здóрово!", + "PROGRESS_TEMPLATE_SELECTION": "Выбор шаблона", + "PROGRESS_NAME_DESCRIPTION": "Название и описание" + }, + "WIKI": { + "PAGE_TITLE": "{{wikiPageName}} - Вики - {{projectName}}", + "PAGE_DESCRIPTION": "Последнее редактирование: {{lastModifiedDate}} ({{totalEditions}} - всего правок) Контент: {{ wikiPageContent }}", + "DATETIME": "ДД МММ ГГГГ ЧЧ:мм", + "PLACEHOLDER_PAGE": "Создать вики страницу", + "REMOVE": "Удалить эту вики страницу", + "DELETE_LIGHTBOX_TITLE": "Удалить вики страницу", + "NAVIGATION": { + "SECTION_NAME": "Ссылки", + "ACTION_ADD_LINK": "Добавить ссылку" + }, + "SUMMARY": { + "TIMES_EDITED": "раз
отредактировано", + "LAST_EDIT": "последняя
правка", + "LAST_MODIFICATION": "последнее изменение" + } + }, + "HINTS": { + "SECTION_NAME": "Подсказка", + "LINK": "Чтобы узать как пользовать этим — посетите нашу страницу поддержки.", + "LINK_TITLE": "Посетить нашу страницу поддержки", + "HINT1_TITLE": "Вы знали что можно импортировать и экспортировать проекты?", + "HINT1_TEXT": "Это позволяет вам собирать данные из одной Taiga и копировать в другую.", + "HINT2_TITLE": "Вы знали что можно создавать собственные поля?", + "HINT2_TEXT": "Команды теперь могут создавать специальные поля в качестве гибкого средства для ввода специфических данных их конкретного процесса работы", + "HINT3_TITLE": "Отсортируйте ваши проекты по признаку, наиболее важному для вас", + "HINT3_TEXT": "Главные 10 проектов будут доступны непосредственно из верхней панели", + "HINT4_TITLE": "Вы забыли над чем работали?", + "HINT4_TEXT": "Не переживайте, на вашем рабочем столе вы найдёте ваши активные задачи, проблемы, и истории от пользователей в том порядке, в котором вы над ними работали." + }, + "TIMELINE": { + "UPLOAD_ATTACHMENT": "{{username}} приложил новый файл к {{obj_name}}", + "US_CREATED": "{{username}} создал новую ПИ {{obj_name}} в {{project_name}}", + "ISSUE_CREATED": "{{username}} указал на новую проблему {{obj_name}} в {{project_name}}", + "TASK_CREATED": "{{username}} создал новую задачу {{obj_name}} в {{project_name}}", + "TASK_CREATED_WITH_US": "{{username}} создал новую задачу {{obj_name}} в {{project_name}}, которая принадлежит Задаче от Пользователя {{us_name}}", + "WIKI_CREATED": "{{username}} создал новую вики-страницу {{obj_name}} в {{project_name}}", + "MILESTONE_CREATED": "{{username}} создал новый спринт {{obj_name}} в {{project_name}}", + "NEW_PROJECT": "{{username}} создал проект {{project_name}}", + "MILESTONE_UPDATED": "{{username}} обновил спринт {{obj_name}}", + "US_UPDATED": "{{username}} обновил атрибут \"{{field_name}}\" ПИ {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" для ПИ {{obj_name}} на {{new_value}}", + "US_UPDATED_POINTS": "{{username}} установил очки для '{{role_name}}' для ПИ {{obj_name}} на {{new_value}}", + "ISSUE_UPDATED": "{{username}} обновил атрибут \"{{field_name}}\" проблемы {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" проблемы {{obj_name}} на {{new_value}}", + "TASK_UPDATED": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}} на {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}} на {{new_value}}", + "TASK_UPDATED_WITH_US": "{{username}} изменил атрибут \"{{field_name}}\" задачи {{obj_name}}, которая принадлежит ПИ {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}}, которая принадлежит ПИ {{us_name}}, на {{new_value}}", + "WIKI_UPDATED": "{{username}} обновил вики-страницу {{obj_name}}", + "NEW_COMMENT_US": "{{username}} прокомментировал ПИ {{obj_name}}", + "NEW_COMMENT_ISSUE": "{{username}} прокомментировал проблему {{obj_name}}", + "NEW_COMMENT_TASK": "{{username}} прокомментировал задачу {{obj_name}}", + "NEW_MEMBER": "У {{project_name}} появился новый участник", + "US_ADDED_MILESTONE": "{{username}} добавил ПИ {{obj_name}} для {{sprint_name}}", + "US_REMOVED_FROM_MILESTONE": "{{username}} добавил ПИ {{obj_name}} к списку задач", + "BLOCKED": "{{username}} заблокировал {{obj_name}}", + "UNBLOCKED": "{{username}} разблокировал {{obj_name}}", + "NEW_USER": "{{username}} присоединился к Taiga" + } +} \ No newline at end of file From 55b2cad4872b709b948b0c8006604b61e6918637 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 29 Jul 2015 12:23:24 +0200 Subject: [PATCH 085/403] set isCreatedRightNow to false after the save scope apply after ESC --- app/coffee/modules/common/attachments.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/coffee/modules/common/attachments.coffee b/app/coffee/modules/common/attachments.coffee index 6f269935..1102715d 100644 --- a/app/coffee/modules/common/attachments.coffee +++ b/app/coffee/modules/common/attachments.coffee @@ -283,6 +283,7 @@ AttachmentDirective = ($template, $compile, $translate) -> saveAttachment = -> attachment.description = $el.find("input[name='description']").val() attachment.is_deprecated = $el.find("input[name='is-deprecated']").prop("checked") + attachment.isCreatedRightNow = false $scope.$apply -> $ctrl.updateAttachment(attachment).then -> @@ -297,7 +298,7 @@ AttachmentDirective = ($template, $compile, $translate) -> if event.keyCode == 13 saveAttachment() else if event.keyCode == 27 - render(attachment, false) + $scope.$apply -> render(attachment, false) $el.on "click", "a.editable-settings.icon-delete", (event) -> event.preventDefault() From 774d77201ff8e58d5636188fd70f88348df9b2ea Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 21 Jul 2015 09:51:22 +0200 Subject: [PATCH 086/403] enhancement 1503 - caps lock warning --- CHANGELOG.md | 1 + app/coffee/modules/admin/lightboxes.coffee | 2 +- app/coffee/modules/common.coffee | 53 +++++++++++++++++++ app/locales/locale-en.json | 1 + .../change-password-from-recovery-form.jade | 6 +-- .../includes/modules/forgot-form.jade | 2 +- .../modules/invitation-login-form.jade | 6 +-- .../modules/invitation-register-form.jade | 8 +-- app/partials/includes/modules/login-form.jade | 5 +- .../includes/modules/register-form.jade | 6 +-- app/partials/user/user-change-password.jade | 6 +-- app/partials/user/user-profile.jade | 4 +- app/styles/core/forms.scss | 3 ++ 13 files changed, 81 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fdcaf68..99576e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ ### Misc - Improve performance: Show cropped images in timelines. +- Caps lock warning in login and register form. - Lots of small and not so small bugfixes. diff --git a/app/coffee/modules/admin/lightboxes.coffee b/app/coffee/modules/admin/lightboxes.coffee index 9b43695c..8ba5fb77 100644 --- a/app/coffee/modules/admin/lightboxes.coffee +++ b/app/coffee/modules/admin/lightboxes.coffee @@ -41,7 +41,7 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading, lightboxService, template = _.template("""
- data-required="true" <% } %> data-type="email" />
diff --git a/app/coffee/modules/common.coffee b/app/coffee/modules/common.coffee index abe17a6c..9688ae31 100644 --- a/app/coffee/modules/common.coffee +++ b/app/coffee/modules/common.coffee @@ -229,3 +229,56 @@ Template = ($templateCache) -> } module.factory("$tgTemplate", ["$templateCache", Template]) + +############################################################################# +## Permission directive, hide elements when necessary +############################################################################# + +Capslock = ($translate) -> + link = ($scope, $el, $attrs) -> + open = false + + warningIcon = $('
') + .addClass('icon') + .addClass('icon-capslock') + .attr('title', $translate.instant('COMMON.CAPSLOCK_WARNING')) + + hideIcon = () -> + warningIcon.fadeOut () -> + open = false + + $(this).remove() + + showIcon = () -> + return if open + + top = $el.position().top + left = $el.position().left + $el.outerWidth(true) + + warningIcon.css({ + display: 'none', + position: 'absolute', + top: top, + left: left - 25 + lineHeight: $el.outerHeight() + 'px', + marginLeft: 0 + }) + + warningIcon + .insertAfter($el) + .fadeIn() + + open = true + + $el.on 'keyup.capslock', (e) -> + if $el.val() == $el.val().toLowerCase() + hideIcon() + else + showIcon() + + $scope.$on "$destroy", -> + $el.off('.capslock') + + return {link:link} + +module.directive("tgCapslock", ["$translate", Capslock]) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index a09bff42..72cf19ae 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "an external user", "GENERIC_ERROR": "One of our Oompa Loompas says {{error}}.", "IOCAINE_TEXT": "Feeling a bit overwhelmed by a task? Make sure others know about it by clicking on Iocaine when editing a task. It's possible to become immune to this (fictional) deadly poison by consuming small amounts over time just as it's possible to get better at what you do by occasionally taking on extra challenges!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "This value seems to be invalid.", "TYPE_EMAIL": "This value should be a valid email.", diff --git a/app/partials/includes/modules/change-password-from-recovery-form.jade b/app/partials/includes/modules/change-password-from-recovery-form.jade index 3c64b179..8a2f3c44 100644 --- a/app/partials/includes/modules/change-password-from-recovery-form.jade +++ b/app/partials/includes/modules/change-password-from-recovery-form.jade @@ -6,15 +6,15 @@ div.change-password-form-container(tg-change-password-from-recovery) form fieldset.token-change-password(ng-hide="tokenInParams") - input(type="text", name="token", ng-model="data.token", data-required="true", + input(type="text", tg-capslock, name="token", ng-model="data.token", data-required="true", placeholder="{{'CHANGE_PASSWORD_RECOVERY_FORM.PLACEHOLDER_RECOVER_PASSWORD_TOKEN' | translate}}") a.get-token(href="", tg-nav="forgot-password", title="{{'CHANGE_PASSWORD_RECOVERY_FORM.TITLE_LINK_NEED_TOKEN' | translate}}", translate="CHANGE_PASSWORD_RECOVERY_FORM.LINK_NEED_TOKEN") fieldset - input(type="password", name="password", id="password", ng-model="data.password", + input(type="password", tg-capslock, name="password", id="password", ng-model="data.password", data-required="true", placeholder="{{'CHANGE_PASSWORD_RECOVERY_FORM.PLACEHOLDER_NEW_PASSWORD' | translate}}") fieldset - input(type="password", name="password2", id="password2", ng-model="data.password2", + input(type="password", tg-capslock, name="password2", id="password2", ng-model="data.password2", data-required="true", data-equalto="#password", placeholder="{{'CHANGE_PASSWORD_RECOVERY_FORM.PLACEHOLDER_RE_TYPE_NEW_PASSWORD' | translate}}") fieldset button.button-change-password.button-gray.submit-button(type="submit", title="{{'CHANGE_PASSWORD_RECOVERY_FORM.ACTION_RESET_PASSWORD' | translate}}", translate="CHANGE_PASSWORD_RECOVERY_FORM.ACTION_RESET_PASSWORD") diff --git a/app/partials/includes/modules/forgot-form.jade b/app/partials/includes/modules/forgot-form.jade index ce276287..b98647be 100644 --- a/app/partials/includes/modules/forgot-form.jade +++ b/app/partials/includes/modules/forgot-form.jade @@ -6,7 +6,7 @@ div.forgot-form-container(tg-forgot-password) form(ng-submit="ctrl.submit()") fieldset - input(type="text", name="username", ng-model="data.username", data-required="true", + input(type="text", tg-capslock, name="username", ng-model="data.username", data-required="true", placeholder="{{'FORGOT_PASSWORD_FORM.PLACEHOLDER_FIELD' | translate}}") fieldset button.button-gray.submit-button.button-forgot(type="submit", title="{{'FORGOT_PASSWORD_FORM.ACTION_RESET_PASSWORD' | translate}}", translate="FORGOT_PASSWORD_FORM.ACTION_RESET_PASSWORD") diff --git a/app/partials/includes/modules/invitation-login-form.jade b/app/partials/includes/modules/invitation-login-form.jade index b089d1c0..1e9ffbef 100644 --- a/app/partials/includes/modules/invitation-login-form.jade +++ b/app/partials/includes/modules/invitation-login-form.jade @@ -2,13 +2,13 @@ form.login-form p.form-header(translate="LOGIN_COMMON.HEADER") fieldset - input(type="text", name="username", ng-model="dataLogin.username", data-required="true", + input(type="text", tg-capslock, name="username", ng-model="dataLogin.username", data-required="true", placeholder="{{'LOGIN_COMMON.PLACEHOLDER_AUTH_NAME' | translate}}") fieldset.login-password - input(type="password", name="password", ng-model="dataLogin.password", data-required="true", + input(type="password", tg-capslock, name="password", ng-model="dataLogin.password", data-required="true", placeholder="{{'LOGIN_COMMON.PLACEHOLDER_AUTH_PASSWORD' | translate}}") - a.forgot-pass(href="", tg-nav="forgot-password", + a.forgot-pass(href="", tg-nav="forgot-password", tg-capslock, title="{{'LOGIN_COMMON.TITLE_LINK_FORGOT_PASSWORD' | translate}}", translate="LOGIN_COMMON.LINK_FORGOT_PASSWORD") diff --git a/app/partials/includes/modules/invitation-register-form.jade b/app/partials/includes/modules/invitation-register-form.jade index 4eeace6a..6db3e055 100644 --- a/app/partials/includes/modules/invitation-register-form.jade +++ b/app/partials/includes/modules/invitation-register-form.jade @@ -1,7 +1,7 @@ form.register-form p.form-header(translate="REGISTER_FORM.TITLE") fieldset - input(type="text", name="username", ng-model="dataRegister.username", + input(type="text", tg-capslock, name="username", ng-model="dataRegister.username", data-required="true", data-maxlength="255", data-regexp="^[\\w.-]+$", placeholder="{{'REGISTER_FORM.PLACEHOLDER_NAME' | translate}}") @@ -11,13 +11,13 @@ form.register-form placeholder="{{'REGISTER_FORM.PLACEHOLDER_FULL_NAME' | translate}}") fieldset - input(type="text", name="email", ng-model="dataRegister.email", + input(type="text", tg-capslock, name="email", ng-model="dataRegister.email", data-required="true", data-maxlength="255", placeholder="{{'REGISTER_FORM.PLACEHOLDER_EMAIL' | translate}}") fieldset - input(type="password", name="password", ng-model="dataRegister.password", data-required="true", - placeholder="{{'REGISTER_FORM.PLACEHOLDER_PASSWORD' | translate}}") + input(type="password", tg-capslock, name="password", ng-model="dataRegister.password", data-required="true", + placeholder="{{'REGISTER_FORM.PLACEHOLDER_PASSWORD' | translate}}") fieldset a.button-register.button-blackish.submit-button(type="submit", title="{{'REGISTER_FORM.ACTION_SIGN_UP' | translate}}", translate="REGISTER_FORM.ACTION_SIGN_UP") diff --git a/app/partials/includes/modules/login-form.jade b/app/partials/includes/modules/login-form.jade index 18bfa351..ecfa6956 100644 --- a/app/partials/includes/modules/login-form.jade +++ b/app/partials/includes/modules/login-form.jade @@ -1,10 +1,11 @@ div.login-form-container(tg-login) form.login-form fieldset - input(type="text", name="username", data-required="true", + input(type="text", tg-capslock, name="username", data-required="true", placeholder="{{'LOGIN_COMMON.PLACEHOLDER_AUTH_NAME' | translate}}") + fieldset.login-password - input(type="password", name="password", data-required="true", + input(type="password", tg-capslock, name="password", data-required="true", placeholder="{{'LOGIN_COMMON.PLACEHOLDER_AUTH_PASSWORD' | translate}}") // This should be hidden when focus on pass a.forgot-pass(href="", tg-nav="forgot-password", title="{{'LOGIN_COMMON.TITLE_LINK_FORGOT_PASSWORD' | translate}}", translate="LOGIN_COMMON.LINK_FORGOT_PASSWORD") diff --git a/app/partials/includes/modules/register-form.jade b/app/partials/includes/modules/register-form.jade index 0b955507..62b89c9c 100644 --- a/app/partials/includes/modules/register-form.jade +++ b/app/partials/includes/modules/register-form.jade @@ -1,7 +1,7 @@ div.register-form-container(tg-register) form.register-form fieldset - input(type="text", name="username", ng-model="data.username", + input(type="text", name="username", ng-model="data.username", tg-capslock, data-required="true", data-maxlength="255", data-regexp="^[\\w.-]+$", placeholder="{{'REGISTER_FORM.PLACEHOLDER_NAME' | translate}}") @@ -11,12 +11,12 @@ div.register-form-container(tg-register) placeholder="{{'REGISTER_FORM.PLACEHOLDER_FULL_NAME' | translate}}") fieldset - input(type="text", name="email", ng-model="data.email", + input(type="text", name="email", ng-model="data.email", tg-capslock, data-required="true", data-maxlength="255", placeholder="{{'REGISTER_FORM.PLACEHOLDER_EMAIL' | translate}}") fieldset - input(type="password", name="password", ng-model="data.password", + input(type="password", name="password", ng-model="data.password", tg-capslock, data-required="true", data-minlength="4", placeholder="{{'REGISTER_FORM.PLACEHOLDER_PASSWORD' | translate}}") diff --git a/app/partials/user/user-change-password.jade b/app/partials/user/user-change-password.jade index f2d6df51..633e467e 100644 --- a/app/partials/user/user-change-password.jade +++ b/app/partials/user/user-change-password.jade @@ -15,12 +15,12 @@ div.wrapper(tg-user-change-password, ng-controller="UserChangePasswordController form fieldset label(for="current-password", translate="CHANGE_PASSWORD.FIELD_CURRENT_PASSWORD") - input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_CURRENT_PASSWORD' | translate}}", id="current-password", ng-model="currentPassword") + input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_CURRENT_PASSWORD' | translate}}", id="current-password", ng-model="currentPassword", tg-capslock) fieldset label(for="new-password", translate="CHANGE_PASSWORD.FIELD_NEW_PASSWORD") - input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_NEW_PASSWORD' | translate}}", id="new-password", ng-model="newPassword1") + input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_NEW_PASSWORD' | translate}}", id="new-password", ng-model="newPassword1", tg-capslock) fieldset label(for="retype-password", translate="CHANGE_PASSWORD.FIELD_RETYPE_PASSWORD") - input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_RETYPE_PASSWORD' | translate}}", id="retype-password", ng-model="newPassword2") + input(type="password", placeholder="{{'CHANGE_PASSWORD.PLACEHOLDER_RETYPE_PASSWORD' | translate}}", id="retype-password", ng-model="newPassword2", tg-capslock) fieldset button.button-green.submit-button(type="submit", title="{{'COMMON.SAVE' | translate}}", translate="COMMON.SAVE") diff --git a/app/partials/user/user-profile.jade b/app/partials/user/user-profile.jade index dd94f565..6c698965 100644 --- a/app/partials/user/user-profile.jade +++ b/app/partials/user/user-profile.jade @@ -31,14 +31,14 @@ div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl", div.data fieldset label(for="username", translate="USER_PROFILE.FIELD.USERNAME") - input(type="text", name="username", id="username", + input(type="text", name="username", id="username", tg-capslock, placeholder="{{'USER_PROFILE.FIELD.USERNAME' | translate}}", ng-model="user.username", data-required="true", data-maxlength="255", data-regexp="^[\\w.-]+$") fieldset label(for="email", translate="USER_PROFILE.FIELD.EMAIL") - input(type="text", name="email", id="email", + input(type="text", name="email", id="email", tg-capslock, placeholder="{{'USER_PROFILE.FIELD.EMAIL' | translate}}", ng-model="user.email", data-type="email", data-required="true", data-maxlength="255") diff --git a/app/styles/core/forms.scss b/app/styles/core/forms.scss index 22b5e476..708a362d 100644 --- a/app/styles/core/forms.scss +++ b/app/styles/core/forms.scss @@ -9,6 +9,9 @@ fieldset { top: 31px; } } + .icon-capslock { + cursor: pointer; + } } input[type="text"], From 9c809f08480c069ead0df734fd570d5081a3470b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Wed, 5 Aug 2015 12:35:22 +0200 Subject: [PATCH 087/403] [i18n] Update locales --- app/locales/locale-ca.json | 1 + app/locales/locale-de.json | 3 ++- app/locales/locale-es.json | 1 + app/locales/locale-fi.json | 1 + app/locales/locale-fr.json | 1 + app/locales/locale-nl.json | 1 + app/locales/locale-pl.json | 1 + app/locales/locale-ru.json | 1 + app/locales/locale-zh-hant.json | 1 + 9 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index de0f018e..a59b268f 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "un usuari extern", "GENERIC_ERROR": "Un Oompa Loompas diu {{error}}.", "IOCAINE_TEXT": "Un poc saturat per una tasca? Fes-ho saber als teus companys clicant a Iocaina quan edites la tasca. Es possible ser inmune a aquesta (fictícia) poció mortal consumint xicotetes dòsis poc a poc, així com es possible millorar amb xicotets nous desafiaments!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Aquest valor pareix invàlid.", "TYPE_EMAIL": "Deu ser un correu vàlid.", diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 20725740..e0cb5c03 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "ein externer Benutzer", "GENERIC_ERROR": "Eins unserer Helferlein sagt {{error}}.", "IOCAINE_TEXT": "Fühlen Sie sich von einer Aufgabe etwas erdrückt? Stellen Sie sicher, dass andere davon erfahren, indem Sie auf Locaine klicken, wenn Sie eine Aufgabe ändern. Es ist möglich, gegen dieses (fiktive) tödliche Gift immun zu werden, indem man kleine Mengen über einen Zeitraum hinweg einnimmt. Genauso, wie es möglich ist, besser in dem zu werden, was man tut, indem man gelegentlich zusätzliche Herausforderungen annimmt! ", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Dieser Wert scheint ungültig zu sein. ", "TYPE_EMAIL": "Dieser Wert sollte eine gültige E-Mail Adresse enthalten.", @@ -343,7 +344,7 @@ "DESCRIPTION": "Geben Sie eine kurze Beschreibung ein", "DEPRECATED": "(verworfen)", "DEPRECATED_FILE": "Verworfen?", - "ADD": "Add new attachment. {{maxFileSizeMsg}}", + "ADD": "Neuen Anhang hinzufügen. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. Größe: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ verworfene Anhänge zeigen", "HIDE_DEPRECATED": "- verworfene Anhänge verbergen", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index cad4e01a..16499420 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "un usuario externo", "GENERIC_ERROR": "Uno de nuestros Oompa Loompas dice {{error}}.", "IOCAINE_TEXT": "¿Te sientes fuera de tu zona de confort en una tarea? Asegúrate de que los demás están al tanto de ello, marca el check de la Iocaína al editar una tarea. Igual eu era posible llegar a ser inmune a este veneno mortal a base de consumir pequeñas dosis a lo largo del tiempo, es posible conseguir mejor en lo que estás haciendo si afrontas de vez en cuando esta clase de retos!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Este valor parece inválido.", "TYPE_EMAIL": "El valor debe ser un email.", diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index 973388d7..c84bc717 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "ulkoinen käyttäjä", "GENERIC_ERROR": "Oompa Loompas havaitsivat virheen {{error}}.", "IOCAINE_TEXT": "Jos tehtävä ahdistaa, merkitse se myrkylliseksi. Ajan mittaa pieninä annoksina saattaa kastokykysi myrkkyä vastaan parantua.", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Tämä arvo vaikuttaa virheelliseltä.", "TYPE_EMAIL": "Tämän pitäisi olla toimiva sähköpostiosoite.", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 56624146..47467b16 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "um usuário externo", "GENERIC_ERROR": "L'un de nos Oompa Loompas dit {{error}}.", "IOCAINE_TEXT": "Vous vous sentez un peu submergé par une tâche ? Soyez certains d'en informer les autres en cliquant su Iocaine lors de la modification de la tâche. Il est possible de s'immuniser contre ce poison (fictif) en consommant de petites quantités en heures supplémentaires, tout comme il est possible de s'améliorer en acceptant parfois de nouveaux défis !", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Cette valeur semble être invalide.", "TYPE_EMAIL": "Cette valeur devrait être une adresse courriel valide.", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 8faa9c17..926bd535 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "een extern gebruiker", "GENERIC_ERROR": "Een van onze Oempa Loempa's zegt {{error}}.", "IOCAINE_TEXT": "Voel je je wat overweldigd door een taak? Zorg ervoor dat anderen dit weten door op Iocaine te klikken bij het wijzigen van een taak. Je kan stapsgewijs immuun worden tegen dit (fictioneel) dodelijk gif door kleine dosissen op te nemen. Net zoals je beter kan worden in wat je doet door af en toe een extra uitdaging aan te gaan!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Deze waarde lijkt ongeldig te zijn", "TYPE_EMAIL": "Deze waarde moet een geldig emailadres bevatten", diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index ce720f0b..bec3d665 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "zewnętrzny użytkownik", "GENERIC_ERROR": "Umpa Lumpa mówi {{error}}.", "IOCAINE_TEXT": "Czujesz się trochę przytłoczony zadaniem? Daj znać innym klikając na ikonę Iokainy podczas edycji zadania. Jest szansa, że staniesz się odporny na tą (fikcyjną ;) ) śmiertelną truciznę biorąc małe dawki. Z pewnością jednak da Ci ona dodatkowego kopa, który pomoże w pokonaniu nowego wyzwania i staniu się lepszym w tym co robisz!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Nieprawidłowa wartość", "TYPE_EMAIL": "Podaj prawidłowy adres email.", diff --git a/app/locales/locale-ru.json b/app/locales/locale-ru.json index f8ef6be4..97ea2734 100644 --- a/app/locales/locale-ru.json +++ b/app/locales/locale-ru.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "внешний пользователь", "GENERIC_ERROR": "Один из Умпа-Лумп говорит {{error}}.", "IOCAINE_TEXT": "Чувствуете, что задание берет верх над вами? Дайте другим знать об этом, нажав на \"Иокаин\", когда редактируете задание. Возможно стать неуязвимым к этому (выдуманному) смертельном яду, потребляя небольшие количества время от времени, так же как возможно стать лучше в том, что вы делаете, временами беря на себя дополнительные препятствия!", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Кажется, это значение некорректно.", "TYPE_EMAIL": "Это значение должно быть корректным email-адресом.", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 0354b9b8..523bee9a 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -36,6 +36,7 @@ "EXTERNAL_USER": "外部使用者", "GENERIC_ERROR": "我們的系統指出{{error}}.", "IOCAINE_TEXT": "感到任務的不堪負荷?確認其它人在編輯任務時知道此狀況,可以點選Iocaine。它可能會成為免疫的致命狀況,只要長期小量消耗,但如果你只是偶而挑戰它可有助表現。", + "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "該數值似乎為無效", "TYPE_EMAIL": "該電子郵件應為有效地址", From 4961f2689639e3350d2e825813e149bf0a90a352 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 6 Aug 2015 12:03:53 +0200 Subject: [PATCH 088/403] fix #3146 - filter active users in project team --- .../project/project.controller.coffee | 5 +++++ .../project/project.controller.spec.coffee | 21 +++++++++++++------ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/app/modules/projects/project/project.controller.coffee b/app/modules/projects/project/project.controller.coffee index 7d72f4cd..673df954 100644 --- a/app/modules/projects/project/project.controller.coffee +++ b/app/modules/projects/project/project.controller.coffee @@ -16,6 +16,11 @@ class ProjectController .getProjectBySlug(projectSlug) .then (project) => @.project = project + + members = @.project.get('members').filter (member) -> member.get('is_active') + + @.project = @.project.set('members', members) + @._setMeta(@.project) .catch (xhr) => diff --git a/app/modules/projects/project/project.controller.spec.coffee b/app/modules/projects/project/project.controller.spec.coffee index 8bd7aa5f..e450fdef 100644 --- a/app/modules/projects/project/project.controller.spec.coffee +++ b/app/modules/projects/project/project.controller.spec.coffee @@ -1,4 +1,4 @@ -describe "ProjectController", -> +describe.only "ProjectController", -> $controller = null $q = null provide = null @@ -69,6 +69,7 @@ describe "ProjectController", -> it "set local user", () -> project = Immutable.fromJS({ name: "projectName" + members: [] }) mocks.projectService.getProjectBySlug.withArgs("project-slug").promise().resolve(project) @@ -82,7 +83,8 @@ describe "ProjectController", -> $scope = $rootScope.$new() project = Immutable.fromJS({ name: "projectName" - description: "projectDescription" + description: "projectDescription", + members: [] }) mocks.translate.instant @@ -100,17 +102,24 @@ describe "ProjectController", -> done() ) - it "set local project variable", (done) -> + it "set local project variable with active members", (done) -> project = Immutable.fromJS({ - name: "projectName" + name: "projectName", + members: [ + {is_active: true}, + {is_active: true}, + {is_active: true}, + {is_active: false} + ] }) mocks.projectService.getProjectBySlug.withArgs("project-slug").promise().resolve(project) ctrl = $controller("Project") - setTimeout ( () -> - expect(ctrl.project).to.be.equal(project) + setTimeout (() -> + expect(ctrl.project.get('members').size).to.be.equal(3) + done() ) From 873ec2fbcc9227b35ba9f66c1452b983f3be3df1 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 6 Aug 2015 13:49:12 +0200 Subject: [PATCH 089/403] fix issue 3159 - fix timeline messages when move us's on backlog --- app/locales/locale-en.json | 1 + .../project/project.controller.spec.coffee | 2 +- .../user-timeline-item-type.service.coffee | 27 ++++++++++++------- .../user-timeline.service.coffee | 13 +++++++-- .../user-timeline.service.spec.coffee | 13 +++++---- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index 72cf19ae..f9f7d90d 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -1262,6 +1262,7 @@ "NEW_COMMENT_TASK": "{{username}} has commented in the task {{obj_name}}", "NEW_MEMBER": "{{project_name}} has a new member", "US_ADDED_MILESTONE": "{{username}} has added the US {{obj_name}} to {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} has added the US {{obj_name}} to the backlog", "BLOCKED": "{{username}} has blocked {{obj_name}}", "UNBLOCKED": "{{username}} has unblocked {{obj_name}}", diff --git a/app/modules/projects/project/project.controller.spec.coffee b/app/modules/projects/project/project.controller.spec.coffee index e450fdef..baa83fc6 100644 --- a/app/modules/projects/project/project.controller.spec.coffee +++ b/app/modules/projects/project/project.controller.spec.coffee @@ -1,4 +1,4 @@ -describe.only "ProjectController", -> +describe "ProjectController", -> $controller = null $q = null provide = null diff --git a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee index db2e20fa..df01a154 100644 --- a/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee +++ b/app/modules/user-timeline/user-timeline-item/user-timeline-item-type.service.coffee @@ -87,28 +87,35 @@ timelineType = (timeline, event) -> description: (timeline) -> return $(timeline.getIn(['data', 'comment_html'])).text() }, - { # UsToMilestone + { # UsMove check: (timeline, event) -> - if timeline.hasIn(['data', 'value_diff']) && - timeline.getIn(['data', 'value_diff', 'key']) == 'milestone' && + return timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'moveInBacklog' && + timeline.hasIn(['data', 'value_diff', 'value', 'backlog_order']) && event.type == 'change' - return timeline.getIn(['data', 'value_diff', 'value']).get(0) == null - - return false - key: 'TIMELINE.US_ADDED_MILESTONE', - translate_params: ['username', 'obj_name', 'sprint_name'] + key: 'TIMELINE.US_MOVED', + translate_params: ['username', 'obj_name'] }, { # UsToBacklog check: (timeline, event) -> if timeline.hasIn(['data', 'value_diff']) && - timeline.getIn(['data', 'value_diff', 'key']) == 'milestone' && + timeline.getIn(['data', 'value_diff', 'key']) == 'moveInBacklog' && event.type == 'change' - return timeline.getIn(['data', 'value_diff', 'value']).get(1) == null + + return timeline.getIn(['data', 'value_diff', 'value', 'milestone']).get(1) == null return false key: 'TIMELINE.US_REMOVED_FROM_MILESTONE', translate_params: ['username', 'obj_name'] }, + { # UsToMilestone + check: (timeline, event) -> + return timeline.hasIn(['data', 'value_diff']) && + timeline.getIn(['data', 'value_diff', 'key']) == 'moveInBacklog' && + event.type == 'change' + key: 'TIMELINE.US_ADDED_MILESTONE', + translate_params: ['username', 'obj_name', 'sprint_name'] + }, { # Blocked check: (timeline, event) -> if timeline.hasIn(['data', 'value_diff']) && diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee index ed82befb..5ba77b7b 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.coffee @@ -15,13 +15,15 @@ class UserTimelineService extends taiga.Service 'priority', 'type', 'attachments', - 'milestone', 'is_iocaine', 'content_diff', 'name', 'estimated_finish', 'estimated_start', - 'blocked' + # customs + 'blocked', + 'moveInBacklog', + 'milestone' ] _invalid: [ @@ -78,6 +80,8 @@ class UserTimelineService extends taiga.Service newdata = Immutable.List() response.get('data').forEach (item) -> + event_type = item.get('event_type').split(".") + data = item.get('data') values_diff = data.get('values_diff') @@ -86,6 +90,11 @@ class UserTimelineService extends taiga.Service if values_diff.has('is_blocked') values_diff = Immutable.Map({'blocked': values_diff}) + if values_diff.has('milestone') + values_diff = Immutable.Map({'moveInBacklog': values_diff}) + else if event_type[1] == 'milestone' + values_diff = Immutable.Map({'milestone': values_diff}) + values_diff.forEach (value, key) -> obj = Immutable.Map({ key: key, diff --git a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee index 64f2198c..11aae951 100644 --- a/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee +++ b/app/modules/user-timeline/user-timeline/user-timeline.service.spec.coffee @@ -74,7 +74,6 @@ describe "tgUserTimelineService", -> event_type: "xx.tt.create", data: { values_diff: { - "fake2": "xx", "milestone": "xx" } } @@ -157,10 +156,10 @@ describe "tgUserTimelineService", -> mocks.userTimelinePaginationSequence.generate = (config) -> return config.fetch().then (res) -> - expect(res.get('data').size).to.be.equal(14) + expect(res.get('data').size).to.be.equal(13) items = config.filter(res.get('data')) - expect(items.size).to.be.equal(5) + expect(items.size).to.be.equal(6) return true @@ -180,10 +179,10 @@ describe "tgUserTimelineService", -> mocks.userTimelinePaginationSequence.generate = (config) -> return config.fetch().then (res) -> - expect(res.get('data').size).to.be.equal(14) + expect(res.get('data').size).to.be.equal(13) items = config.filter(res.get('data')) - expect(items.size).to.be.equal(5) + expect(items.size).to.be.equal(6) return true @@ -203,10 +202,10 @@ describe "tgUserTimelineService", -> mocks.userTimelinePaginationSequence.generate = (config) -> return config.fetch().then (res) -> - expect(res.get('data').size).to.be.equal(14) + expect(res.get('data').size).to.be.equal(13) items = config.filter(res.get('data')) - expect(items.size).to.be.equal(5) + expect(items.size).to.be.equal(6) return true From ac9ddb3d4766abbdf67a2a73f74f415ade5ed073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Thu, 6 Aug 2015 16:42:22 +0200 Subject: [PATCH 090/403] [i18n] Update locales --- app/locales/locale-es.json | 2 +- app/locales/locale-pl.json | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index 16499420..b391b656 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -36,7 +36,7 @@ "EXTERNAL_USER": "un usuario externo", "GENERIC_ERROR": "Uno de nuestros Oompa Loompas dice {{error}}.", "IOCAINE_TEXT": "¿Te sientes fuera de tu zona de confort en una tarea? Asegúrate de que los demás están al tanto de ello, marca el check de la Iocaína al editar una tarea. Igual eu era posible llegar a ser inmune a este veneno mortal a base de consumir pequeñas dosis a lo largo del tiempo, es posible conseguir mejor en lo que estás haciendo si afrontas de vez en cuando esta clase de retos!", - "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", + "CAPSLOCK_WARNING": "¡Ten cuidado! Usted está escribiendo con mayúsculas y esta entrada es sensible a mayúsculas.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Este valor parece inválido.", "TYPE_EMAIL": "El valor debe ser un email.", diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index bec3d665..1490c16d 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -15,8 +15,8 @@ "COPY_TO_CLIPBOARD": "Skopiuj do schowka: Ctrl+C", "EDIT": "Edycja", "DRAG": "Przeciągnij", - "TAG_LINE": "Twoje zwinne, wolne, otwarto źródłowe narzędzie do zarządzania projektem", - "TAG_LINE_2": "KOCHAM TWÓJ PROJEKT", + "TAG_LINE": "Twoje zwinne, wolne, otwartoźródłowe narzędzie do zarządzania projektem", + "TAG_LINE_2": "Pokochaj swój projekt!", "BLOCK": "Blokuj", "UNBLOCK": "Odblokuj", "BLOCKED": "Zablokowane", @@ -36,7 +36,7 @@ "EXTERNAL_USER": "zewnętrzny użytkownik", "GENERIC_ERROR": "Umpa Lumpa mówi {{error}}.", "IOCAINE_TEXT": "Czujesz się trochę przytłoczony zadaniem? Daj znać innym klikając na ikonę Iokainy podczas edycji zadania. Jest szansa, że staniesz się odporny na tą (fikcyjną ;) ) śmiertelną truciznę biorąc małe dawki. Z pewnością jednak da Ci ona dodatkowego kopa, który pomoże w pokonaniu nowego wyzwania i staniu się lepszym w tym co robisz!", - "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", + "CAPSLOCK_WARNING": "UWAGA! Klawisz CAPSLOCK jest aktywny.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Nieprawidłowa wartość", "TYPE_EMAIL": "Podaj prawidłowy adres email.", @@ -285,13 +285,13 @@ "PAGE_DESCRIPTION": "Podaj twoją nazwę użytkownika lub e-mail by zdobyć nowe hasło i odzyskać dostęp do Taiga." }, "FORGOT_PASSWORD_FORM": { - "TITLE": "Ups, czy nie zapomniałaś swojego hasła?", + "TITLE": "Ups, czyżbyś zapomniał hasło?", "SUBTITLE": "Podaj twoją nazwę użytkownika lub e-mail by zdobyć nowe", "PLACEHOLDER_FIELD": "Login albo e-mail", "ACTION_RESET_PASSWORD": "Resetuj hasło", "LINK_CANCEL": "Nie, zabierz mnie stąd. Chyba je pamiętam.", - "SUCCESS": "Sprawdź swoją skrzynkę!
Wysłaliśmy Ci wiadomość e-mail z instrukcją jak ustawić nowe hasło", - "ERROR": "NAsze Umpa Lumpy twierdzą, że nie jesteś jeszcze zarejestrowany." + "SUCCESS": "Sprawdź swoją skrzynkę!
Wysłaliśmy Ci wiadomość e-mail z instrukcją jak ustawić nowe hasło.", + "ERROR": "Nasze Umpa Lumpy twierdzą, że nie jesteś jeszcze zarejestrowany." }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Zmień hasło - Taiga", From 3765a75b24b8630f22de3317d946405afd7dec77 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 7 Aug 2015 08:22:47 +0200 Subject: [PATCH 091/403] remove repeated code --- app/coffee/modules/backlog/main.coffee | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index ac50729c..56c139f2 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -359,9 +359,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F r = @scope.userstories.indexOf(us) @scope.userstories.splice(r, 1) - r = @scope.userstories.indexOf(us) - @scope.userstories.splice(r, 1) - # From sprint to sprint else us.milestone = newSprintId for us in usList From 0b31956888714fcf408537def7064104f59f6343 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 6 Aug 2015 10:07:30 +0200 Subject: [PATCH 092/403] fix issue #3136 behavior: - When you enter the first time the loader is open, I increase maximum open time to 15s. - On the first load the search page opens the first tab with content. - When you search in the left bar a loader appears on the input and your current tab doesn't change even if you don't have content in the tab. --- app/coffee/modules/common/loader.coffee | 7 ------ app/coffee/modules/search.coffee | 29 ++++++++++++++++++++----- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/app/coffee/modules/common/loader.coffee b/app/coffee/modules/common/loader.coffee index 4ebc0215..aebc6a30 100644 --- a/app/coffee/modules/common/loader.coffee +++ b/app/coffee/modules/common/loader.coffee @@ -77,13 +77,6 @@ Loader = ($rootscope) -> lastResponseDate = 0 autoClose = () -> - maxAuto = 5000 - timeoutAuto = setTimeout (() -> - pageLoaded() - - clearInterval(intervalAuto) - ), maxAuto - intervalAuto = setInterval (() -> if lastResponseDate && requestCount == 0 pageLoaded() diff --git a/app/coffee/modules/search.coffee b/app/coffee/modules/search.coffee index 661dedfd..8a2ce080 100644 --- a/app/coffee/modules/search.coffee +++ b/app/coffee/modules/search.coffee @@ -164,13 +164,22 @@ module.directive("tgSearchBox", SearchBoxDirective) SearchDirective = ($log, $compile, $templatecache, $routeparams, $location) -> linkTable = ($scope, $el, $attrs, $ctrl) -> + applyAutoTab = true + activeSectionName = "userstories" tabsDom = $el.find("section.search-filter") lastSeatchResults = null getActiveSection = (data) -> maxVal = 0 - selectedSectionName = null - selectedSectionData = null + selectedSection = {} + selectedSection.name = "userstories" + selectedSection.value = [] + + if !applyAutoTab + selectedSection.name = activeSectionName + selectedSection.value = data[activeSectionName] + + return selectedSection if data for name in ["userstories", "issues", "tasks", "wikipages"] @@ -178,14 +187,14 @@ SearchDirective = ($log, $compile, $templatecache, $routeparams, $location) -> if value.length > maxVal maxVal = value.length - selectedSectionName = name - selectedSectionData = value + selectedSection.name = name + selectedSection.value = value break; if maxVal == 0 - return {name: "userstories", value: []} + return selectedSection - return {name:selectedSectionName, value: selectedSectionData} + return selectedSection renderFilterTabs = (data) -> for name, value of data @@ -197,6 +206,9 @@ SearchDirective = ($log, $compile, $templatecache, $routeparams, $location) -> tabsDom.find("a.active").removeClass("active") tabsDom.find("li.#{section.name} a").addClass("active") + applyAutoTab = false + activeSectionName = section.name + templates = { issues: $templatecache.get("search-issues") tasks: $templatecache.get("search-tasks") @@ -221,8 +233,13 @@ SearchDirective = ($log, $compile, $templatecache, $routeparams, $location) -> $scope.$watch "searchResults", (data) -> lastSeatchResults = data + + return if !lastSeatchResults + activeSection = getActiveSection(data) + renderFilterTabs(data) + renderTableContent(activeSection) markSectionTabActive(activeSection) From 1456be633a87a97a2c4627cc5a032aefc5066edc Mon Sep 17 00:00:00 2001 From: Juanfran Date: Fri, 7 Aug 2015 14:18:18 +0200 Subject: [PATCH 093/403] fix lightbox transitions --- app/coffee/modules/common/lightboxes.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee index a5b5bff7..5756f2be 100644 --- a/app/coffee/modules/common/lightboxes.coffee +++ b/app/coffee/modules/common/lightboxes.coffee @@ -39,13 +39,14 @@ class LightboxService extends taiga.Service lightboxContent = $el.children().not(".close") lightboxContent.hide() - $el.css('display', 'flex') + @animationFrame.add -> + $el.css('display', 'flex') - @animationFrame.add => + @animationFrame.add -> $el.addClass("open") - @animationFrame.add -> - $el.find('input,textarea').first().focus() + @animationFrame.add -> + $el.find('input,textarea').first().focus() @animationFrame.add => lightboxContent.show() From 8538b267b8d789e40a8dcd22f7ec13fb8dbafaea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 10 Aug 2015 11:35:23 +0200 Subject: [PATCH 094/403] [i18n] Update locales --- app/locales/locale-ca.json | 1 + app/locales/locale-de.json | 1 + app/locales/locale-es.json | 1 + app/locales/locale-fi.json | 1 + app/locales/locale-fr.json | 1 + app/locales/locale-nl.json | 1 + app/locales/locale-pl.json | 3 ++- app/locales/locale-ru.json | 1 + app/locales/locale-zh-hant.json | 1 + 9 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index a59b268f..8c138982 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} has commented in the task {{obj_name}}", "NEW_MEMBER": "{{project_name}} has a new member", "US_ADDED_MILESTONE": "{{username}} has added the US {{obj_name}} to {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} has added the US {{obj_name}} to the backlog", "BLOCKED": "{{username}} has blocked {{obj_name}}", "UNBLOCKED": "{{username}} has unblocked {{obj_name}}", diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index e0cb5c03..93d919b2 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} schrieb einen Kommentar in der Aufgabe {{obj_name}}", "NEW_MEMBER": "{{project_name}} hat ein neues Mitglied", "US_ADDED_MILESTONE": "{{username}} fügte dem Sprint {{sprint_name}} die User-Story {{obj_name}} hinzu", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} fügte der Auftragsliste die User-Story {{obj_name}} hinzu", "BLOCKED": "{{username}} vermerkte die Blockierung von {{obj_name}}", "UNBLOCKED": "{{username}} hob die Blockierung von {{obj_name}} auf", diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index b391b656..b98ad82f 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} ha añadido un comentado en la tarea {{obj_name}}", "NEW_MEMBER": "{{project_name}} tiene un nuevo miembro", "US_ADDED_MILESTONE": "{{username}} ha añadido la historia {{obj_name}} a {{sprint_name}}", + "US_MOVED": "{{username}} ha movido la historia {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} ha añadido la historia {{obj_name}} al backlog", "BLOCKED": "{{username}} ha bloqueado {{obj_name}}", "UNBLOCKED": "{{username}} ha desbloqueado {{obj_name}}", diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index c84bc717..542d260e 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} has commented in the task {{obj_name}}", "NEW_MEMBER": "{{project_name}} has a new member", "US_ADDED_MILESTONE": "{{username}} has added the US {{obj_name}} to {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} has added the US {{obj_name}} to the backlog", "BLOCKED": "{{username}} has blocked {{obj_name}}", "UNBLOCKED": "{{username}} has unblocked {{obj_name}}", diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 47467b16..92c30f84 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} a commenté la tâche {{obj_name}}", "NEW_MEMBER": "{{project_name}} a un nouveau membre", "US_ADDED_MILESTONE": "{{username}} a ajouté le récit utilisateur {{obj_name}} à {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} a ajouté le récit utilisateur {{obj_name}} au carnet", "BLOCKED": "{{username}} a bloqué {{obj_name}}", "UNBLOCKED": "{{username}} a débloqué {{obj_name}}", diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 926bd535..1465eb3a 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} heeft gereageerd op de taak {{obj_name}}", "NEW_MEMBER": "{{project_name}} heeft een nieuw lid", "US_ADDED_MILESTONE": "{{username}} heeft de US {{obj_name}} toegevoegd aan {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} heeft de US {{obj_name}} toegevoegd aan de Backlog", "BLOCKED": "{{username}} heeft {{obj_name}} geblokkeerd", "UNBLOCKED": "{{username}} heeft {{obj_name}} gedeblokkeerd", diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index 1490c16d..2424b7ca 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -568,7 +568,7 @@ "COLUMN_ROLE": "Rola", "COLUMN_STATUS": "Status", "STATUS_ACTIVE": "Aktywny", - "STATUS_PENDING": "Niekatywny", + "STATUS_PENDING": "Nieaktywny", "DELETE_MEMBER": "Usuń członka", "SUCCESS_SEND_INVITATION": "Ponownie wysłano zaproszenie do '{{e-mail}}'.", "ERROR_SEND_INVITATION": "Zaproszenie nie zostało wysłane.", @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "Użytkownik {{username}} skomentował zadanie {{obj_name}}", "NEW_MEMBER": "Projekt {{project_name}} ma nowego członka", "US_ADDED_MILESTONE": "Użytkownik{{username}} dodał HU {{obj_name}} do {{sprint_name}}", + "US_MOVED": "{{username}} przeniósł historyjkę użytkownika {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "Użytkownik {{username}} dodał HU {{obj_name}} do backlogu", "BLOCKED": "Użytkownik {{username}} zablokował {{obj_name}}", "UNBLOCKED": "Użytkownik {{username}} odblokował {{obj_name}}", diff --git a/app/locales/locale-ru.json b/app/locales/locale-ru.json index 97ea2734..0f5531ad 100644 --- a/app/locales/locale-ru.json +++ b/app/locales/locale-ru.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} прокомментировал задачу {{obj_name}}", "NEW_MEMBER": "У {{project_name}} появился новый участник", "US_ADDED_MILESTONE": "{{username}} добавил ПИ {{obj_name}} для {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} добавил ПИ {{obj_name}} к списку задач", "BLOCKED": "{{username}} заблокировал {{obj_name}}", "UNBLOCKED": "{{username}} разблокировал {{obj_name}}", diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 523bee9a..859ffa28 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -1259,6 +1259,7 @@ "NEW_COMMENT_TASK": "{{username}} 評論了此任務{{obj_name}}", "NEW_MEMBER": "{{project_name}} 有新成員", "US_ADDED_MILESTONE": "{{username}} 增加使用者故事 {{obj_name}} 給 {{sprint_name}}", + "US_MOVED": "{{username}} has moved the US {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} 新增使用者故事 {{obj_name}} 到待辦工作優先列表", "BLOCKED": "{{username}} 封鎖了 {{obj_name}}", "UNBLOCKED": "{{username}} 解除了封鎖 {{obj_name}}", From de8500d515cfc4eadf07603400a52efb5cb4e3c1 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 3 Aug 2015 10:19:31 +0200 Subject: [PATCH 095/403] Removing descriptions from list API --- app/coffee/modules/admin/lightboxes.coffee | 8 +- .../modules/admin/project-profile.coffee | 26 +++--- app/coffee/modules/admin/third-parties.coffee | 24 +++--- app/coffee/modules/backlog/lightboxes.coffee | 8 +- app/coffee/modules/backlog/main.coffee | 20 ++++- app/coffee/modules/backlog/sprints.coffee | 8 +- app/coffee/modules/common/components.coffee | 28 ++++--- app/coffee/modules/common/confirm.coffee | 13 ++- app/coffee/modules/common/history.coffee | 11 ++- app/coffee/modules/common/lightboxes.coffee | 22 ++++-- app/coffee/modules/common/loading.coffee | 79 +++++++++++++++---- app/coffee/modules/feedback.coffee | 8 +- app/coffee/modules/issues/detail.coffee | 38 +++++---- app/coffee/modules/issues/lightboxes.coffee | 17 ++-- app/coffee/modules/issues/list.coffee | 10 ++- app/coffee/modules/kanban/main.coffee | 18 ++++- app/coffee/modules/projects/lightboxes.coffee | 9 ++- app/coffee/modules/related-tasks.coffee | 17 ++-- .../modules/taskboard/lightboxes.coffee | 14 ++-- app/coffee/modules/taskboard/main.coffee | 17 +++- app/coffee/modules/tasks/detail.coffee | 24 +++--- .../user-settings/change-password.coffee | 8 +- app/coffee/modules/userstories/detail.coffee | 50 ++++++------ app/coffee/modules/wiki/main.coffee | 9 ++- app/coffee/modules/wiki/nav.coffee | 10 ++- app/partials/common/history/history-base.jade | 2 +- .../includes/components/backlog-row.jade | 2 +- app/styles/components/kanban-task.scss | 5 ++ app/styles/components/taskboard-task.scss | 7 +- 29 files changed, 343 insertions(+), 169 deletions(-) diff --git a/app/coffee/modules/admin/lightboxes.coffee b/app/coffee/modules/admin/lightboxes.coffee index 8ba5fb77..5167fa8c 100644 --- a/app/coffee/modules/admin/lightboxes.coffee +++ b/app/coffee/modules/admin/lightboxes.coffee @@ -109,16 +109,18 @@ CreateMembersDirective = ($rs, $rootScope, $confirm, $loading, lightboxService, submit = debounce 2000, (event) => event.preventDefault() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() onSuccess = (data) -> - $loading.finish(submitButton) + currentLoading.finish() lightboxService.close($el) $confirm.notify("success") $rootScope.$broadcast("membersform:new:success") onError = (data) -> - $loading.finish(submitButton) + currentLoading.finish() lightboxService.close($el) $confirm.notify("error") $rootScope.$broadcast("membersform:new:error") diff --git a/app/coffee/modules/admin/project-profile.coffee b/app/coffee/modules/admin/project-profile.coffee index 97e9d1ac..4705fb45 100644 --- a/app/coffee/modules/admin/project-profile.coffee +++ b/app/coffee/modules/admin/project-profile.coffee @@ -114,11 +114,13 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje return if not form.validate() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.save($scope.project) promise.then -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("success") newUrl = $navurls.resolve("project-admin-project-profile-details", { project: $scope.project.slug @@ -131,7 +133,7 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje currentUserService.loadProjects() promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) @@ -158,15 +160,17 @@ ProjectDefaultValuesDirective = ($repo, $confirm, $loading) -> return if not form.validate() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.save($scope.project) promise.then -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("success") promise.then null, (data) -> - $loading.finish(target) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) @@ -193,19 +197,21 @@ ProjectModulesDirective = ($repo, $confirm, $loading, projectService) -> form = $el.find("form").checksley() return if not form.validate() - target = angular.element(".admin-functionalities a.button-green") - $loading.start(target) + target = angular.element(".admin-functionalities .submit-button") + currentLoading = $loading() + .target(target) + .start() promise = $repo.save($scope.project) promise.then -> - $loading.finish(target) + currentLoading.finish() $confirm.notify("success") $scope.$emit("project:loaded", $scope.project) projectService.fetchProject() promise.then null, (data) -> - $loading.finish(target) + currentLoading.finish() $confirm.notify("error", data._error_message) $el.on "submit", "form", (event) -> diff --git a/app/coffee/modules/admin/third-parties.coffee b/app/coffee/modules/admin/third-parties.coffee index 737a8144..7d36fc4c 100644 --- a/app/coffee/modules/admin/third-parties.coffee +++ b/app/coffee/modules/admin/third-parties.coffee @@ -454,15 +454,17 @@ GithubWebhooksDirective = ($repo, $confirm, $loading) -> return if not form.validate() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.saveAttribute($scope.github, "github") promise.then -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("success") promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) @@ -488,16 +490,18 @@ GitlabWebhooksDirective = ($repo, $confirm, $loading) -> return if not form.validate() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.saveAttribute($scope.gitlab, "gitlab") promise.then -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("success") $scope.$emit("project:modules:reload") promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) @@ -523,16 +527,18 @@ BitbucketWebhooksDirective = ($repo, $confirm, $loading) -> return if not form.validate() - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.saveAttribute($scope.bitbucket, "bitbucket") promise.then -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("success") $scope.$emit("project:modules:reload") promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) diff --git a/app/coffee/modules/backlog/lightboxes.coffee b/app/coffee/modules/backlog/lightboxes.coffee index cf952c4e..2915e19d 100644 --- a/app/coffee/modules/backlog/lightboxes.coffee +++ b/app/coffee/modules/backlog/lightboxes.coffee @@ -71,17 +71,19 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading, promise = $repo.save(newSprint) broadcastEvent = "sprintform:edit:success" - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise.then (data) -> - $loading.finish(submitButton) + currentLoading.finish() $scope.sprintsCounter += 1 if createSprint $rootscope.$broadcast(broadcastEvent, data) lightboxService.close($el) promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 56c139f2..8cd5d696 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -50,11 +50,12 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F "$tgNavUrls", "$tgEvents", "$tgAnalytics", - "$translate" + "$translate", + "$tgLoading" ] constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, - @location, @appMetaService, @navUrls, @events, @analytics, @translate) -> + @location, @appMetaService, @navUrls, @events, @analytics, @translate, @loading) -> bindMethods(@) @scope.sectionName = @translate.instant("BACKLOG.SECTION_NAME") @@ -488,8 +489,19 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @rootscope.$broadcast("filters:update") @.loadProjectStats() - editUserStory: (us) -> - @rootscope.$broadcast("usform:edit", us) + editUserStory: (projectId, ref, $event) -> + target = $($event.target) + + currentLoading = @loading() + .target(target) + .removeClasses("icon-edit") + .timeout(200) + .start() + + @rs.userstories.getByRef(projectId, ref).then (us) => + @rootscope.$broadcast("usform:edit", us) + + currentLoading.finish() deleteUserStory: (us) -> title = @translate.instant("US.TITLE_DELETE_ACTION") diff --git a/app/coffee/modules/backlog/sprints.coffee b/app/coffee/modules/backlog/sprints.coffee index 09127a7d..4db13c68 100644 --- a/app/coffee/modules/backlog/sprints.coffee +++ b/app/coffee/modules/backlog/sprints.coffee @@ -153,12 +153,16 @@ ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading, $translate) -> loadingElm = $("
") $el.after(loadingElm) + currentLoading = null + # Event Handlers $el.on "click", (event) -> event.preventDefault() excludeClosedSprints = not excludeClosedSprints - $loading.start(loadingElm) + currentLoading = $loading() + .target(loadingElm) + .start() if excludeClosedSprints $rootscope.$broadcast("backlog:unload-closed-sprints") @@ -169,7 +173,7 @@ ToggleExcludeClosedSprintsVisualization = ($rootscope, $loading, $translate) -> $el.off() $scope.$on "closed-sprints:reloaded", (ctx, sprints) => - $loading.finish(loadingElm) + currentLoading.finish() if sprints.length > 0 key = "BACKLOG.SPRINTS.ACTION_HIDE_CLOSED_SPRINTS" diff --git a/app/coffee/modules/common/components.coffee b/app/coffee/modules/common/components.coffee index a57a5972..bf9e1517 100644 --- a/app/coffee/modules/common/components.coffee +++ b/app/coffee/modules/common/components.coffee @@ -316,18 +316,20 @@ AssignedToDirective = ($rootscope, $confirm, $repo, $loading, $qqueue, $template save = $qqueue.bindAdd (userId) => $model.$modelValue.assigned_to = userId - $loading.start($el) + currentLoading = $loading() + .target($el) + .start() promise = $repo.save($model.$modelValue) promise.then -> - $loading.finish($el) + currentLoading.finish() $confirm.notify("success") renderAssignedTo($model.$modelValue) $rootscope.$broadcast("object:updated") promise.then null, -> $model.$modelValue.revert() $confirm.notify("error") - $loading.finish($el) + currentLoading.finish() return promise @@ -408,9 +410,12 @@ BlockButtonDirective = ($rootscope, $loading, $template) -> $el.on "click", ".item-unblock", (event) -> event.preventDefault() - $loading.start($el.find(".item-unblock")) + currentLoading = $loading() + .target($el.find(".item-unblock")) + .start() + finish = -> - $loading.finish($el.find(".item-unblock")) + currentLoading.finish() $rootscope.$broadcast("unblock", $model.$modelValue, finish) @@ -486,7 +491,9 @@ EditableSubjectDirective = ($rootscope, $repo, $confirm, $loading, $qqueue, $tem save = $qqueue.bindAdd (subject) => $model.$modelValue.subject = subject - $loading.start($el.find('.save-container')) + currentLoading = $loading() + .target($el.find('.save-container')) + .start() promise = $repo.save($model.$modelValue) promise.then -> @@ -497,7 +504,7 @@ EditableSubjectDirective = ($rootscope, $repo, $confirm, $loading, $qqueue, $tem promise.then null, -> $confirm.notify("error") promise.finally -> - $loading.finish($el.find('.save-container')) + currentLoading.finish() return promise @@ -571,7 +578,10 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, save = $qqueue.bindAdd (description) => $model.$modelValue.description = description - $loading.start($el.find('.save-container')) + currentLoading = $loading() + .target($el.find('.save-container')) + .start() + promise = $repo.save($model.$modelValue) promise.then -> $confirm.notify("success") @@ -581,7 +591,7 @@ EditableDescriptionDirective = ($rootscope, $repo, $confirm, $compile, $loading, promise.then null, -> $confirm.notify("error") promise.finally -> - $loading.finish($el.find('.save-container')) + currentLoading.finish() $el.on "mouseup", ".view-description", (event) -> # We want to dettect the a inside the div so we use the target and diff --git a/app/coffee/modules/common/confirm.coffee b/app/coffee/modules/common/confirm.coffee index fd877c4b..28851121 100644 --- a/app/coffee/modules/common/confirm.coffee +++ b/app/coffee/modules/common/confirm.coffee @@ -64,9 +64,12 @@ class ConfirmService extends taiga.Service el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) => event.preventDefault() target = angular.element(event.currentTarget) - @loading.start(target) + currentLoading = @loading() + .target(target) + .start() + defered.resolve (ok=true) => - @loading.finish(target) + currentLoading.finish() if ok @.hide(el) @@ -110,11 +113,13 @@ class ConfirmService extends taiga.Service el.on "click.confirm-dialog", "a.button-green", debounce 2000, (event) => event.preventDefault() target = angular.element(event.currentTarget) - @loading.start(target) + currentLoading = @loading() + .target(target) + .start() defered.resolve { selected: choicesField.val() finish: => - @loading.finish(target) + currentLoading.finish() @.hide(el) } diff --git a/app/coffee/modules/common/history.coffee b/app/coffee/modules/common/history.coffee index d056cc6c..ec2a438c 100644 --- a/app/coffee/modules/common/history.coffee +++ b/app/coffee/modules/common/history.coffee @@ -347,18 +347,21 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c $el.find(".comment-list").addClass("activeanimation") + currentLoading = $loading() + .target(target) + .start() + onSuccess = -> $rootScope.$broadcast("comment:new") $ctrl.loadHistory(type, objectId).finally -> - $loading.finish(target) + currentLoading.finish() onError = -> - $loading.finish(target) + currentLoading.finish() $confirm.notify("error") model = $scope.$eval($attrs.ngModel) - $loading.start(target) $ctrl.repo.save(model).then(onSuccess, onError) @@ -371,7 +374,7 @@ HistoryDirective = ($log, $loading, $qqueue, $template, $confirm, $translate, $c # Events - $el.on "click", ".add-comment input.button-green", debounce 2000, (event) -> + $el.on "click", ".add-comment button.button-green", debounce 2000, (event) -> event.preventDefault() target = angular.element(event.currentTarget) diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee index 5756f2be..c92c176b 100644 --- a/app/coffee/modules/common/lightboxes.coffee +++ b/app/coffee/modules/common/lightboxes.coffee @@ -179,7 +179,9 @@ BlockLightboxDirective = ($rootscope, $tgrepo, $confirm, lightboxService, $loadi block = $qqueue.bindAdd (item) => $model.$setViewValue(item) - $loading.start($el.find(".button-green")) + currentLoading = $loading() + .target($el.find(".button-green")) + .start() promise = $tgrepo.save($model.$modelValue) promise.then -> @@ -192,7 +194,7 @@ BlockLightboxDirective = ($rootscope, $tgrepo, $confirm, lightboxService, $loadi $model.$setViewValue(item) promise.finally -> - $loading.finish($el.find(".button-green")) + currentLoading.finish() lightboxService.close($el) $scope.$on "block", -> @@ -324,7 +326,9 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService, if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() if $scope.isNew promise = $repo.create("userstories", $scope.us) @@ -334,12 +338,12 @@ CreateEditUserstoryDirective = ($repo, $model, $rs, $rootScope, lightboxService, broadcastEvent = "usform:edit:success" promise.then (data) -> - $loading.finish(submitButton) + currentLoading.finish() lightboxService.close($el) $rootScope.$broadcast(broadcastEvent, data) promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) @@ -399,16 +403,18 @@ CreateBulkUserstoriesDirective = ($repo, $rs, $rootscope, lightboxService, $load if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $rs.userstories.bulkCreate($scope.new.projectId, $scope.new.statusId, $scope.new.bulk) promise.then (result) -> - $loading.finish(submitButton) + currentLoading.finish() $rootscope.$broadcast("usform:bulk:success", result) lightboxService.close($el) promise.then null, (data) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(data) if data._error_message $confirm.notify("error", data._error_message) diff --git a/app/coffee/modules/common/loading.coffee b/app/coffee/modules/common/loading.coffee index bb92f178..e2c0de6e 100644 --- a/app/coffee/modules/common/loading.coffee +++ b/app/coffee/modules/common/loading.coffee @@ -21,29 +21,78 @@ module = angular.module("taigaCommon") -class TgLoadingService extends taiga.Service - start: (target) -> - if not target.hasClass('loading') - target.data('loading-old-content', target.html()) - target.addClass('loading') - target.html("loading...") +TgLoadingService = -> + spinner = "loading..." - finish: (target) -> - if target.hasClass('loading') - oldContent = target.data('loading-old-content') - target.data('loading-old-content', null) - target.html(oldContent) - target.removeClass('loading') + return () -> + service = { + settings: { + target: null, + classes: [] + timeout: 0 + }, + target: (target) -> + service.settings.target = target -module.service("$tgLoading", TgLoadingService) + return service + removeClasses: (classess...) -> + service.settings.classes = classess + + return service + timeout: (timeout) -> + service.settings.timeout = timeout + + return service + + start: -> + target = service.settings.target + service.settings.classes.map (className) -> target.removeClass(className) + + # The loader is shown after that quantity of milliseconds + timeoutId = setTimeout (-> + if not target.hasClass('loading') + service.settings.oldContent = target.html() + + target.addClass('loading') + target.html(spinner) + ), service.settings.timeout + + service.settings.timeoutId = timeoutId + + return service + + finish: -> + target = service.settings.target + timeoutId = service.settings.timeoutId + + if timeoutId + clearTimeout(timeoutId) + + removeClasses = service.settings.classes + removeClasses.map (className) -> service.settings.target.addClass(className) + + target.html(service.settings.oldContent) + target.removeClass('loading') + + return service + } + + return service + +module.factory("$tgLoading", TgLoadingService) LoadingDirective = ($loading) -> link = ($scope, $el, attr) -> + currentLoading = null + $scope.$watch attr.tgLoading, (showLoading) => + if showLoading - $loading.start($el) + currentLoading = $loading() + .target($el) + .start() else - $loading.finish($el) + currentLoading.finish() return { link:link diff --git a/app/coffee/modules/feedback.coffee b/app/coffee/modules/feedback.coffee index 247db488..d121c889 100644 --- a/app/coffee/modules/feedback.coffee +++ b/app/coffee/modules/feedback.coffee @@ -39,17 +39,19 @@ FeedbackDirective = ($lightboxService, $repo, $confirm, $loading, feedbackServic if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.create("feedback", $scope.feedback) promise.then (data) -> - $loading.finish(submitButton) + currentLoading.finish() $lightboxService.close($el) $confirm.notify("success", "\\o/ we'll be happy to read your") promise.then null, -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("error") submitButton = $el.find(".submit-button") diff --git a/app/coffee/modules/issues/detail.coffee b/app/coffee/modules/issues/detail.coffee index 6dda40b4..1cadbb05 100644 --- a/app/coffee/modules/issues/detail.coffee +++ b/app/coffee/modules/issues/detail.coffee @@ -239,18 +239,21 @@ IssueStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $t issue = $model.$modelValue.clone() issue.status = statusId + currentLoading = $loading() + .target($el.find(".level-name")) + .start() + onSuccess = -> $confirm.notify("success") $model.$setViewValue(issue) $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") issue.revert() $model.$setViewValue(issue) - $loading.finish($el.find(".level-name")) + currentLoading.finish() - $loading.start($el.find(".level-name")) $repo.save(issue).then(onSuccess, onError) @@ -323,18 +326,21 @@ IssueTypeButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $tem issue = $model.$modelValue.clone() issue.type = type + currentLoading = $loading() + .target($el.find(".level-name")) + .start() + onSuccess = -> $confirm.notify("success") $model.$setViewValue(issue) $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") issue.revert() $model.$setViewValue(issue) - $loading.finish($el.find(".level-name")) - $loading.start($el.find(".level-name")) + currentLoading.finish() $repo.save(issue).then(onSuccess, onError) @@ -409,18 +415,20 @@ IssueSeverityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, issue = $model.$modelValue.clone() issue.severity = severity + currentLoading = $loading() + .target($el.find(".level-name")) + .start() + onSuccess = -> $confirm.notify("success") $model.$setViewValue(issue) $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") issue.revert() $model.$setViewValue(issue) - $loading.finish($el.find(".level-name")) - - $loading.start($el.find(".level-name")) + currentLoading.finish() $repo.save(issue).then(onSuccess, onError) @@ -496,18 +504,20 @@ IssuePriorityButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, issue = $model.$modelValue.clone() issue.priority = priority + currentLoading = $loading() + .target($el.find(".level-name")) + .start() + onSuccess = -> $confirm.notify("success") $model.$setViewValue(issue) $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") issue.revert() $model.$setViewValue(issue) - $loading.finish($el.find(".level-name")) - - $loading.start($el.find(".level-name")) + currentLoading.finish() $repo.save(issue).then(onSuccess, onError) diff --git a/app/coffee/modules/issues/lightboxes.coffee b/app/coffee/modules/issues/lightboxes.coffee index f05f2caf..29052e8f 100644 --- a/app/coffee/modules/issues/lightboxes.coffee +++ b/app/coffee/modules/issues/lightboxes.coffee @@ -58,17 +58,20 @@ CreateIssueDirective = ($repo, $confirm, $rootscope, lightboxService, $loading) if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() + promise = $repo.create("issues", $scope.issue) promise.then (data) -> - $loading.finish(submitButton) + currentLoading.finish() $rootscope.$broadcast("issueform:new:success", data) lightboxService.close($el) $confirm.notify("success") promise.then null, -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("error") @@ -103,20 +106,22 @@ CreateBulkIssuesDirective = ($repo, $rs, $confirm, $rootscope, $loading, lightbo if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() data = $scope.new.bulk projectId = $scope.new.projectId promise = $rs.issues.bulkCreate(projectId, data) promise.then (result) -> - $loading.finish(submitButton) + currentLoading.finish() $rootscope.$broadcast("issueform:new:success", result) lightboxService.close($el) $confirm.notify("success") promise.then null, -> - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify("error") submitButton = $el.find(".submit-button") diff --git a/app/coffee/modules/issues/list.coffee b/app/coffee/modules/issues/list.coffee index 0435e870..65642aa4 100644 --- a/app/coffee/modules/issues/list.coffee +++ b/app/coffee/modules/issues/list.coffee @@ -649,12 +649,14 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat if event.keyCode == 13 target = angular.element(event.currentTarget) newFilter = target.val() - $loading.start($el.find(".new")) + currentLoading = $loading() + .target($el.find(".new")) + .start() promise = $ctrl.saveCurrentFiltersTo(newFilter) promise.then -> loadPromise = $ctrl.loadMyFilters() loadPromise.then (filters) -> - $loading.finish($el.find(".new")) + currentLoading.finish() $scope.filters.myFilters = filters currentfilterstype = $el.find("h2 a.subfilter span.title").prop('data-type') @@ -665,11 +667,11 @@ IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $templat $el.find('.save-filters').show() loadPromise.then null, -> - $loading.finish($el.find(".new")) + currentLoading.finish() $confirm.notify("error", "Error loading custom filters") promise.then null, -> - $loading.finish($el.find(".new")) + currentLoading.finish() $el.find(".my-filter-name").val(newFilter).focus().select() $confirm.notify("error", "Filter not saved") diff --git a/app/coffee/modules/kanban/main.coffee b/app/coffee/modules/kanban/main.coffee index 66935eb8..988f693a 100644 --- a/app/coffee/modules/kanban/main.coffee +++ b/app/coffee/modules/kanban/main.coffee @@ -404,7 +404,7 @@ module.directive("tgKanbanArchivedStatusIntro", ["$translate", KanbanArchivedSta ## Kanban User Story Directive ############################################################################# -KanbanUserstoryDirective = ($rootscope) -> +KanbanUserstoryDirective = ($rootscope, $loading, $rs) -> link = ($scope, $el, $attrs, $model) -> $el.disableSelection() @@ -418,8 +418,18 @@ KanbanUserstoryDirective = ($rootscope) -> if $el.find(".icon-edit").hasClass("noclick") return - $scope.$apply -> - $rootscope.$broadcast("usform:edit", $model.$modelValue) + target = $(event.target) + + currentLoading = $loading() + .target(target) + .timeout(200) + .removeClasses("icon-edit") + .start() + + us = $model.$modelValue + $rs.userstories.getByRef(us.project, us.ref).then (editingUserStory) => + $rootscope.$broadcast("usform:edit", editingUserStory) + currentLoading.finish() $scope.$on "$destroy", -> $el.off() @@ -430,7 +440,7 @@ KanbanUserstoryDirective = ($rootscope) -> require: "ngModel" } -module.directive("tgKanbanUserstory", ["$rootScope", KanbanUserstoryDirective]) +module.directive("tgKanbanUserstory", ["$rootScope", "$tgLoading", "$tgResources", KanbanUserstoryDirective]) ############################################################################# ## Kanban Squish Column Directive diff --git a/app/coffee/modules/projects/lightboxes.coffee b/app/coffee/modules/projects/lightboxes.coffee index b027f58c..d5a482ea 100644 --- a/app/coffee/modules/projects/lightboxes.coffee +++ b/app/coffee/modules/projects/lightboxes.coffee @@ -30,6 +30,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project link = ($scope, $el, attrs) -> $scope.data = {} $scope.templates = [] + currentLoading = null form = $el.find("form").checksley({"onlyOneErrorElement": true}) @@ -39,7 +40,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project # than another deleted in the same session $cacheFactory.get('$http').removeAll() - $loading.finish(submitButton) + currentLoading.finish() $rootscope.$broadcast("projects:reload") $confirm.notify("success", $translate.instant("COMMON.SAVE")) @@ -49,7 +50,7 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project currentUserService.loadProjects() onErrorSubmit = (response) -> - $loading.finish(submitButton) + currentLoading.finish() form.setErrors(response) selectors = [] for error_field in _.keys(response) @@ -65,7 +66,9 @@ CreateProject = ($rootscope, $repo, $confirm, $location, $navurls, $rs, $project if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $repo.create("projects", $scope.data) promise.then(onSuccessSubmit, onErrorSubmit) diff --git a/app/coffee/modules/related-tasks.coffee b/app/coffee/modules/related-tasks.coffee index 4817d976..81eda43b 100644 --- a/app/coffee/modules/related-tasks.coffee +++ b/app/coffee/modules/related-tasks.coffee @@ -33,16 +33,18 @@ RelatedTaskRowDirective = ($repo, $compile, $confirm, $rootscope, $loading, $tem saveTask = debounce 2000, (task) -> task.subject = $el.find('input').val() - $loading.start($el.find('.task-name')) + currentLoading = $loading() + .target($el.find('.task-name')) + .start() promise = $repo.save(task) promise.then => - $loading.finish($el.find('.task-name')) + currentLoading.finish() $confirm.notify("success") $rootscope.$broadcast("related-tasks:update") promise.then null, => - $loading.finish($el.find('.task-name')) + currentLoading.finish() $el.find('input').val(task.subject) $confirm.notify("error") return promise @@ -126,17 +128,20 @@ RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, $scope.newTask.status = $scope.project.default_task_status $scope.newTask.assigned_to = null - $loading.start($el.find('.task-name')) + currentLoading = $loading() + .target($el.find('.task-name')) + .start() + promise = $repo.create("tasks", task) promise.then -> $analytics.trackEvent("task", "create", "create task on userstory", 1) - $loading.finish($el.find('.task-name')) + currentLoading.finish() $scope.$emit("related-tasks:add") $confirm.notify("success") promise.then null, -> $el.find('input').val(task.subject) - $loading.finish($el.find('.task-name')) + currentLoading.finish() $confirm.notify("error") return promise diff --git a/app/coffee/modules/taskboard/lightboxes.coffee b/app/coffee/modules/taskboard/lightboxes.coffee index c57e67eb..dbb97bd1 100644 --- a/app/coffee/modules/taskboard/lightboxes.coffee +++ b/app/coffee/modules/taskboard/lightboxes.coffee @@ -80,11 +80,13 @@ CreateEditTaskDirective = ($repo, $model, $rs, $rootscope, $loading, lightboxSer promise = $repo.save($scope.task) broadcastEvent = "taskform:edit:success" - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() # FIXME: error handling? promise.then (data) -> - $loading.finish(submitButton) + currentLoading.finish() lightboxService.close($el) $rootscope.$broadcast(broadcastEvent, data) @@ -107,7 +109,9 @@ CreateBulkTasksDirective = ($repo, $rs, $rootscope, $loading, lightboxService) - if not form.validate() return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() data = $scope.form.data projectId = $scope.projectId @@ -116,13 +120,13 @@ CreateBulkTasksDirective = ($repo, $rs, $rootscope, $loading, lightboxService) - promise = $rs.tasks.bulkCreate(projectId, sprintId, usId, data) promise.then (result) -> - $loading.finish(submitButton) + currentLoading.finish() $rootscope.$broadcast("taskform:bulk:success", result) lightboxService.close($el) # TODO: error handling promise.then null, -> - $loading.finish(submitButton) + currentLoading.finish() console.log "FAIL" $scope.$on "taskform:bulk", (ctx, sprintId, usId)-> diff --git a/app/coffee/modules/taskboard/main.coffee b/app/coffee/modules/taskboard/main.coffee index b8a17671..a6ecad42 100644 --- a/app/coffee/modules/taskboard/main.coffee +++ b/app/coffee/modules/taskboard/main.coffee @@ -295,7 +295,7 @@ module.directive("tgTaskboard", ["$rootScope", TaskboardDirective]) ## Taskboard Task Directive ############################################################################# -TaskboardTaskDirective = ($rootscope) -> +TaskboardTaskDirective = ($rootscope, $loading, $rs) -> link = ($scope, $el, $attrs, $model) -> $el.disableSelection() @@ -309,12 +309,23 @@ TaskboardTaskDirective = ($rootscope) -> if $el.find('.icon-edit').hasClass('noclick') return $scope.$apply -> - $rootscope.$broadcast("taskform:edit", $scope.task) + target = $(event.target) + + currentLoading = $loading() + .target(target) + .timeout(200) + .removeClasses("icon-edit") + .start() + + task = $scope.task + $rs.tasks.getByRef(task.project, task.ref).then (editingTask) => + $rootscope.$broadcast("taskform:edit", editingTask) + currentLoading.finish() return {link:link} -module.directive("tgTaskboardTask", ["$rootScope", TaskboardTaskDirective]) +module.directive("tgTaskboardTask", ["$rootScope", "$tgLoading", "$tgResources", TaskboardTaskDirective]) ############################################################################# ## Taskboard Squish Column Directive diff --git a/app/coffee/modules/tasks/detail.coffee b/app/coffee/modules/tasks/detail.coffee index d9864bbf..a6f67ee1 100644 --- a/app/coffee/modules/tasks/detail.coffee +++ b/app/coffee/modules/tasks/detail.coffee @@ -246,21 +246,21 @@ TaskStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $co task = $model.$modelValue.clone() task.status = status - $model.$setViewValue(task) + currentLoading = $loading() + .target($el.find(".level-name")) + .start() onSuccess = -> + $model.$setViewValue(task) $confirm.notify("success") $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") - task.revert() - $model.$setViewValue(task) - $loading.finish($el.find(".level-name")) + currentLoading.finish() - $loading.start($el.find(".level-name")) - $repo.save($model.$modelValue).then(onSuccess, onError) + $repo.save(task).then(onSuccess, onError) $el.on "click", ".status-data", (event) -> event.preventDefault() @@ -328,22 +328,22 @@ TaskIsIocaineButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qqueue task = $model.$modelValue.clone() task.is_iocaine = is_iocaine - $model.$setViewValue(task) - $loading.start($el.find('label')) + currentLoading = $loading() + .target($el.find('label')) + .start() promise = $tgrepo.save(task) promise.then -> + $model.$setViewValue(task) $confirm.notify("success") $rootscope.$broadcast("object:updated") promise.then null, -> - task.revert() - $model.$setViewValue(task) $confirm.notify("error") promise.finally -> - $loading.finish($el.find('label')) + currentLoading.finish() $el.on "click", ".is-iocaine", (event) -> return if not isEditable() diff --git a/app/coffee/modules/user-settings/change-password.coffee b/app/coffee/modules/user-settings/change-password.coffee index ba1d19d0..c978bdec 100644 --- a/app/coffee/modules/user-settings/change-password.coffee +++ b/app/coffee/modules/user-settings/change-password.coffee @@ -67,15 +67,17 @@ UserChangePasswordDirective = ($rs, $confirm, $loading, $translate) -> $confirm.notify('error', $translate.instant("CHANGE_PASSWORD.ERROR_PASSWORD_MATCH")) return - $loading.start(submitButton) + currentLoading = $loading() + .target(submitButton) + .start() promise = $rs.userSettings.changePassword($scope.currentPassword, $scope.newPassword1) promise.then => - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify('success') promise.then null, (response) => - $loading.finish(submitButton) + currentLoading.finish() $confirm.notify('error', response.data._error_message) submitButton = $el.find(".submit-button") diff --git a/app/coffee/modules/userstories/detail.coffee b/app/coffee/modules/userstories/detail.coffee index 814dab5b..d819a947 100644 --- a/app/coffee/modules/userstories/detail.coffee +++ b/app/coffee/modules/userstories/detail.coffee @@ -304,8 +304,8 @@ UsStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $temp statuses: $scope.statusList editable: isEditable() }) - $el.html(html) + $el.html(html) save = $qqueue.bindAdd (status) => us = $model.$modelValue.clone() @@ -314,22 +314,21 @@ UsStatusButtonDirective = ($rootScope, $repo, $confirm, $loading, $qqueue, $temp $.fn.popover().closeAll() - $model.$setViewValue(us) + currentLoading = $loading() + .target($el.find(".level-name")) + .start() onSuccess = -> $confirm.notify("success") + $model.$setViewValue(us) $rootScope.$broadcast("object:updated") - $loading.finish($el.find(".level-name")) + currentLoading.finish() onError = -> $confirm.notify("error") - us.revert() - $model.$setViewValue(us) - $loading.finish($el.find(".level-name")) + currentLoading.finish() - $loading.start($el.find(".level-name")) - - $repo.save($model.$modelValue).then(onSuccess, onError) + $repo.save(us).then(onSuccess, onError) $el.on "click", ".status-data", (event) -> event.preventDefault() @@ -393,20 +392,19 @@ UsTeamRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $qq us = $model.$modelValue.clone() us.team_requirement = team_requirement - $model.$setViewValue(us) + currentLoading = $loading() + .target($el.find("label")) + .start() - $loading.start($el.find("label")) - - promise = $tgrepo.save($model.$modelValue) + promise = $tgrepo.save(us) promise.then => - $loading.finish($el.find("label")) + $model.$setViewValue(us) + currentLoading.finish() $rootscope.$broadcast("object:updated") promise.then null, -> - $loading.finish($el.find("label")) + currentLoading.finish() $confirm.notify("error") - us.revert() - $model.$setViewValue(us) $el.on "click", ".team-requirement", (event) -> return if not canEdit() @@ -456,18 +454,18 @@ UsClientRequirementButtonDirective = ($rootscope, $tgrepo, $confirm, $loading, $ us = $model.$modelValue.clone() us.client_requirement = client_requirement - $model.$setViewValue(us) + currentLoading = $loading() + .target($el.find("label")) + .start() - $loading.start($el.find("label")) - promise = $tgrepo.save($model.$modelValue) + promise = $tgrepo.save(us) promise.then => - $loading.finish($el.find("label")) - $rootscope.$broadcast("object:updated") - promise.then null, -> - $loading.finish($el.find("label")) - $confirm.notify("error") - us.revert() $model.$setViewValue(us) + currentLoading.finish() + $rootscope.$broadcast("object:updated") + + promise.then null, -> + $confirm.notify("error") $el.on "click", ".client-requirement", (event) -> return if not canEdit() diff --git a/app/coffee/modules/wiki/main.coffee b/app/coffee/modules/wiki/main.coffee index 4a2b87d4..68c3b27f 100644 --- a/app/coffee/modules/wiki/main.coffee +++ b/app/coffee/modules/wiki/main.coffee @@ -233,7 +233,12 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $ onError = -> $confirm.notify("error") - $loading.start($el.find('.save-container')) + console.log $el.find('.save-container') + + currentLoading = $loading() + .removeClasses("icon-floppy") + .target($el.find('.icon-floppy')) + .start() if wiki.id? promise = $repo.save(wiki).then(onSuccess, onError) @@ -241,7 +246,7 @@ EditableWikiContentDirective = ($window, $document, $repo, $confirm, $loading, $ promise = $repo.create("wiki", wiki).then(onSuccess, onError) promise.finally -> - $loading.finish($el.find('.save-container')) + currentLoading.finish() $el.on "click", "a", (event) -> target = angular.element(event.target) diff --git a/app/coffee/modules/wiki/nav.coffee b/app/coffee/modules/wiki/nav.coffee index 558ff820..e0aa2c1b 100644 --- a/app/coffee/modules/wiki/nav.coffee +++ b/app/coffee/modules/wiki/nav.coffee @@ -104,27 +104,29 @@ WikiNavDirective = ($tgrepo, $log, $location, $confirm, $navUrls, $analytics, $l target = angular.element(event.currentTarget) newLink = target.val() - $loading.start($el.find(".new")) + currentLoading = $loading() + .target($el.find(".new")) + .start() promise = $tgrepo.create("wiki-links", {project: $scope.projectId, title: newLink, href: slugify(newLink)}) promise.then -> $analytics.trackEvent("wikilink", "create", "create wiki link", 1) loadPromise = $ctrl.loadWikiLinks() loadPromise.then -> - $loading.finish($el.find(".new")) + currentLoading.finish() $el.find(".new").addClass("hidden") $el.find(".new input").val('') $el.find(".add-button").show() render($scope.wikiLinks) loadPromise.then null, -> - $loading.finish($el.find(".new")) + currentLoading.finish() $el.find(".new").addClass("hidden") $el.find(".new input").val('') $el.find(".add-button").show() $confirm.notify("error", "Error loading wiki links") promise.then null, (error) -> - $loading.finish($el.find(".new")) + currentLoading.finish() $el.find(".new input").val(newLink) $el.find(".new input").focus().select() if error?.__all__?[0]? diff --git a/app/partials/common/history/history-base.jade b/app/partials/common/history/history-base.jade index f9450728..4ca4a9af 100644 --- a/app/partials/common/history/history-base.jade +++ b/app/partials/common/history/history-base.jade @@ -16,7 +16,7 @@ section.history a(class="help-markdown", href="https://taiga.io/support/taiga-markdown-syntax/", target="_blank", title="{{'COMMON.WYSIWYG.MARKDOWN_HELP' | translate}}") span.icon.icon-help span(translate="COMMON.WYSIWYG.MARKDOWN_HELP") - input(type="button", ng-disabled!="!<%- ngmodel %>.comment.length" title="{{'COMMENTS.COMMENT' | translate}}", value="{{'COMMENTS.COMMENT' | translate}}", class="button button-green save-comment") + button(type="button", ng-disabled!="!<%- ngmodel %>.comment.length" title="{{'COMMENTS.COMMENT' | translate}}", translate="COMMENTS.COMMENT", class="button button-green save-comment") <% } %> section.history-activity.hidden .changes-list diff --git a/app/partials/includes/components/backlog-row.jade b/app/partials/includes/components/backlog-row.jade index f375076b..e91e4156 100644 --- a/app/partials/includes/components/backlog-row.jade +++ b/app/partials/includes/components/backlog-row.jade @@ -10,7 +10,7 @@ div.row.us-item-row(ng-repeat="us in userstories track by us.id", tg-bind-scope, span(ng-bind="us.subject") div.us-settings a.icon.icon-edit(tg-check-permission="modify_us", href="", - ng-click="ctrl.editUserStory(us)", title="{{'COMMON.EDIT' | translate}}") + ng-click="ctrl.editUserStory(us.project, us.ref, $event)", title="{{'COMMON.EDIT' | translate}}") a.icon.icon-delete(tg-check-permission="delete_us", href="", ng-click="ctrl.deleteUserStory(us)", title="{{'COMMON.DELETE' | translate}}") diff --git a/app/styles/components/kanban-task.scss b/app/styles/components/kanban-task.scss index 2aa34c30..401c45a0 100644 --- a/app/styles/components/kanban-task.scss +++ b/app/styles/components/kanban-task.scss @@ -87,6 +87,10 @@ .task-name { @extend %bold; } + .loading { + bottom: .5rem; + position: absolute; + } .icon-edit, .icon-drag-h { @extend %large; @@ -132,6 +136,7 @@ .task-name { word-wrap: break-word; } + .loading, .icon-edit { bottom: .2rem; right: .5rem; diff --git a/app/styles/components/taskboard-task.scss b/app/styles/components/taskboard-task.scss index 8e94caab..a8d58830 100644 --- a/app/styles/components/taskboard-task.scss +++ b/app/styles/components/taskboard-task.scss @@ -109,6 +109,10 @@ .icon { transition: color .3s linear, opacity .3s linear; } + .loading { + bottom: .5rem; + position: absolute; + } .icon-edit, .icon-drag-h { @extend %large; @@ -120,7 +124,8 @@ color: $card-dark; } } - .icon-edit { + .icon-edit, + .loading { right: 1rem; } .icon-drag-h { From 48cd25294b37bc8c9c5afdf2482a0ebbd9313efc Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 10 Aug 2015 14:34:27 +0200 Subject: [PATCH 096/403] fix related task link --- app/partials/issue/issues-detail.jade | 2 +- app/partials/task/task-detail.jade | 2 +- app/partials/us/us-detail.jade | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/partials/issue/issues-detail.jade b/app/partials/issue/issues-detail.jade index 6f8e536c..c4f1d6d5 100644 --- a/app/partials/issue/issues-detail.jade +++ b/app/partials/issue/issues-detail.jade @@ -18,7 +18,7 @@ div.wrapper(ng-controller="IssueDetailController as ctrl", a(ng-repeat="us in issue.generated_user_stories", tg-check-permission="view_us", href="", tg-bo-title="'#' + us.ref + ' ' + us.subject", - tg-nav="project-userstories-detail:project=project.slug, ref=us.ref") + tg-nav="project-userstories-detail:project=project.slug,ref=us.ref") span(tg-bo-ref="us.ref") p.external-reference(ng-if="issue.external_reference") diff --git a/app/partials/task/task-detail.jade b/app/partials/task/task-detail.jade index ea22158d..e24dd306 100644 --- a/app/partials/task/task-detail.jade +++ b/app/partials/task/task-detail.jade @@ -22,7 +22,7 @@ div.wrapper(ng-controller="TaskDetailController as ctrl", h3.us-related-task(ng-if="us") | {{ 'TASK.OWNER_US'|translate }} a(tg-check-permission="view_us", href="", title="{{'TASK.TITLE_LINK_GO_OWNER' | translate}}", - tg-nav="project-userstories-detail:project=project.slug, ref=us.ref") + tg-nav="project-userstories-detail:project=project.slug,ref=us.ref") span(tg-bo-ref="us.ref") span(tg-bo-bind="us.subject") diff --git a/app/partials/us/us-detail.jade b/app/partials/us/us-detail.jade index bb2de2ac..95ca50f1 100644 --- a/app/partials/us/us-detail.jade +++ b/app/partials/us/us-detail.jade @@ -22,7 +22,7 @@ div.wrapper(ng-controller="UserStoryDetailController as ctrl", p.us-related-task(ng-if="us.origin_issue") | {{ 'US.PROMOTED'|translate }} a(tg-check-permission="view_us", href="", title="{{'US.TITLE_LINK_GO_TO_ISSUE' | translate}}", - tg-nav="project-issues-detail:project=project.slug, ref=us.origin_issue.ref" + tg-nav="project-issues-detail:project=project.slug,ref=us.origin_issue.ref" tg-bo-title="'#' + us.origin_issue.ref + ' ' + us.origin_issue.subject") span(tg-bo-ref="us.origin_issue.ref") From ea7e5ebf4908a0d40f6710941a5b466b9c4c72fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Sat, 15 Aug 2015 11:30:00 +0200 Subject: [PATCH 097/403] [i18n] Update locales --- app/locales/locale-ca.json | 154 ++++++++++++++++++------------------- app/locales/locale-nl.json | 26 +++---- app/locales/locale-pl.json | 30 ++++---- 3 files changed, 105 insertions(+), 105 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index 8c138982..c09e6d28 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -6,7 +6,7 @@ "LOADING_PROJECT": "Carregant projecte...", "DATE": "DD MMM YYYY", "DATETIME": "DD MMM YYYY HH:mm", - "SAVE": "Guardar", + "SAVE": "Desa", "CANCEL": "Següent", "ACCEPT": "Acceptar", "DELETE": "Esborrar", @@ -45,8 +45,8 @@ "TYPE_NUMBER": "Deu ser un nombre vàlid.", "TYPE_DIGITS": "This value should be digits.", "TYPE_DATEISO": "This value should be a valid date (YYYY-MM-DD).", - "TYPE_ALPHANUM": "This value should be alphanumeric.", - "TYPE_PHONE": "This value should be a valid phone number.", + "TYPE_ALPHANUM": "Aquest valor ha de ser alfanumèric.", + "TYPE_PHONE": "Aquest valor ha de ser un número de telèfon vàlid.", "NOTNULL": "This value should not be null.", "NOT_BLANK": "This value should not be blank.", "REQUIRED": "Aquest valor és necessari.", @@ -101,10 +101,10 @@ "SAT": "Ds" } }, - "SEE_USER_PROFILE": "See {{username }} profile", + "SEE_USER_PROFILE": "Veure el perfil de {{usuari}}", "USER_STORY": "Història d'usuari", - "TASK": "Task", - "ISSUE": "Issue", + "TASK": "Tasca", + "ISSUE": "incidència", "TAGS": { "PLACEHOLDER": "Afegir tag", "DELETE": "Elimina l'etiqueta", @@ -251,13 +251,13 @@ "INVITED_YOU": "T'ha convidat a participar en el projecte", "NOT_REGISTERED_YET": "No t'has registrat encara?", "REGISTER": "Registrat", - "CREATE_ACCOUNT": "Crea el teu conter gratis ací" + "CREATE_ACCOUNT": "crea el teu compte gratuït ací" }, "LOGIN_COMMON": { - "HEADER": "Ja tinc un conter de Taiga", + "HEADER": "Ja tinc un compte de Taiga", "PLACEHOLDER_AUTH_NAME": "Nom d'usuari i correu electrònic (sensible a majúscules i minúscules)", "LINK_FORGOT_PASSWORD": "L'has oblidat?", - "TITLE_LINK_FORGOT_PASSWORD": "Has oblidat la teua contrasenya?", + "TITLE_LINK_FORGOT_PASSWORD": "Has oblidat la teva contrasenya?", "ACTION_ENTER": "Entrar", "ACTION_SIGN_IN": "Entrar", "PLACEHOLDER_AUTH_PASSWORD": "Contrasenya (sensible a majúscules i minúscules)" @@ -271,11 +271,11 @@ "PAGE_DESCRIPTION": "Crea un nou compte de Taiga, una plataforma de gestió de projectes per a empreses àgils que necessiten una eïna sencilla i elegant que et permet gaudir del teu treball" }, "REGISTER_FORM": { - "TITLE": "Registra un nou compte de Taiga (gratis)", + "TITLE": "Registra un nou compte de Taiga (gratuït)", "PLACEHOLDER_NAME": "Trieu un nom d'usuari (sensible a majúscules i minúscules)", "PLACEHOLDER_FULL_NAME": "Escriu el teu nom complet", "PLACEHOLDER_EMAIL": "El teu correu", - "PLACEHOLDER_PASSWORD": "Tria una contrasenya(sensible a majúscules i minúscules)", + "PLACEHOLDER_PASSWORD": "Defineix una contrasenya (sensible a majúscules i minúscules)", "ACTION_SIGN_UP": "Registrar-se", "TITLE_LINK_LOGIN": "Entrar", "LINK_LOGIN": "Ja estàs registrat? Entra" @@ -285,17 +285,17 @@ "PAGE_DESCRIPTION": "Escriviu el vostre nom d'usuari o correu electrònic per a conseguir-ne un de nou" }, "FORGOT_PASSWORD_FORM": { - "TITLE": "Oops, has oblidat la teua contrasenya?", + "TITLE": "Oops, has oblidat la teva contrasenya?", "SUBTITLE": "Escriviu el vostre nom d'usuari o correu electrònic per a conseguir-ne un de nou", "PLACEHOLDER_FIELD": "Nom d'usuari o correu electrònic", "ACTION_RESET_PASSWORD": "Resetejar contrasenya", - "LINK_CANCEL": "No, portam enrere, crec que ho recorde.", + "LINK_CANCEL": "No, porta'm enrere, crec que ja ho recordo.", "SUCCESS": "Mira el teu correu!
Hem enviat un correu amb les instrucciones per a setejar una nova contrasenya.", "ERROR": "Segons els nostres Oompa Loompas, no estàs registrat encara." }, "CHANGE_PASSWORD": { "PAGE_TITLE": "Canvi de contrasenya - Taiga", - "PAGE_DESCRIPTION": "Set a new password for your Taiga account and hey!, you may want to eat some more iron-rich food, it's good for your brain :P", + "PAGE_DESCRIPTION": "Estableix una contrasenya nova per al teu compte de Taiga i per cer cert! Potser voleu menjar més aliments rics en ferro, és bo per al cervell :P", "SECTION_NAME": "Canvi de contrasenya", "FIELD_CURRENT_PASSWORD": "Contrasenya actual", "PLACEHOLDER_CURRENT_PASSWORD": "La teua contrasenya actua (buit si no tens contrasenya encara)", @@ -306,8 +306,8 @@ "ERROR_PASSWORD_MATCH": "Les contrasenyes no coincideixen" }, "CHANGE_PASSWORD_RECOVERY_FORM": { - "TITLE": "Crea un nou password", - "SUBTITLE": "Menja un poc més de ferro, es bo pel cervell :P ", + "TITLE": "Crea una nova contrasenya", + "SUBTITLE": "Menja més aliments rics en ferro, es bo pel cervell :P ", "PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Recuperar token de contrasenya", "LINK_NEED_TOKEN": "Neccesites un?", "TITLE_LINK_NEED_TOKEN": "Necessites un token per a recuperar la teua contrasenya perque l'has oblidat?", @@ -321,7 +321,7 @@ "PAGE_DESCRIPTION": "Accepta la invitació a un projecte en Taiga, una plataforma de gestió de projectes per a empreses àgils que necessiten una eïna sencilla i elegant que et permet gaudir del teu treball" }, "INVITATION_LOGIN_FORM": { - "NOT_FOUND": "Ooops, ha hagut un problema
Els nosters Oompa Loompas no troben la teua invitació.", + "NOT_FOUND": "Ooops, ha hagut un problema
Els nosters Oompa Loompas no troben la teva invitació.", "SUCCESS": "T'has incorporat a este projecte. Vos donem la benvinguda a {{project_name}}", "ERROR": "Segons els nostres OOmpa Loompas, no estàs registrat encara o has escrit una contrasenya invàlida." }, @@ -344,11 +344,11 @@ "DESCRIPTION": "Escriu una descripció curta", "DEPRECATED": "(obsolet)", "DEPRECATED_FILE": "Obsolet?", - "ADD": "Add new attachment. {{maxFileSizeMsg}}", + "ADD": "Afegeix un nou adjunt. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. grandària: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ mostra els adjunts obsolets", "HIDE_DEPRECATED": "- Amagar els adjunts obsolets", - "COUNT_DEPRECATED": "({{ counter }} deprecated)", + "COUNT_DEPRECATED": "({{ counter }} obsolet)", "MAX_UPLOAD_SIZE": "El tamany màxim de pujada es ", "DATE": "DD MMM YYYY [at] hh:mm", "ERROR_UPLOAD_ATTACHMENT": "No hem pogut pujar '{{fileName}}'. {{errorMessage}}", @@ -375,7 +375,7 @@ }, "MEMBERSHIPS": { "TITLE": "Gestió de Membres", - "PAGE_TITLE": "Memberships - {{projectName}}", + "PAGE_TITLE": "Afiliacions - {{projectName}}", "ADD_BUTTON": "+ Nou membre", "ADD_BUTTON_TITLE": "Afegir nou membre" }, @@ -412,11 +412,11 @@ "JITSI_CHAT_ROOM": "Jitsi", "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", - "CUSTOM_CHAT_ROOM": "Custom", - "URL_CHAT_ROOM": "URL of your chat room" + "CUSTOM_CHAT_ROOM": "Personalitzat", + "URL_CHAT_ROOM": "Adreça web del teu xat" }, "PROJECT_PROFILE": { - "PAGE_TITLE": "{{sectionName}} - Project profile - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - Perfil de projecte - {{projectName}}", "PROJECT_DETAILS": "Detalls de projecte", "PROJECT_NAME": "Nom del projecte", "PROJECT_SLUG": "Slug de projecte", @@ -437,7 +437,7 @@ "REGENERATE_SUBTITLE": "Vas a canviar la URL d'accés al CSV. La URL previa no funcionarà. Estàs segur?" }, "CSV": { - "SECTION_TITLE_US": "user stories reports", + "SECTION_TITLE_US": "informes d'històries d'usuari", "SECTION_TITLE_TASK": "infome de tasques", "SECTION_TITLE_ISSUE": "informe d'incidències", "DOWNLOAD": "Descarrega el CSV", @@ -456,7 +456,7 @@ "ISSUE_DESCRIPTION": "Camps personalitzats d'incidències", "ISSUE_ADD": "Afegix camps personalitzats en incidències", "FIELD_TYPE_TEXT": "Text", - "FIELD_TYPE_MULTI": "Multi-line" + "FIELD_TYPE_MULTI": "Múltiples línies" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", @@ -464,22 +464,22 @@ "ERROR_DELETE_ALL": "No pots esborrar tots els valors." }, "PROJECT_VALUES_POINTS": { - "TITLE": "Points", + "TITLE": "Punts", "SUBTITLE": "Especifica els punts en els que poden ser estimades les històries d'usuari", - "US_TITLE": "US points", + "US_TITLE": "Punts d'història d'usuari", "ACTION_ADD": "Afegir punts nous" }, "PROJECT_VALUES_PRIORITIES": { - "TITLE": "Priorities", + "TITLE": "Prioritats", "SUBTITLE": "Especifica les prioritats que tindran les teues tasques", - "ISSUE_TITLE": "Issue priorities", - "ACTION_ADD": "Add new priority" + "ISSUE_TITLE": "Prioritats d'incidències", + "ACTION_ADD": "Afegir nova prioritat" }, "PROJECT_VALUES_SEVERITIES": { - "TITLE": "Severities", + "TITLE": "Severitats", "SUBTITLE": "Especifiqueu les severitats que tindran les vostres incidències", - "ISSUE_TITLE": "Issue severities", - "ACTION_ADD": "Add new severity" + "ISSUE_TITLE": "Severitats d'incidències", + "ACTION_ADD": "Afegir nova severitat" }, "PROJECT_VALUES_STATUS": { "TITLE": "Estat", @@ -495,7 +495,7 @@ "ACTION_ADD": "Afegir now {{objName}}" }, "ROLES": { - "PAGE_TITLE": "Roles - {{projectName}}", + "PAGE_TITLE": "Rols - {{projectName}}", "WARNING_NO_ROLE": "Ves amb compte, cap rol en el teu projecte pot estimar punts per a les històries d'usuari", "HELP_ROLE_ENABLED": "Si està activat, els membres assignats a aquest rol podràn estimar els punts d'històries d'usuaris", "COUNT_MEMBERS": "{{ role.members_count }} membres amb aquest rol", @@ -551,7 +551,7 @@ "WEBHOOK_NAME": "Webhook '{{name}}'" }, "CUSTOM_ATTRIBUTES": { - "PAGE_TITLE": "{{sectionName}} - Custom Attributes - {{projectName}}", + "PAGE_TITLE": "{{sectionName}} - Atributs personalitzats - {{projectName}}", "ADD": "Afegix camp personalitzat", "EDIT": "Edita el camp personalitzat", "DELETE": "Esborrar camp personalitzat", @@ -633,19 +633,19 @@ "PROFILE": { "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", "EDIT": "Edita el perfil", - "FOLLOW": "Follow", + "FOLLOW": "Seguir", "PROJECTS": "Projectes", "CLOSED_US": "HU tancada", - "CONTACTS": "Contacts", - "REPORT": "Report Abuse", - "ACTIVITY_TAB": "Activity Tab", - "PROJECTS_TAB": "Projects Tab", - "CONTACTS_TAB": "Contacts Tab", - "FAVORITES_TAB": "Favorites Tab", - "CONTACTS_EMPTY": "{{username}} doesn't have contacts yet", - "CURRENT_USER_CONTACTS_EMPTY": "You don't have contacts yet", - "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "The people with whom you work at Taiga will be your contacts automatically", - "PROJECTS_EMPTY": "{{username}} doesn't' have projects yet" + "CONTACTS": "Contactes", + "REPORT": "Informar d'un abús", + "ACTIVITY_TAB": "Pestanya d'activitat", + "PROJECTS_TAB": "Pestanya de projectes", + "CONTACTS_TAB": "Pestanya de contactes", + "FAVORITES_TAB": "Pestanya de preferits", + "CONTACTS_EMPTY": "{{Usuari}} no té contactes encara", + "CURRENT_USER_CONTACTS_EMPTY": "No tens contactes encara", + "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "Les persones amb les que treballa a Taiga seran els seus contactes de forma automàtica", + "PROJECTS_EMPTY": "{{username}} encara no te cap projecte" }, "PROFILE_SIDEBAR": { "TITLE": "El teu perfil", @@ -657,7 +657,7 @@ "PAGE_TITLE": "{{projectName}}", "WELCOME": "Benvinguts", "SECTION_PROJECTS": "Projectes", - "HELP": "Reorder your projects to set in the top the most used ones.
The top 10 projects will appear in the top navigation bar project list", + "HELP": "Reordena els teus projectes per a establir els més utilitzats en les primeres posicions.
Els 10 millors projectes apareixeran en la llista de projectes de la barra de navegació superior", "PRIVATE": "Projecte privat", "STATS": { "PROJECT": "punts
projecte", @@ -680,22 +680,22 @@ "SECTION_TITLE": "Els teus projectes", "PLACEHOLDER_SEARCH": "Cerca en...", "ACTION_CREATE_PROJECT": "Crear projecte", - "ACTION_IMPORT_PROJECT": "Import project", + "ACTION_IMPORT_PROJECT": "Importar projecte", "SEE_MORE_PROJECTS": "Visualitza més projectes", - "TITLE_CREATE_PROJECT": "Create project", - "TITLE_IMPORT_PROJECT": "Import project", + "TITLE_CREATE_PROJECT": "Crear projecte", + "TITLE_IMPORT_PROJECT": "Importar projecte", "TITLE_PRVIOUS_PROJECT": "Mostra projectes previs", "TITLE_NEXT_PROJECT": "Mostrar próxims projectes", - "HELP_TITLE": "Taiga Support Page", + "HELP_TITLE": "Pàgina d'ajuda de Taiga", "HELP": "Ajuda", "FEEDBACK_TITLE": "Enviar suggerències", "FEEDBACK": "Suggerències", - "NOTIFICATIONS_TITLE": "Edit your notification settings", + "NOTIFICATIONS_TITLE": "Edita la configuració de les teves notificacions", "NOTIFICATIONS": "Notificacions", "ORGANIZATIONS_TITLE": "Edit your organizations", "ORGANIZATIONS": "Edit organizations", - "SETTINGS_TITLE": "Edit your settings", - "SETTINGS": "Settings", + "SETTINGS_TITLE": "Editeu les vostres preferències", + "SETTINGS": "Preferències", "VIEW_PROFILE_TITLE": "Visualitza el perfil", "VIEW_PROFILE": "Visualitza el perfil", "EDIT_PROFILE_TITLE": "Editeu el vostre perfil", @@ -786,9 +786,9 @@ } }, "US": { - "PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{userStoryStatus }}. Completed {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} of {{userStoryTotalTasks}} tasks closed). Points: {{userStoryPoints}}. Description: {{userStoryDescription}}", - "SECTION_NAME": "User story details", + "PAGE_TITLE": "{{userStorySubject}} - Història d'Usuari {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Estat: {{userStoryStatus }}. Completat {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} de {{userStoryTotalTasks}} tasques tancades). Punts: {{userStoryPoints}}. Descripció: {{userStoryDescription}}", + "SECTION_NAME": "Detalls de la història d'usuari", "LINK_TASKBOARD": "Panell de tasques", "TITLE_LINK_TASKBOARD": "Anar a panell de tasques", "TOTAL_POINTS": "total", @@ -876,7 +876,7 @@ }, "BACKLOG": { "PAGE_TITLE": "Backlog - {{projectName}}", - "PAGE_DESCRIPTION": "The backlog panel, with user stories and sprints of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "El panell Backlog, amb històries d'usuari i esprints del projecte {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Backlog", "MOVE_US_TO_CURRENT_SPRINT": "Envia al Sprint", "SHOW_FILTERS": "Mostra filtres", @@ -897,13 +897,13 @@ "CHART": { "XAXIS_LABEL": "Sprints", "YAXIS_LABEL": "Punts", - "OPTIMAL": "Optimal pending points for sprint \"{{sprintName}}\" should be {{value}}", + "OPTIMAL": "Els punts pendents òptims per l'esprint \"{{sprintName}}\" haurien de ser {{value}}", "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" }, "TAGS": { - "TOGGLE": "Toggle tags visibility", + "TOGGLE": "Alterna la visibilitat d'etiquetes", "SHOW": "Mostra etiquetes", "HIDE": "Amaga etiquetes" }, @@ -957,7 +957,7 @@ "VERSION_ERROR": "Algú dins de Taiga ha canviat aȯ abans i els Oompa Loompas no pode aplicar els teus canvis. Per favor recarrega i aplica els teus canvis (es perdràn)" }, "TASKBOARD": { - "PAGE_TITLE": "{{sprintName}} - Sprint taskboard - {{projectName}}", + "PAGE_TITLE": "{{sprintName}} - Panell de tasques del esprint - {{projectName}}", "PAGE_DESCRIPTION": "Sprint {{sprintName}} (from {{startDate}} to {{endDate}}) of {{projectName}}. Completed {{completedPercentage}}% ({{completedPoints}} of {{totalPoints}} points). {{openTasks}} opened tasks of {{totalTasks}}.", "SECTION_NAME": "Panell de tasques", "TITLE_ACTION_ADD": "Afegir nova tasca", @@ -983,7 +983,7 @@ }, "TASK": { "PAGE_TITLE": "{{taskSubject}} - Task {{taskRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{taskStatus }}. Description: {{taskDescription}}", + "PAGE_DESCRIPTION": "Estat: {{taskStatus }}. Descripció: {{taskDescription}}", "SECTION_NAME": "Detalls de la tasca", "LINK_TASKBOARD": "Panell de tasques", "TITLE_LINK_TASKBOARD": "Anar a panell de tasques", @@ -1030,10 +1030,10 @@ "SUCCESS": "Els Oompa Loompas han actualitzat el teu correu" }, "ISSUES": { - "PAGE_TITLE": "Issues - {{projectName}}", + "PAGE_TITLE": "Incidències - {{projectName}}", "PAGE_DESCRIPTION": "The issues list panel of the project {{projectName}}: {{projectDescription}}", "LIST_SECTION_NAME": "Incidències", - "SECTION_NAME": "Issue details", + "SECTION_NAME": "Detalls d'incidència", "ACTION_NEW_ISSUE": "+ NOVA INCIDÈNCIA", "ACTION_PROMOTE_TO_US": "Promocionar història d'usuari", "PLACEHOLDER_FILTER_NAME": "Escriu el filtre i pressiona Intro", @@ -1096,12 +1096,12 @@ } }, "ISSUE": { - "PAGE_TITLE": "{{issueSubject}} - Issue {{issueRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priority: {{issuePriority}}. Severity: {{issueSeverity}}. Description: {{issueDescription}}" + "PAGE_TITLE": "{{issueSubject}} - incidència {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Estat: {{issueStatus }}. Tipus: {{issueType}}, Prioritat: {{issuePriority}}. Severitat: {{issueSeverity}}. Descripció: {{issueDescription}}" }, "KANBAN": { "PAGE_TITLE": "Kanban - {{projectName}}", - "PAGE_DESCRIPTION": "The kanban panel, with user stories of the project {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "El panell Kanban, amb històries d'usuari del projecte {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Kanban", "TITLE_ACTION_FOLD": "Plegar columna", "TITLE_ACTION_UNFOLD": "Desplegar columna", @@ -1116,7 +1116,7 @@ "UNDO_ARCHIVED": "Arrastra de nou per desfer" }, "SEARCH": { - "PAGE_TITLE": "Search - {{projectName}}", + "PAGE_TITLE": "Cerca - {{projectName}}", "PAGE_DESCRIPTION": "Search anything, user stories, issues, tasks or wiki pages, in the project {{projectName}}: {{projectDescription}}", "FILTER_USER_STORIES": "Històries d'usuari", "FILTER_ISSUES": "Incidències", @@ -1128,7 +1128,7 @@ "EMPTY_DESCRIPTION": "Prova amb una de les pestanyes o busca de nou" }, "TEAM": { - "PAGE_TITLE": "Team - {{projectName}}", + "PAGE_TITLE": "Equip - {{projectName}}", "PAGE_DESCRIPTION": "The team panel to show all the members of the project {{projectName}}: {{projectDescription}}", "SECTION_NAME": "Equip", "APP_TITLE": "EQUIP - {{projectName}}", @@ -1224,10 +1224,10 @@ "HINTS": { "SECTION_NAME": "Hint", "LINK": "If you want to know how to use it visit our support page", - "LINK_TITLE": "Visit our support page", - "HINT1_TITLE": "Did you know you can import and export projects?", - "HINT1_TEXT": "This allow you to extract all your data from one Taiga and move it to another one.", - "HINT2_TITLE": "Did you know you can create custom fields?", + "LINK_TITLE": "Visita la nostra pàgina d'ajuda", + "HINT1_TITLE": "Saps que pots importar i exportar projectes?", + "HINT1_TEXT": "Això li permet extreure totes les dades d'un Taiga i moure'l a un altre.", + "HINT2_TITLE": "Saps que pots crear camps personalitzats?", "HINT2_TEXT": "Teams can now create custom fields as a flexible means to enter specific data useful for their particular workflow", "HINT3_TITLE": "Reorder your projects to feature those most relevant to you", "HINT3_TEXT": "The top 10 project will be in your top bar direct access", @@ -1236,9 +1236,9 @@ }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} has uploaded a new attachment in {{obj_name}}", - "US_CREATED": "{{username}} has created a new US {{obj_name}} in {{project_name}}", - "ISSUE_CREATED": "{{username}} has created a new issue {{obj_name}} in {{project_name}}", - "TASK_CREATED": "{{username}} has created a new task {{obj_name}} in {{project_name}}", + "US_CREATED": "{{username}} ha creat una nova història d'usuari {{obj_name}} a {{project_name}}", + "ISSUE_CREATED": "{{username}} ha creat una nova incidència {{obj_name}} a {{project_name}}", + "TASK_CREATED": "{{username}} ha creat una nova tasca {{obj_name}} a {{project_name}}", "TASK_CREATED_WITH_US": "{{username}} ha creat una nova tasca {{obj_name}} a {{project_name}} provinent de US {{us_name}}", "WIKI_CREATED": "{{username}} has created a new wiki page {{obj_name}} in {{project_name}}", "MILESTONE_CREATED": "{{username}} has created a new sprint {{obj_name}} in {{project_name}}", @@ -1263,6 +1263,6 @@ "US_REMOVED_FROM_MILESTONE": "{{username}} has added the US {{obj_name}} to the backlog", "BLOCKED": "{{username}} has blocked {{obj_name}}", "UNBLOCKED": "{{username}} has unblocked {{obj_name}}", - "NEW_USER": "{{username}} has joined Taiga" + "NEW_USER": "{{username}} s'ha unit a Taiga" } } \ No newline at end of file diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index 1465eb3a..dead6855 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -36,7 +36,7 @@ "EXTERNAL_USER": "een extern gebruiker", "GENERIC_ERROR": "Een van onze Oempa Loempa's zegt {{error}}.", "IOCAINE_TEXT": "Voel je je wat overweldigd door een taak? Zorg ervoor dat anderen dit weten door op Iocaine te klikken bij het wijzigen van een taak. Je kan stapsgewijs immuun worden tegen dit (fictioneel) dodelijk gif door kleine dosissen op te nemen. Net zoals je beter kan worden in wat je doet door af en toe een extra uitdaging aan te gaan!", - "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", + "CAPSLOCK_WARNING": "Let op! Je schrijft met alleen hoofdletters en dit veld is hoofdlettergevoelig.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Deze waarde lijkt ongeldig te zijn", "TYPE_EMAIL": "Deze waarde moet een geldig emailadres bevatten", @@ -344,7 +344,7 @@ "DESCRIPTION": "Geef een korte beschrijving", "DEPRECATED": "(verouderd)", "DEPRECATED_FILE": "Verouderd?", - "ADD": "Add new attachment. {{maxFileSizeMsg}}", + "ADD": "Nieuwe bijlage toevoegen. {{maxFileSizeMsg}}", "MAX_FILE_SIZE": "[Max. grootte: {{maxFileSize}}]", "SHOW_DEPRECATED": "+ toon verouderde bijlagen", "HIDE_DEPRECATED": "- verberg verouderde bijlagen", @@ -412,7 +412,7 @@ "JITSI_CHAT_ROOM": "Jitsi", "APPEARIN_CHAT_ROOM": "AppearIn", "TALKY_CHAT_ROOM": "Talky", - "CUSTOM_CHAT_ROOM": "Custom", + "CUSTOM_CHAT_ROOM": "Op maat", "URL_CHAT_ROOM": "URL van je chat room" }, "PROJECT_PROFILE": { @@ -431,7 +431,7 @@ "REPORTS": { "TITLE": "Rapporten", "SUBTITLE": "Exporteer je project data in CSV formaat en maak je eigen rapporten", - "DESCRIPTION": "Download a CSV file or copy the generated URL and open it in your favourite text editor or spreadsheet to make your own project data reports. You will be able to visualize and analyze all your data easily.", + "DESCRIPTION": "Download een CSV bestand of kopieer de gegenereerde URL en open deze in je favoriete tekst editor of spreadsheet om je eigen rapportages te maken. Op die manier kun je al je data gemakkelijk analyseren en visualiseren.", "HELP": "Hoe kan ik dit gebruiken in mijn eigen spreadsheet?", "REGENERATE_TITLE": "Wijzig URL", "REGENERATE_SUBTITLE": "Je staat op het punt de CSV data toegang url te veranderen. De vorige url zal worden uitgeschakeld. Ben je zeker dat je ermee door wil gaan?" @@ -456,7 +456,7 @@ "ISSUE_DESCRIPTION": "Issues aangepaste velden", "ISSUE_ADD": "Voeg een aangepast veld toe in issues", "FIELD_TYPE_TEXT": "Tekst", - "FIELD_TYPE_MULTI": "Multi-line" + "FIELD_TYPE_MULTI": "Over meerdere regels" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project waardes - {{projectName}}", @@ -802,7 +802,7 @@ "PREVIOUS": "Vorige user story", "NEXT": "volgende user story", "TITLE_DELETE_ACTION": "Verwijder user story", - "LIGHTBOX_TITLE_BLOKING_US": "Ons blokkeren", + "LIGHTBOX_TITLE_BLOKING_US": "User story blokkeren", "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} taken afgewerkt", "ASSIGN": "User story toewijzen", "NOT_ESTIMATED": "Niet ingeschat", @@ -899,8 +899,8 @@ "YAXIS_LABEL": "Punten", "OPTIMAL": "Optimaal aantal openstaande punten voor sprint \"{{sprintName}}\" zou {{value}} moeten zijn", "REAL": "Reële openstaande punten voor sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_TEAM": "Incremented points by team requirements for sprint \"{{sprintName}}\" is {{value}}", - "INCREMENT_CLIENT": "Incremented points by client requirements for sprint \"{{sprintName}}\" is {{value}}" + "INCREMENT_TEAM": "Toegevoegde aantal punten door team vereisten voor sprint \"{{sprintName}}\" is {{vallue}}", + "INCREMENT_CLIENT": "Toegevoegde aantal punten door klant vereisten voor sprint \"{{sprintName}}\" is {{vallue}}" }, "TAGS": { "TOGGLE": "Zet de tag zichtbaarheid aan of af", @@ -1246,20 +1246,20 @@ "MILESTONE_UPDATED": "{{username}} heeft de sprint {{obj_name}} bijgewerkt", "US_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van de US {{obj_name}} bijgewerkt", "US_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de US {{obj_name}} gewijzigd naar {{new_value}}", - "US_UPDATED_POINTS": "{{username}} has updated '{{role_name}}' points of the US {{obj_name}} to {{new_value}}", + "US_UPDATED_POINTS": "{{username}} heeft '{{role_name}}' punten van de user story {{obj_name}} gewijzigd naar {{new_value}}", "ISSUE_UPDATED": "{{username}} heeft de eigenschap \"{{field_name}}\" van het issue {{obj_name}} bijgewerkt", "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de issue gewijzigd van {{obj_name}} naar {{new_value}}", - "TASK_UPDATED": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", - "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} to {{new_value}}", + "TASK_UPDATED": "{{username}} heeft het attribuut \"{{field_name}}\" van de taak {{obj_name}} gewijzigd naar {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} heeft het attribuut \"{{field_name}}\" van de taak {{obj_name}} gewijzigd naar {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} heeft de eigenschap \"{{field_name}}\" van de taak {{obj_name}} die behoort tot de US {{us_name}} bijgewerkt", - "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} has updated the attribute \"{{field_name}}\" of the task {{obj_name}} which belongs to the US {{us_name}} to {{new_value}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} heeft de eigenschap \"{{field_name}}\" van de taak {{obj_name}} die behoort tot de US {{us_name}} gewijzigd naar {{new_value}}", "WIKI_UPDATED": "{{username}} heeft de wiki pagina {{obj_name}} bijgewerkt", "NEW_COMMENT_US": "{{username}} heeft gereageerd op de US {{obj_name}}", "NEW_COMMENT_ISSUE": "{{username}} heeft gereageerd op het issue {{obj_name}}", "NEW_COMMENT_TASK": "{{username}} heeft gereageerd op de taak {{obj_name}}", "NEW_MEMBER": "{{project_name}} heeft een nieuw lid", "US_ADDED_MILESTONE": "{{username}} heeft de US {{obj_name}} toegevoegd aan {{sprint_name}}", - "US_MOVED": "{{username}} has moved the US {{obj_name}}", + "US_MOVED": "{{username}} heeft de user story {{obj_name}} verplaatst", "US_REMOVED_FROM_MILESTONE": "{{username}} heeft de US {{obj_name}} toegevoegd aan de Backlog", "BLOCKED": "{{username}} heeft {{obj_name}} geblokkeerd", "UNBLOCKED": "{{username}} heeft {{obj_name}} gedeblokkeerd", diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index 2424b7ca..fcc7bb46 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -125,7 +125,7 @@ "IS_CLOSED": "Zamknięte?", "STATUS": "Status", "TYPE": "Typ", - "SEVERITY": "Rygor", + "SEVERITY": "Ważność", "PRIORITY": "Priorytet", "ASSIGNED_TO": "Przydzielone do", "POINTS": "Punkty", @@ -150,7 +150,7 @@ }, "WATCHERS": { "ADD": "Dodaj obserwatora", - "TITLE": "obserwatory", + "TITLE": "obserwatorzy", "DELETE": "Usuń obserwatora", "TITLE_LIGHTBOX_DELETE_WARTCHER": "Usuwanie obserwatora..." }, @@ -476,10 +476,10 @@ "ACTION_ADD": "Dodaj nowy priorytet" }, "PROJECT_VALUES_SEVERITIES": { - "TITLE": "Rygory", - "SUBTITLE": "Zdefiniuj rygory dla zgłoszeń", - "ISSUE_TITLE": "Rygory zgłoszeń", - "ACTION_ADD": "Dodaj nowy rygor" + "TITLE": "Ważność", + "SUBTITLE": "Zdefiniuj ważność dla zgłoszeń", + "ISSUE_TITLE": "Ważność zgłoszeń", + "ACTION_ADD": "Dodaj nową ważność" }, "PROJECT_VALUES_STATUS": { "TITLE": "Status", @@ -581,7 +581,7 @@ "LABEL_US": "Domyślna wartość dla selektora statusu historyjek użytkownika", "LABEL_TASK_STATUS": "Domyśla wartość dla selektora statusu zadań", "LABEL_PRIORITY": "Domyślna wartość dla selektora priorytetu", - "LABEL_SEVERITY": "Domyślna wartość dla selektora rygoru", + "LABEL_SEVERITY": "Domyślna wartość dla selektora ważności", "LABEL_ISSUE_TYPE": "Domyślna wartość dla selektora typu zgłoszenia", "LABEL_ISSUE_STATUS": "Domyślna wartość dla selektora statusu zgłoszenia" }, @@ -613,7 +613,7 @@ "STATUS": "Status", "POINTS": "Punkty", "PRIORITIES": "Priorytety", - "SEVERITIES": "Rygory", + "SEVERITIES": "Ważność", "TYPES": "Typy", "CUSTOM_FIELDS": "Niestandardowe pola" }, @@ -626,7 +626,7 @@ "TITLE_ACTION_NEW_ROLE": "Dodaj nową rolę" }, "SUBMENU_THIDPARTIES": { - "TITLE": "Rygory" + "TITLE": "Ważność" } }, "USER": { @@ -851,7 +851,7 @@ "FINISH_DATE": "data zakończenia", "TYPE": "typ", "PRIORITY": "priorytet", - "SEVERITY": "rygor", + "SEVERITY": "ważność", "ASSIGNED_TO": "przypisane do", "WATCHERS": "obserwatorzy", "MILESTONE": "sprint", @@ -1047,7 +1047,7 @@ "LIGHTBOX_TITLE_BLOKING_ISSUE": "Blokowanie zgłoszenia", "FIELDS": { "PRIORITY": "Priorytet", - "SEVERITY": "Rygor", + "SEVERITY": "Ważność", "TYPE": "Typ" }, "CONFIRM_PROMOTE": { @@ -1064,7 +1064,7 @@ "CATEGORIES": { "TYPE": "Typy", "STATUS": "Statusy", - "SEVERITY": "Rygory", + "SEVERITY": "Ważność", "PRIORITIES": "Priorytety", "TAGS": "Tagi", "ASSIGNED_TO": "Przypisane do", @@ -1079,7 +1079,7 @@ "TABLE": { "COLUMNS": { "TYPE": "Typ", - "SEVERITY": "Rygor", + "SEVERITY": "Ważność", "PRIORITY": "Priorytet", "SUBJECT": "Temat", "STATUS": "Status", @@ -1090,14 +1090,14 @@ "TITLE_ACTION_ASSIGNED_TO": "Przypisane do", "EMPTY": { "TITLE": "Brak zgłoszeń :-)", - "SUBTITLE": "MAsz zgłoszenie?", + "SUBTITLE": "Masz zgłoszenie?", "ACTION_CREATE_ISSUE": "Utwórz nowe zgłoszenie" } } }, "ISSUE": { "PAGE_TITLE": "{{issueSubject}} - Zgłoszenie {{issueRef}} - {{projectName}}", - "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Type: {{issueType}}, Priorytet: {{issuePriority}}. Rygor: {{issueSeverity}}. Opis: {{issueDescription}}" + "PAGE_DESCRIPTION": "Status: {{issueStatus }}. Typ: {{issueType}}, Priorytet: {{issuePriority}}. Ważność: {{issueSeverity}}. Opis: {{issueDescription}}" }, "KANBAN": { "PAGE_TITLE": "Kanban - {{projectName}}", From 77b491fd0d642f425a1ad2f55b96f24099690633 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 17 Aug 2015 08:06:01 +0200 Subject: [PATCH 098/403] Fixing js error when redirecting /login for anonymous users --- app/modules/home/working-on/working-on.directive.coffee | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/modules/home/working-on/working-on.directive.coffee b/app/modules/home/working-on/working-on.directive.coffee index 2a806655..3e0cdaae 100644 --- a/app/modules/home/working-on/working-on.directive.coffee +++ b/app/modules/home/working-on/working-on.directive.coffee @@ -1,8 +1,10 @@ WorkingOnDirective = (homeService, currentUserService) -> link = (scope, el, attrs, ctrl) -> - userId = currentUserService.getUser().get("id") - - ctrl.getWorkInProgress(userId) + user = currentUserService.getUser() + # If we are not logged in the user will be null + if user + userId = user.get("id") + ctrl.getWorkInProgress(userId) return { controller: "WorkingOn", From ee6e102f7441fa05aaf80aa4afdb5d9bd1edd26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 24 Aug 2015 10:37:59 +0200 Subject: [PATCH 099/403] [i18n] Update locales --- app/locales/locale-pl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index fcc7bb46..ad2c80ca 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -743,7 +743,7 @@ "HELP_TEXT": "Jeżeli użytkownik jest już zarejestrowany w Taiga, będzie dodany automatycznie. W przeciwnym wypadku otrzyma zaproszenie." }, "CREATE_ISSUE": { - "TITLE": "Dodaj Zagadnienie" + "TITLE": "Dodaj zgłoszenie" }, "FEEDBACK": { "TITLE": "Powiedz nam coś...", From f6b9bf2cd49c16e6945aa8084667df8d2d17f808 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 5 Aug 2015 15:04:57 +0200 Subject: [PATCH 100/403] Issue #3054 - Same icon for kanban and scrum in project creation --- app/partials/project/wizard-create-project.jade | 2 +- app/styles/core/typography.scss | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/partials/project/wizard-create-project.jade b/app/partials/project/wizard-create-project.jade index 9e61a345..1d52dc48 100644 --- a/app/partials/project/wizard-create-project.jade +++ b/app/partials/project/wizard-create-project.jade @@ -10,7 +10,7 @@ form ng-value='template.id', ng-model="data.creation_template", data-required="true") label.backlog(for="template-{{ template.id }}") - span.icon.icon-backlog + span.icon( ng-class="'icon-'+template.slug") h2 {{ template.name }} p {{ template.description }} diff --git a/app/styles/core/typography.scss b/app/styles/core/typography.scss index 6e106f99..9e50fb32 100755 --- a/app/styles/core/typography.scss +++ b/app/styles/core/typography.scss @@ -251,7 +251,8 @@ a:visited { .icon-issues:before { content: 'U'; } -.icon-backlog:before { +.icon-backlog:before, +.icon-scrum:before, { content: 'R'; } .icon-iocaine:before { From bbc4a575a7705eaa696c7a6e8b4009f9d2cdcfff Mon Sep 17 00:00:00 2001 From: Brett Profitt Date: Thu, 13 Aug 2015 00:13:39 -0400 Subject: [PATCH 101/403] Added attachment previews for images. Fixes #577. --- AUTHORS.rst | 1 + CHANGELOG.md | 1 + app/coffee/modules/common/attachments.coffee | 10 ++++-- app/coffee/modules/common/lightboxes.coffee | 33 +++++++++++++++++++ app/partials/attachment/attachments.jade | 2 ++ .../lightbox/lightbox-attachment-preview.jade | 6 ++++ app/styles/modules/common/attachments.scss | 5 +++ 7 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 app/partials/common/lightbox/lightbox-attachment-preview.jade diff --git a/AUTHORS.rst b/AUTHORS.rst index 8f30a52f..4aaa06b5 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -27,3 +27,4 @@ answer newbie questions, and generally made Taiga that much better: - Florian Bezagu - Ryan Swanstrom - Chris Wilson +- Brett Profitt diff --git a/CHANGELOG.md b/CHANGELOG.md index 99576e39..7364934a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Add custom videoconference system. - Make burndown chart collapsible at the backlog panel. - Ability to choose a theme (thanks to [@astagi](https://github.com/astagi)) +- Inline viewing of image attachments (thanks to [@brettp](https://github.com/brettp)). - i18n. - Add polish (pl) translation. - Add russian (ru) translation. diff --git a/app/coffee/modules/common/attachments.coffee b/app/coffee/modules/common/attachments.coffee index 1102715d..0c521519 100644 --- a/app/coffee/modules/common/attachments.coffee +++ b/app/coffee/modules/common/attachments.coffee @@ -245,7 +245,7 @@ AttachmentsDirective = ($config, $confirm, $templates, $translate) -> module.directive("tgAttachments", ["$tgConfig", "$tgConfirm", "$tgTemplate", "$translate", AttachmentsDirective]) -AttachmentDirective = ($template, $compile, $translate) -> +AttachmentDirective = ($template, $compile, $translate, $rootScope) -> template = $template.get("attachment/attachment.html", true) templateEdit = $template.get("attachment/attachment-edit.html", true) @@ -315,6 +315,12 @@ AttachmentDirective = ($template, $compile, $translate) -> $scope.$apply -> $ctrl.removeAttachment(attachment) + $el.on "click", "div.attachment-name a", (event) -> + if null != attachment.name.match(/\.(jpe?g|png|gif|gifv|webm)/i) + event.preventDefault() + $scope.$apply -> + $rootScope.$broadcast("attachment:preview", attachment) + $scope.$on "$destroy", -> $el.off() @@ -330,4 +336,4 @@ AttachmentDirective = ($template, $compile, $translate) -> restrict: "AE" } -module.directive("tgAttachment", ["$tgTemplate", "$compile", "$translate", AttachmentDirective]) +module.directive("tgAttachment", ["$tgTemplate", "$compile", "$translate", "$rootScope", AttachmentDirective]) \ No newline at end of file diff --git a/app/coffee/modules/common/lightboxes.coffee b/app/coffee/modules/common/lightboxes.coffee index c92c176b..fa1e5965 100644 --- a/app/coffee/modules/common/lightboxes.coffee +++ b/app/coffee/modules/common/lightboxes.coffee @@ -624,3 +624,36 @@ WatchersLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationS } module.directive("tgLbWatchers", ["$tgRepo", "lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", "$compile", WatchersLightboxDirective]) + + +############################################################################# +## Attachment Preview Lighbox +############################################################################# + +AttachmentPreviewLightboxDirective = ($repo, lightboxService, lightboxKeyboardNavigationService, $template, $compile) -> + link = ($scope, $el, attrs) -> + template = $template.get("common/lightbox/lightbox-attachment-preview.html", true) + + $scope.$on "attachment:preview", (event, attachment) -> + lightboxService.open($el) + render(attachment) + + $scope.$on "$destroy", -> + $el.off() + + render = (attachment) -> + ctx = { + url: attachment.url, + title: attachment.description, + name: attachment.name + } + + html = template(ctx) + html = $compile(html)($scope) + $el.html(html) + + return { + link: link + } + +module.directive("tgLbAttachmentPreview", ["$tgRepo", "lightboxService", "lightboxKeyboardNavigationService", "$tgTemplate", "$compile", AttachmentPreviewLightboxDirective]) diff --git a/app/partials/attachment/attachments.jade b/app/partials/attachment/attachments.jade index 0cd720a8..25ada019 100644 --- a/app/partials/attachment/attachments.jade +++ b/app/partials/attachment/attachments.jade @@ -26,3 +26,5 @@ section.attachments span.text(data-type="show", translate="ATTACHMENT.SHOW_DEPRECATED") span.text.hidden(data-type="hide", translate="ATTACHMENT.HIDE_DEPRECATED") span.more-attachments-num(translate="ATTACHMENT.COUNT_DEPRECATED", translate-values="{counter: '{{ctrl.deprecatedAttachmentsCount}}'}") + + div.lightbox.lightbox-block(tg-lb-attachment-preview) \ No newline at end of file diff --git a/app/partials/common/lightbox/lightbox-attachment-preview.jade b/app/partials/common/lightbox/lightbox-attachment-preview.jade new file mode 100644 index 00000000..91932ed7 --- /dev/null +++ b/app/partials/common/lightbox/lightbox-attachment-preview.jade @@ -0,0 +1,6 @@ +.attachment-preview + a.close(href="", title="{{'COMMON.CLOSE' | translate}}") + span.icon.icon-delete + + a(href!="<%- url %>", title!="<%- title %>", target="_blank", download!="<%- name %>") + img(src!="<%- url %>") \ No newline at end of file diff --git a/app/styles/modules/common/attachments.scss b/app/styles/modules/common/attachments.scss index 556324ac..48aa96a0 100644 --- a/app/styles/modules/common/attachments.scss +++ b/app/styles/modules/common/attachments.scss @@ -183,3 +183,8 @@ color: $gray-light; } } + +.attachment-preview img { + max-height: 95vh; + max-width: 95vw; +} From 57033c6e8be3f02e394ccc19971625880bea3322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 25 Aug 2015 15:02:45 +0200 Subject: [PATCH 102/403] [i18n] Add portuguese (Brazil) (pt_BR) translation. --- .tx/config | 2 +- CHANGELOG.md | 1 + app/locales/locale-pt-br.json | 1268 +++++++++++++++++++++++++++++++++ 3 files changed, 1270 insertions(+), 1 deletion(-) create mode 100644 app/locales/locale-pt-br.json diff --git a/.tx/config b/.tx/config index 191c665f..38d247e7 100644 --- a/.tx/config +++ b/.tx/config @@ -1,6 +1,6 @@ [main] host = https://www.transifex.com -lang_map = sr@latin:sr-latn, zh-Hans:zh-hans, zh-Hant:zh-hant +lang_map = sr@latin:sr-latn, zh-Hans:zh-hans, zh-Hant:zh-hant, pt_BR:pt-br [taiga-front.locale-enjson] file_filter = app/locales/locale-.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 7364934a..99ea3606 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Inline viewing of image attachments (thanks to [@brettp](https://github.com/brettp)). - i18n. - Add polish (pl) translation. + - Add portuguese (Brazil) (pt_BR) translation. - Add russian (ru) translation. ### Misc diff --git a/app/locales/locale-pt-br.json b/app/locales/locale-pt-br.json new file mode 100644 index 00000000..91e0419c --- /dev/null +++ b/app/locales/locale-pt-br.json @@ -0,0 +1,1268 @@ +{ + "COMMON": { + "YES": "Sim", + "NO": "Não", + "LOADING": "Carregando...", + "LOADING_PROJECT": "Carregando projeto...", + "DATE": "DD MMM YYYY", + "DATETIME": "DD MMM YYYY HH:mm", + "SAVE": "Salvar", + "CANCEL": "Cancelar", + "ACCEPT": "Aceitar", + "DELETE": "Apagar", + "CREATE": "Criar", + "ADD": "Adicionar", + "COPY_TO_CLIPBOARD": "Copiar para a área de transferência: Ctrl+C", + "EDIT": "Editar", + "DRAG": "Arrastar", + "TAG_LINE": "Sua ferramenta de código aberto, gratuita e ágil.", + "TAG_LINE_2": "AME SEU PROJETO", + "BLOCK": "Bloquear", + "UNBLOCK": "Desbloquear", + "BLOCKED": "Bloqueado", + "CREATED_BY": "Criado por {{fullDisplayName}}", + "FROM": "de", + "TO": "para", + "CLOSE": "fechar", + "BLOCKED_NOTE": "Por que esta User Story foi bloqueada? ", + "BLOCKED_REASON": "Por favor, explique a razão", + "GO_HOME": "Ir ao início", + "PLUGINS": "Plugins", + "BETA": "Estamos em beta!", + "ONE_ITEM_LINE": "Um item por linha...", + "NEW_BULK": "Nova inserção em lote", + "RELATED_TASKS": "Tarefas relacionadas", + "LOGOUT": "Sair", + "EXTERNAL_USER": "um usuário externo", + "GENERIC_ERROR": "Um Oompa Loompas disse {{error}}.", + "IOCAINE_TEXT": "Se sentindo sobrecarregado por uma tarefa? Assegure-se de que os outros saibam disso clicando em Iocaine quando estiver editando a tarefa. É possível se tornar imune a essse veneno mortal (fictício) consumindo pequenas quantidades ao longo do tempo, assim como é possível ficar melhor no que faz, ocasionalmente, por assumir desafios extras!", + "CAPSLOCK_WARNING": "Seja cuidadoso! Você está escrevendo em letras maiúsculas e esse campo é case sensitive, ou seja trata com distinção letras maiúsculas das minúsculas", + "FORM_ERRORS": { + "DEFAULT_MESSAGE": "Este valor parece ser inválido.", + "TYPE_EMAIL": "Este valor deve ser um e-mail válido.", + "TYPE_URL": "Este valor deve ser uma url válida.", + "TYPE_URLSTRICT": "Este valor deve ser uma url válida.", + "TYPE_NUMBER": "Este valor deve ser um número válido.", + "TYPE_DIGITS": "Este valor deve ser dígitos.", + "TYPE_DATEISO": "Este valor deve ser uma data válida (YYYY-MM-DD).", + "TYPE_ALPHANUM": "Este valor deve ser alfanumérico.", + "TYPE_PHONE": "Este valor deveria ser um número telefônico valido.", + "NOTNULL": "Este valor não deveria ser nulo.", + "NOT_BLANK": "Esta campo não deveria esta em branco.", + "REQUIRED": "Este valor é obrigatório.", + "REGEXP": "Este valor parece ser inválido.", + "MIN": "O valor deve ser maior que ou igual a %s.", + "MAX": "Esse valor deve ser menor que ou igual a %s.", + "RANGE": "Esse valor deve ser entre %s e %s.", + "MIN_LENGTH": "Esse valor é muito curto. deve ter %s caracteres ou mais.", + "MAX_LENGTH": "Valor muito longo. O campo deve conter %s caracteres ou menos.", + "RANGE_LENGTH": "Esse comprimento de valor é inválido. Deve ser entre %s e %s caracteres de comprimento.", + "MIN_CHECK": "Você deve selecionar pelo menos %s escolhas.", + "MAX_CHECK": "Você deve selecionar %s escolhas ou menos.", + "RANGE_CHECK": "Você deve selecionar entre %s e %s escolhas.", + "EQUAL_TO": "Esse valor deveria ser o mesmo." + }, + "PICKERDATE": { + "FORMAT": "DD MMM YYYY", + "IS_RTL": "false", + "FIRST_DAY_OF_WEEK": "1", + "PREV_MONTH": "Mês Anterior", + "NEXT_MONTH": "Próximo Mês", + "MONTHS": { + "JAN": "Janeiro", + "FEB": "Fevereiro", + "MAR": "Março", + "APR": "Abril", + "MAY": "Maio", + "JUN": "Junho", + "JUL": "Julho", + "AUG": "Agosto", + "SEP": "Setembro", + "OCT": "Outubro", + "NOV": "Novembro", + "DEC": "Dezembro" + }, + "WEEK_DAYS": { + "SUN": "Domingo", + "MON": "Segunda-feira", + "TUE": "Terça-feira", + "WED": "Quarta-feira", + "THU": "Quinta-feira", + "FRI": "Sexta-feira", + "SAT": "Sábado" + }, + "WEEK_DAYS_SHORT": { + "SUN": "Dom", + "MON": "Seg", + "TUE": "Ter", + "WED": "Qua", + "THU": "Qui", + "FRI": "Sex", + "SAT": "Sab" + } + }, + "SEE_USER_PROFILE": "Ver o perfil de {{username }}", + "USER_STORY": "User Story", + "TASK": "Tarefa", + "ISSUE": "caso", + "TAGS": { + "PLACEHOLDER": "To dentro! Me tagueie....", + "DELETE": "Apagar tag", + "ADD": "Adicionar tag" + }, + "DESCRIPTION": { + "EMPTY": "Espaço vazio é tãããooo monótono... escreva algo, vai...", + "NO_DESCRIPTION": "Sem descrição ainda" + }, + "FIELDS": { + "SUBJECT": "Assunto", + "NAME": "Nome", + "URL": "URL", + "DESCRIPTION": "Descrição", + "VALUE": "Valor", + "SLUG": "Rótulo", + "COLOR": "Cor", + "IS_CLOSED": "Está fechado?", + "STATUS": "Situação", + "TYPE": "Tipo", + "SEVERITY": "Severidade", + "PRIORITY": "Prioridade", + "ASSIGNED_TO": "Atribuído a", + "POINTS": "Pontos", + "BLOCKED_NOTE": "Nota de bloqueio", + "IS_BLOCKED": "está bloqueada", + "REF": "Ref" + }, + "ROLES": { + "ALL": "Tudo" + }, + "ASSIGNED_TO": { + "NOT_ASSIGNED": "Não assinado", + "DELETE_ASSIGNMENT": "Excluir atribuição", + "REMOVE_ASSIGNED": "Remover assinatura", + "TOO_MANY": "...muitos usuários, continue filtrando", + "CONFIRM_UNASSIGNED": "Você tem certeza que deseja deixar sem ", + "TITLE_ACTION_EDIT_ASSIGNMENT": "E" + }, + "STATUS": { + "CLOSED": "Fechado", + "OPEN": "Aberto" + }, + "WATCHERS": { + "ADD": "Adicionar expectador", + "TITLE": "Observadores", + "DELETE": "Deletar observador", + "TITLE_LIGHTBOX_DELETE_WARTCHER": "Deletar observador..." + }, + "CUSTOM_ATTRIBUTES": { + "CUSTOM_FIELDS": "Campos Personalizados", + "SAVE": "Salvar Campo Personalizado", + "EDIT": "Editar Campo Personalizado", + "DELETE": "Apagar atributo personalizado", + "CONFIRM_DELETE": "Lembre-se que todos os valores deste campo personalizado serão deletados.
Tem certeza que quer continuar?" + }, + "FILTERS": { + "TITLE": "filtros", + "INPUT_PLACEHOLDER": "Assunto ou referência", + "TITLE_ACTION_FILTER_BUTTON": "procurar", + "BREADCRUMB_TITLE": "voltar para categorias", + "BREADCRUMB_FILTERS": "Filtros", + "BREADCRUMB_STATUS": "Situação" + }, + "WYSIWYG": { + "H1_BUTTON": "Primeira caixa de cabeçalho", + "H1_SAMPLE_TEXT": "Seu título aqui...", + "H2_BUTTON": "Segundo caixa de cabeçalho", + "H2_SAMPLE_TEXT": "Seu título aqui...", + "H3_BUTTON": "Terceira caixa de cabeçalho", + "H3_SAMPLE_TEXT": "Seu título aqui...", + "BOLD_BUTTON": "Negrito", + "BOLD_BUTTON_SAMPLE_TEXT": "Seu texto aqui...", + "ITALIC_BUTTON": "Itálico", + "ITALIC_SAMPLE_TEXT": "Seu texto aqui...", + "STRIKE_BUTTON": "Strike", + "STRIKE_SAMPLE_TEXT": "Seu texto aqui...", + "BULLETED_LIST_BUTTON": "Lista de Marcadores", + "BULLETED_LIST_SAMPLE_TEXT": "Seu texto aqui...", + "NUMERIC_LIST_BUTTON": "Lista Numérica", + "NUMERIC_LIST_SAMPLE_TEXT": "Seu texto aqui...", + "PICTURE_BUTTON": "Imagem", + "PICTURE_SAMPLE_TEXT": "Seu texto alternativo para a imagem aqui...", + "LINK_BUTTON": "Link", + "LINK_SAMPLE_TEXT": "Seu texto para o link vai aqui...", + "QUOTE_BLOCK_BUTTON": "Bloco de citação", + "QUOTE_BLOCK_SAMPLE_TEXT": "Seu texto aqui...", + "CODE_BLOCK_BUTTON": "Bloco de Código", + "CODE_BLOCK_SAMPLE_TEXT": "Seu texto aqui...", + "PREVIEW_BUTTON": "Pré Visualizar", + "EDIT_BUTTON": "Editar", + "MARKDOWN_HELP": "Ajuda de sintaxe markdown" + }, + "PERMISIONS_CATEGORIES": { + "SPRINTS": { + "NAME": "Sprints", + "VIEW_SPRINTS": "Ver sprints", + "ADD_SPRINTS": "Adicionar sprints", + "MODIFY_SPRINTS": "Modificar sprints", + "DELETE_SPRINTS": "Deletar Sprints" + }, + "USER_STORIES": { + "NAME": "Estórias de Uso", + "VIEW_USER_STORIES": "Ver estória de uso", + "ADD_USER_STORIES": "Adicionar estória de uso", + "MODIFY_USER_STORIES": "Modificar ", + "DELETE_USER_STORIES": "Apagar história" + }, + "TASKS": { + "NAME": "Tarefas", + "VIEW_TASKS": "Ver tarefas", + "ADD_TASKS": "Adicionar uma nova Tarefa", + "MODIFY_TASKS": "Modificar tarefa", + "DELETE_TASKS": "Apagar tarefas" + }, + "ISSUES": { + "NAME": "Casos", + "VIEW_ISSUES": "Ver casos", + "ADD_ISSUES": "Adicionar casos", + "MODIFY_ISSUES": "Modificar casos", + "DELETE_ISSUES": "Apagar casos" + }, + "WIKI": { + "NAME": "Wiki", + "VIEW_WIKI_PAGES": "Exibir páginas da wiki", + "ADD_WIKI_PAGES": "Adicionar páginas wiki", + "MODIFY_WIKI_PAGES": "Modificar páginas wiki", + "DELETE_WIKI_PAGES": "Apagar páginas wiki", + "VIEW_WIKI_LINKS": "Exibir links da wiki", + "ADD_WIKI_LINKS": "Adicionar links da wiki", + "DELETE_WIKI_LINKS": "Apagar links da wiki" + } + }, + "META": { + "PAGE_TITLE": "Taiga", + "PAGE_DESCRIPTION": "Taiga é uma plataforma de gerenciamento de projetos para startups e desenvolvedores ágeis & designers que querem uma simples, bela ferramenta que faça o trabalho ser agradável." + } + }, + "LOGIN": { + "PAGE_TITLE": "Login - Taiga", + "PAGE_DESCRIPTION": "Entrando no Taiga, uma plataforma de gerenciamento de projetos para startups e desenvolvedores ágeis & designers que desejam uma ferramenta bela e simples que torne o trabalho realmente agradável." + }, + "AUTH": { + "INVITED_YOU": "convidou você para entrar no projeto", + "NOT_REGISTERED_YET": "Não cadastrado ainda?", + "REGISTER": "Cadastrar", + "CREATE_ACCOUNT": "crie sua conta grátis aqui" + }, + "LOGIN_COMMON": { + "HEADER": "Eu já tenho um login Taiga", + "PLACEHOLDER_AUTH_NAME": "Nome de usuário ou email (case sensitive)", + "LINK_FORGOT_PASSWORD": "Esqueceu?", + "TITLE_LINK_FORGOT_PASSWORD": "Você esqueceu sua senha?", + "ACTION_ENTER": "Entre", + "ACTION_SIGN_IN": "Identifique-se", + "PLACEHOLDER_AUTH_PASSWORD": "Senha (case sensitive)" + }, + "LOGIN_FORM": { + "ERROR_AUTH_INCORRECT": "De acordo com nossos Oompa Loompas, seu nome de usuario/email ou senha estão incorretos.", + "SUCCESS": "Nossos Oompa Loompas estão felizes, bem vindo ao Taiga." + }, + "REGISTER": { + "PAGE_TITLE": "Cadastre-se - Taiga", + "PAGE_DESCRIPTION": "Crie sua conta no Taiga, uma plataforma de gerenciamento de projetos para startups e desenvolvedores ágeis & designers que desejam uma ferramenta bela e simples que torne o trabalho realmente agradável.\"" + }, + "REGISTER_FORM": { + "TITLE": "Registre uma nova conta Taiga (Grátis)", + "PLACEHOLDER_NAME": "Escolha um nome de usuário (case sensitive)", + "PLACEHOLDER_FULL_NAME": "Insira seu nome completo", + "PLACEHOLDER_EMAIL": "Seu email", + "PLACEHOLDER_PASSWORD": "Escolha uma senha (case sensitive)", + "ACTION_SIGN_UP": "Registre-se", + "TITLE_LINK_LOGIN": "Identifique-se", + "LINK_LOGIN": "Você já está registrado? Idenfique-se" + }, + "FORGOT_PASSWORD": { + "PAGE_TITLE": "Esqueceu sua senha - Taiga", + "PAGE_DESCRIPTION": "Informe seu nome de usuário ou email para receber uma nova senha e ter acesso ao Taiga novamente." + }, + "FORGOT_PASSWORD_FORM": { + "TITLE": "Opaaa, você esqueceu sua senha?", + "SUBTITLE": "Entre seu usuário ou email para conseguir uma senha nova", + "PLACEHOLDER_FIELD": "Nome de usuário ou email", + "ACTION_RESET_PASSWORD": "Resetar Senha", + "LINK_CANCEL": "Nããão, me leve de volta. Acho que me lembrei.", + "SUCCESS": "Verifique sua conta de email
Enviamos um email com as instruções para configurar uma nova senha", + "ERROR": "Segundo nossos Oompa Loompas, você ainda não está inscrito." + }, + "CHANGE_PASSWORD": { + "PAGE_TITLE": "Alterar sua senha - Taiga", + "PAGE_DESCRIPTION": "Escolher nova senha para o seu Taiga e hey!, você deveria comer comida rica em ferro, é ótimo para o cérebro :P", + "SECTION_NAME": "Alterar senha", + "FIELD_CURRENT_PASSWORD": "Senha atual", + "PLACEHOLDER_CURRENT_PASSWORD": "Sua senha atual (ou vazio caso ainda não tenha uma senha)", + "FIELD_NEW_PASSWORD": "Nova senha", + "PLACEHOLDER_NEW_PASSWORD": "Digite a nova senha", + "FIELD_RETYPE_PASSWORD": "Redigite a nova senha", + "PLACEHOLDER_RETYPE_PASSWORD": "Digite novamente a sua nova senha", + "ERROR_PASSWORD_MATCH": "As senhas não coincidem" + }, + "CHANGE_PASSWORD_RECOVERY_FORM": { + "TITLE": "Criar um novo passe Taiga", + "SUBTITLE": "Hey, você deveria comer comida rica em ferro, é ótimo para o cérebro :P", + "PLACEHOLDER_RECOVER_PASSWORD_TOKEN": "Recuperar token de senha", + "LINK_NEED_TOKEN": "Precisa de um?", + "TITLE_LINK_NEED_TOKEN": "Você precisa de um token para recuperar sua senha porque se esqueceu dela?", + "PLACEHOLDER_NEW_PASSWORD": "Nova senha", + "PLACEHOLDER_RE_TYPE_NEW_PASSWORD": "Redigite a nova senha", + "ACTION_RESET_PASSWORD": "Resetar Senha", + "SUCCESS": "Nossos Oompa Loompas salvaram sua nova senha.
Tente identificar-se com ela." + }, + "INVITATION": { + "PAGE_TITLE": "Aceitando um convite - Taiga", + "PAGE_DESCRIPTION": "Aceitar o convite para participar de um projeto no Taiga, uma plataforma de gerenciamento de projetos para startups e desenvolvedores ágeis & designers que desejam uma ferramenta bela e simples que torne o trabalho realmente agradável." + }, + "INVITATION_LOGIN_FORM": { + "NOT_FOUND": "Opa, temos um problema
Nossos Oompa Loompas não conseguiram encontrar seu convite.", + "SUCCESS": "Você ingressou com sucesso nesse projeto, Seja bem vindo ao projeto {{project_name}}", + "ERROR": "De acordo com nossos Oompa Loompas, você não está inscrito ou digitou uma senha inválida." + }, + "HOME": { + "PAGE_TITLE": "Início - Taiga", + "PAGE_DESCRIPTION": "A página inicial do Taiga contém seus projetos principais e todos as user stories atribuídas ou assistidas por você, tarefas e casos", + "EMPTY_WATCHING": "Siga os Projetos, User Stories, Tarefas, casos, etc., sobre os quais você quer manter-se informado :)", + "EMPTY_PROJECT_LIST": "Você ainda não tem projetos", + "WORKING_ON_SECTION": "Trabalhando em", + "WATCHING_SECTION": "Observando" + }, + "PROJECTS": { + "PAGE_TITLE": "Meus projetos - Taiga", + "PAGE_DESCRIPTION": "Uma lista com todos os seus projetos, você pode reorganizá-los ou criar um novo.", + "MY_PROJECTS": "Meus Projetos" + }, + "ATTACHMENT": { + "SECTION_NAME": "anexos", + "TITLE": "{{ fileName }} enviado em {{ date }}", + "DESCRIPTION": "Escreva uma curta descrição", + "DEPRECATED": "(obsoleto)", + "DEPRECATED_FILE": "Obsoleto?", + "ADD": "Adicionar novo anexo. {{maxFileSizeMsg}}", + "MAX_FILE_SIZE": "[Tamanho Máximo: {{maxFileSize}}]", + "SHOW_DEPRECATED": "+ mostrar anexos deprecados", + "HIDE_DEPRECATED": "- esconder anexos obsoletos", + "COUNT_DEPRECATED": "({{ counter }} deprecados)", + "MAX_UPLOAD_SIZE": "Tamanho máximo de upload é {{maxFileSize}}", + "DATE": "DD MMM YYYY [at] hh:mm", + "ERROR_UPLOAD_ATTACHMENT": "Não fomos capazes de carregar '{{fileName}}'.\n{{errorMessage}}", + "TITLE_LIGHTBOX_DELETE_ATTACHMENT": "Apagar anexo...", + "MSG_LIGHTBOX_DELETE_ATTACHMENT": "o anexo '{{fileName}}'", + "ERROR_DELETE_ATTACHMENT": "Não fomos capazes de apagar: {{errorMessage}}", + "FIELDS": { + "IS_DEPRECATED": "está obsoleto" + } + }, + "PAGINATION": { + "PREVIOUS": "Ant", + "NEXT": "Próximo" + }, + "ADMIN": { + "COMMON": { + "TITLE_ACTION_EDIT_VALUE": "Editar valor", + "TITLE_ACTION_DELETE_VALUE": "Apagar valor" + }, + "HELP": "Você precisa de ajuda? Verifique nossa pagina de suporte!", + "PROJECT_DEFAULT_VALUES": { + "TITLE": "Valores Padrão", + "SUBTITLE": "Seleciona valores default para todos os seletores" + }, + "MEMBERSHIPS": { + "TITLE": "Gerenciar Membros", + "PAGE_TITLE": "Filiados - {{projectName}}", + "ADD_BUTTON": "+ Novo Membro", + "ADD_BUTTON_TITLE": "Adicionar novo membro" + }, + "PROJECT_EXPORT": { + "TITLE": "Exportar", + "SUBTITLE": "Exporte seu projeto para guardar um backup ou para criar um novo a partir deste.", + "EXPORT_BUTTON": "Exportar", + "EXPORT_BUTTON_TITLE": "Exportar seu projeto", + "LOADING_TITLE": "Estamos gernado o arquivo de dump", + "DUMP_READY": "Seu arquivo de dump está pronto!", + "LOADING_MESSAGE": "Por favor, não feche esta pagina.", + "ASYNC_MESSAGE": "Enviaremos um email para você assim que estiver pronto.", + "SYNC_MESSAGE": "Se o download não iniciar automáticamente clique aqui", + "ERROR": "Nossos Oompa Loopmas tiveram alguns problemas gerando o dump. Por favor, tente novamente.", + "ERROR_BUSY": "Desculpe, nossos Oompa Loompas estão muito ocupados neste instante. Tente novamente em alguns minutos.", + "ERROR_MESSAGE": "Nossos Oompa Loompas tiveram alguns problemas gerando o seu dump: {{message}}" + }, + "MODULES": { + "TITLE": "Modulos", + "ENABLE": "Habilitar", + "DISABLE": "Desabilitar", + "BACKLOG": "Backlog", + "BACKLOG_DESCRIPTION": "Gerencie suas estorias de uso para manter uma visualização organizada de trabalhos futuros e priorizados.", + "KANBAN": "Kanban", + "KANBAN_DESCRIPTION": "Organize seu projeto de um jeito \"lean\" com esse mural", + "ISSUES": "Casos", + "ISSUES_DESCRIPTION": "Acompanhe os bugs, questões e melhorias relacionadas ao seu projeto. Não perca nada!", + "WIKI": "Wiki", + "WIKI_DESCRIPTION": "Adicione, modifique ou apague conteúdo em colaboração com outras pessoas. Este é o local certo pra documentação do seu projeto.", + "MEETUP": "Reunião", + "MEETUP_DESCRIPTION": "Escolha seu sistema de vídeo conferência. Até desenvolvedores precisam de contato cara a cara.", + "SELECT_VIDEOCONFERENCE": "Selecione um sistema de video conferência", + "SALT_CHAT_ROOM": "Se você quiser, pode acrescentar um 'salt code' para o nome da sala de bate-papo", + "JITSI_CHAT_ROOM": "Jitsi", + "APPEARIN_CHAT_ROOM": "AppearIn", + "TALKY_CHAT_ROOM": "Talky", + "CUSTOM_CHAT_ROOM": "Personalizar", + "URL_CHAT_ROOM": "URL da sua sala de bate-papo" + }, + "PROJECT_PROFILE": { + "PAGE_TITLE": "{{sectionName}} - Perfil do projeto - {{projectName}}", + "PROJECT_DETAILS": "Detalhes do projeto", + "PROJECT_NAME": "Nome do projeto", + "PROJECT_SLUG": "Slug do projeto", + "NUMBER_SPRINTS": "Numero de sprints", + "NUMBER_US_POINTS": "Numero pontos EU", + "TAGS": "Tags", + "DESCRIPTION": "Descrição", + "PUBLIC_PROJECT": "Projeto Publico", + "PRIVATE_PROJECT": "Projeto Privado", + "DELETE": "Apagar este projeto" + }, + "REPORTS": { + "TITLE": "Relatórios", + "SUBTITLE": "Exporte os dados do seu projeto no formato CSV e faça seus próprios relatórios.", + "DESCRIPTION": "Baixe o arquivo CSV ou copie a URL gerada e abra no seu editor de texto favorito ou planilha para fazer seu próprio relatório. Você poderá visualizar e analisar todos os seus dados facilmente.", + "HELP": "Como utilizar isto em minha própria planilha?", + "REGENERATE_TITLE": "Mudar URL", + "REGENERATE_SUBTITLE": "Você está prestes a alterar a url de acesso a dados do CSV. A URL anterior será desabilitada. Você está certo disso?" + }, + "CSV": { + "SECTION_TITLE_US": "Relatórios de Estória de Uso", + "SECTION_TITLE_TASK": "relatórios de tarefas", + "SECTION_TITLE_ISSUE": "relatórios de casos", + "DOWNLOAD": "Baixar CSV", + "URL_FIELD_PLACEHOLDER": "Por favor, gere novamente a url do CSV", + "TITLE_REGENERATE_URL": "Regerar URL CSV", + "ACTION_GENERATE_URL": "Gerar URL", + "ACTION_REGENERATE": "Regenerar" + }, + "CUSTOM_FIELDS": { + "TITLE": "Campos Personalizados", + "SUBTITLE": "Especificar campos personalizados para estórias de uso, tarefas e casos", + "US_DESCRIPTION": "Campos personalizados das Estorias de Uso", + "US_ADD": "Adicionar campo personalizado nas estórias de uso", + "TASK_DESCRIPTION": "Campos personalizados das Tarefas\n", + "TASK_ADD": "Adicionar campos personalizados na tarefa", + "ISSUE_DESCRIPTION": "Campos personalizados dos casos", + "ISSUE_ADD": "Adicionar um campo personalizado no caso", + "FIELD_TYPE_TEXT": "Texto", + "FIELD_TYPE_MULTI": "Multi-linha" + }, + "PROJECT_VALUES": { + "PAGE_TITLE": "{{sectionName}} - Valores do projeto - {{projectName}}", + "REPLACEMENT": "Todos os itens com este valor serão modificados para", + "ERROR_DELETE_ALL": "Você não pode apagar todos os valores." + }, + "PROJECT_VALUES_POINTS": { + "TITLE": "Pontos", + "SUBTITLE": "Especifique pontos que podem estimar suas User Stories", + "US_TITLE": "Pontos de User Stories", + "ACTION_ADD": "Adicionar novo ponto" + }, + "PROJECT_VALUES_PRIORITIES": { + "TITLE": "Prioridades", + "SUBTITLE": "Especifique as prioridades que seus casos terão", + "ISSUE_TITLE": "Prioridades do caso", + "ACTION_ADD": "Adicionar nova prioridade" + }, + "PROJECT_VALUES_SEVERITIES": { + "TITLE": "Seriedades", + "SUBTITLE": "Especifique a severidade que seus casos terão", + "ISSUE_TITLE": "Seriedades do caso", + "ACTION_ADD": "Adicionar nova severidade" + }, + "PROJECT_VALUES_STATUS": { + "TITLE": "Situação", + "SUBTITLE": "Especifique os status pelos quais suas user stories, tarefas e casos passarão", + "US_TITLE": "Estados das Users Strories", + "TASK_TITLE": "Estados da tarefa", + "ISSUE_TITLE": "Estados do caso" + }, + "PROJECT_VALUES_TYPES": { + "TITLE": "Tipos", + "SUBTITLE": "Especifique os tipos que seu caso pode ser", + "ISSUE_TITLE": "Tipos de casos", + "ACTION_ADD": "Adicionar novo {{objName}}" + }, + "ROLES": { + "PAGE_TITLE": "Funções - {{projectName}}", + "WARNING_NO_ROLE": "Seja cuidadoso, nenhuma função em seu projeto será capaz de estimar o valor dos pontos para as histórias de usuários", + "HELP_ROLE_ENABLED": "Quando habilitado, membros atribuídos a esta função serão capazes de estimar valores para user stories", + "COUNT_MEMBERS": "{{ role.members_count }} membros com a mesma função", + "TITLE_DELETE_ROLE": "Excluir Função", + "REPLACEMENT_ROLE": "Todos os usuários com essa função serão movidos para", + "WARNING_DELETE_ROLE": "Seja cuidadoso, todas as estimativas para as funções serão removidas.", + "ERROR_DELETE_ALL": "Você não pode apagar todos os valores", + "EXTERNAL_USER": "Usuário externo" + }, + "THIRD_PARTIES": { + "SECRET_KEY": "Chave secreta", + "PAYLOAD_URL": "URL da Payload", + "VALID_IPS": "IPs de origem válidos (separados por vírgulas)" + }, + "BITBUCKET": { + "SECTION_NAME": "Bitbucket", + "PAGE_TITLE": "Bitbucket - {{projectName}}", + "INFO_VERIFYING_IP": "Requisições do Bitbucket não são assinadas, ou seja, a melhor maneira de verificar a origem é por IP. Se o campo estiver vazio não será realizada verificação de IP." + }, + "GITLAB": { + "SECTION_NAME": "Gitlab", + "PAGE_TITLE": "Gitlab - {{projectName}}", + "INFO_VERIFYING_IP": "Requisições do Gitlab não são assinadas, ou seja, a melhor maneira de verificar a origem é por IP. Se o campo estiver vazio não será realizada verificação de IP." + }, + "GITHUB": { + "SECTION_NAME": "Github", + "PAGE_TITLE": "Github - {{projectName}}" + }, + "WEBHOOKS": { + "PAGE_TITLE": "Webhooks - {{projectName}}", + "SECTION_NAME": "Webhooks", + "SUBTITLE": "Webhooks notificam serviços externos sobre eventos no Taiga, como comentários, histórias de usuarios....", + "ADD_NEW": "Adicionar um Novo Webhook", + "TYPE_NAME": "Digite o nome do serviço", + "TYPE_PAYLOAD_URL": "Digite a url do serviço Payload", + "TYPE_SERVICE_SECRET": "Escreva a palavra segredo do serviço", + "SAVE": "Salvar Webhook", + "CANCEL": "Cancelar Webhook", + "SHOW_HISTORY": "(Mostrar história)", + "TEST": "Testar Webhook", + "EDIT": "Editar Webhook", + "DELETE": "Excluir Webhook", + "REQUEST": "Solicitação", + "RESEND_REQUEST": "Reenviar pedido", + "HEADERS": "Cabeçalhos", + "PAYLOAD": "Payload", + "RESPONSE": "Resposta", + "DATE": "DD MMM YYYY [at] hh:mm:ss", + "ACTION_HIDE_HISTORY": "(Esconder história)", + "ACTION_HIDE_HISTORY_TITLE": "Esconder os detalhes da história", + "ACTION_SHOW_HISTORY": "(Mostrar história)", + "ACTION_SHOW_HISTORY_TITLE": "Mostrar detalhes da história", + "WEBHOOK_NAME": "Webhook '{{name}}'" + }, + "CUSTOM_ATTRIBUTES": { + "PAGE_TITLE": "{{sectionName}} - Atributos personalizados - {{projectName}}", + "ADD": "Adicionar campos personalizados", + "EDIT": "Editar Campo Personalizado", + "DELETE": "Deletar campo personalizado", + "SAVE_TITLE": "Salvar Campo Personalizado", + "CANCEL_TITLE": "Cancelar criação", + "SET_FIELD_NAME": "Definir nome do seu campo personalizados", + "SET_FIELD_DESCRIPTION": "Definir a descrição do seu campo personalizado", + "ACTION_UPDATE": "Atualizar campo personalizado", + "ACTION_CANCEL_EDITION": "Cancelar edição" + }, + "MEMBERSHIP": { + "COLUMN_MEMBER": "Membro", + "COLUMN_ADMIN": "Administrador", + "COLUMN_ROLE": "Função", + "COLUMN_STATUS": "Situação", + "STATUS_ACTIVE": "Ativo", + "STATUS_PENDING": "Pendente", + "DELETE_MEMBER": "Apagar membro", + "SUCCESS_SEND_INVITATION": "Enviamos novamente um convite para '{{email}}'.", + "ERROR_SEND_INVITATION": "Nós não enviamos o convite.", + "SUCCESS_DELETE": "Nós deletamos {{message}}.", + "ERROR_DELETE": "Nós não fomos capaz de deletar {{message}}.", + "DEFAULT_DELETE_MESSAGE": "o convite para {{email}}" + }, + "DEFAULT_VALUES": { + "LABEL_POINTS": "Valores padrões para o seletor de pontos", + "LABEL_US": "Valor padrão para seletor de status da US", + "LABEL_TASK_STATUS": "Valor padrão para seletor de estatus de tarefa", + "LABEL_PRIORITY": "Valor padão para seletor de prioridade", + "LABEL_SEVERITY": "Valor padrão para seletor de severidade", + "LABEL_ISSUE_TYPE": "Valor padrão para seletor de tipo de caso", + "LABEL_ISSUE_STATUS": "Valor padrão para seletor de estatus de caso" + }, + "STATUS": { + "PLACEHOLDER_WRITE_STATUS_NAME": "Digite um nome para o novo estatus" + }, + "TYPES": { + "PLACEHOLDER_WRITE_NAME": "Escreva o nome do novo elemento" + }, + "US_STATUS": { + "ACTION_ADD_STATUS": "Adicionar novo estatus", + "IS_ARCHIVED_COLUMN": "Está arquivado?", + "WIP_LIMIT_COLUMN": "Limite WIP", + "PLACEHOLDER_WRITE_NAME": "Digite um nome para o novo estatus" + }, + "MENU": { + "TITLE": "Administrador", + "PROJECT": "Projeto", + "ATTRIBUTES": "Atributos", + "MEMBERS": "Membros", + "PERMISSIONS": "Permissões", + "INTEGRATIONS": "Integrações", + "PLUGINS": "Plugins" + }, + "SUBMENU_PROJECT_ATTRIBUTES": { + "TITLE": "Atributos" + }, + "SUBMENU_PROJECT_VALUES": { + "STATUS": "Situação", + "POINTS": "Pontos", + "PRIORITIES": "Prioridades", + "SEVERITIES": "Seriedades", + "TYPES": "Tipos", + "CUSTOM_FIELDS": "Campos personalizados" + }, + "SUBMENU_PROJECT_PROFILE": { + "TITLE": "Perfil do Projeto" + }, + "SUBMENU_ROLES": { + "TITLE": "Funções", + "ACTION_NEW_ROLE": "+ Nova Função", + "TITLE_ACTION_NEW_ROLE": "Adicionar nova função" + }, + "SUBMENU_THIDPARTIES": { + "TITLE": "Serviços" + } + }, + "USER": { + "PROFILE": { + "PAGE_TITLE": "{{userFullName}} (@{{userUsername}})", + "EDIT": "Editar Perfil", + "FOLLOW": "Seguir", + "PROJECTS": "Projetos", + "CLOSED_US": "US Fechadas", + "CONTACTS": "Contatos", + "REPORT": "Reportar Abuso", + "ACTIVITY_TAB": "Aba de Atividades", + "PROJECTS_TAB": "Aba de Projetos", + "CONTACTS_TAB": "Aba de Contatos", + "FAVORITES_TAB": "Aba de Favoritos", + "CONTACTS_EMPTY": "{{username}} ainda não tem nenhum contato", + "CURRENT_USER_CONTACTS_EMPTY": "Você não tem nenhum contato", + "CURRENT_USER_CONTACTS_EMPTY_EXPLAIN": "As pessoas que trabalahm na Taiga serão seus contatos automaticamente", + "PROJECTS_EMPTY": "{{username}} ainda não tem projetos" + }, + "PROFILE_SIDEBAR": { + "TITLE": "Seu perfil", + "DESCRIPTION": "Pessoas podem ver tudo o que você faz e seu desempenho. Adicione uma boa biografia para aprimorar sua informação.", + "ADD_INFO": "Editar sua biografia" + } + }, + "PROJECT": { + "PAGE_TITLE": "{{projectName}}", + "WELCOME": "Bem vindo", + "SECTION_PROJECTS": "Projetos", + "HELP": "Reordene seus projetos para colocar no topo os mais usados.
Os 10 primeiros projetos aparecerão na lista de projetos da barra de navegação superior.", + "PRIVATE": "Projeto Privado", + "STATS": { + "PROJECT": "projetos
pontos", + "DEFINED": "pontos
definidos", + "ASSIGNED": "pontos
com designação", + "CLOSED": "pontos
fechados" + }, + "SECTION": { + "SEARCH": "Procurar", + "TIMELINE": "Linha do Tempo", + "BACKLOG": "Backlog", + "KANBAN": "Kanban", + "ISSUES": "Casos", + "WIKI": "Wiki", + "TEAM": "Time", + "MEETUP": "Reunião", + "ADMIN": "Administrador" + }, + "NAVIGATION": { + "SECTION_TITLE": "Seus projetos", + "PLACEHOLDER_SEARCH": "Procurar em...", + "ACTION_CREATE_PROJECT": "Criar projeto", + "ACTION_IMPORT_PROJECT": "Importar projeto", + "SEE_MORE_PROJECTS": "Ver mais projetos", + "TITLE_CREATE_PROJECT": "Criar projeto", + "TITLE_IMPORT_PROJECT": "Importar projeto", + "TITLE_PRVIOUS_PROJECT": "Mostrar projetos prévios", + "TITLE_NEXT_PROJECT": "Mostrar os próximos projetos", + "HELP_TITLE": "Página de Suporte do Taiga", + "HELP": "Ajuda", + "FEEDBACK_TITLE": "Enviar feedback", + "FEEDBACK": "Feedback", + "NOTIFICATIONS_TITLE": "Editar suas configurações de notificações", + "NOTIFICATIONS": "Notificações", + "ORGANIZATIONS_TITLE": "Edite suas organizações", + "ORGANIZATIONS": "Editar organizações", + "SETTINGS_TITLE": "Editar suas configurações", + "SETTINGS": "Configurações", + "VIEW_PROFILE_TITLE": "Ver perfil", + "VIEW_PROFILE": "Ver perfil", + "EDIT_PROFILE_TITLE": "Edit seu perfil", + "EDIT_PROFILE": "Editar Perfil", + "CHANGE_PASSWORD_TITLE": "Alterar senha", + "CHANGE_PASSWORD": "Alterar senha", + "DASHBOARD_TITLE": "Painel", + "DISCOVER_TITLE": "Descobrir projetos em destaques", + "DISCOVER": "Descubra", + "ACTION_REORDER": "Seguro e arraste para ordenar" + }, + "IMPORT": { + "TITLE": "Importando Projeto", + "UPLOADING_FILE": "Enviando arquivo de dump", + "DESCRIPTION": "Este processo pode levar algum tempo, mantenha a janela aberta por favor.", + "ASYNC_IN_PROGRESS_TITLE": "Nossos Oompa Loompas estão importando seu projeto", + "ASYNC_IN_PROGRESS_MESSAGE": "Este processo pode levar alguns minutos
Enviaremos um email a você assim que estiver pronto", + "UPLOAD_IN_PROGRESS_MESSAGE": "Enviado {{uploadedSize}} de {{totalSize}}", + "ERROR": "Nossos Oompa Loompas tiveram alguns problemas importando os dados do seu dump. Tente novamente.", + "ERROR_TOO_MANY_REQUEST": "Desculpe, nossos Oompa Loompas estão muito ocupados neste instante. Tente novamente em alguns minutos.", + "ERROR_MESSAGE": "Nossos Oompa Loompas tiveram alguns problemas ao importar seu arquivo de despejo: {{error_message}}", + "ERROR_MAX_SIZE_EXCEEDED": "'{{fileName}}' ({{fileSize}}) é muito pesado para nossos Oompa Loompas, tente algo menor que ({{maxFileSize}})", + "SYNC_SUCCESS": "Seu projeto foi importado com sucesso" + } + }, + "LIGHTBOX": { + "DELETE_ACCOUNT": { + "SECTION_NAME": "Apagar conta no Taiga", + "CONFIRM": "Você tem certeza que quer apagar sua conta Taiga?", + "SUBTITLE": "Nós vamos sentir sua falta! :-(", + "NEWSLETTER_LABEL_TEXT": "Eu não quero receber mais os informativos" + }, + "DELETE_PROJECT": { + "TITLE": "Apagar projeto", + "QUESTION": "Você tem certeza que quer apagar este projeto?", + "SUBTITLE": "Todas as informações do projeto (estórias de uso, tarefas, casos, sprints e páginas de wiki) serão perdidos! :-(", + "CONFIRM": "Sim, eu tenho certeza" + }, + "ASSIGNED_TO": { + "SELECT": "Selecionar assinalados para", + "SEARCH": "Procurar por usuários" + }, + "ADD_MEMBER": { + "TITLE": "Novo Membro", + "HELP_TEXT": "Se os usuários já estiverem registrados no Taiga, eles serão adicionados automaticamente. Caso contrário, eles receberão um convite." + }, + "CREATE_ISSUE": { + "TITLE": "Adicionar caso" + }, + "FEEDBACK": { + "TITLE": "Diga-nos algo...", + "COMMENT": "...um problema, algumas sugestões, algo legal... ou até seu pior pesadelo com Taiga", + "ACTION_SEND": "Enviar feedback" + }, + "SEARCH": { + "TITLE": "Procurar", + "PLACEHOLDER_SEARCH": "O que você está procurando?" + }, + "ADD_EDIT_SPRINT": { + "TITLE": "Novo Sprint", + "PLACEHOLDER_SPRINT_NAME": "nome do Sprint", + "PLACEHOLDER_SPRINT_START": "Inicio Estimado", + "PLACEHOLDER_SPRINT_END": "Estimativa de Termino", + "ACTION_DELETE_SPRINT": "Você quer apagar este Sprint?", + "TITLE_ACTION_DELETE_SPRINT": "apagar sprint", + "LAST_SPRINT_NAME": "último sprint é {{lastSprint}} ;-) " + }, + "CREATE_EDIT_TASK": { + "TITLE": "Nova tarefa", + "PLACEHOLDER_SUBJECT": "Um assunto da tarefa", + "PLACEHOLDER_STATUS": "Situação da Tarefa", + "OPTION_UNASSIGNED": "Não assinalado", + "PLACEHOLDER_SHORT_DESCRIPTION": "Escreva uma curta descrição", + "ACTION_EDIT": "Editar tarefa" + }, + "CREATE_EDIT_US": { + "TITLE": "Nova EU", + "PLACEHOLDER_DESCRIPTION": "Por favor, adicione um texto descritivo para ajudar outras pessoas a entenderem melhor esta EU", + "NEW_US": "Nova user story", + "EDIT_US": "Editar user story" + }, + "DELETE_SPRINT": { + "TITLE": "Apagar Sprint" + }, + "CREATE_MEMBER": { + "PLACEHOLDER_INVITATION_TEXT": "(Opcional) Adicione uma mensagem de texto ao convite. Diga algo animador para os novos membros ;-)", + "PLACEHOLDER_TYPE_EMAIL": "Digite um Email" + } + }, + "US": { + "PAGE_TITLE": "{{userStorySubject}} - User Story {{userStoryRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Estado: {{userStoryStatus }}. Completos {{userStoryProgressPercentage}}% ({{userStoryClosedTasks}} de {{userStoryTotalTasks}} tarefas encerradas). Pontos: {{userStoryPoints}}. Descrição: {{userStoryDescription}}", + "SECTION_NAME": "Detalhes de User Story", + "LINK_TASKBOARD": "Quadro de Tarefas", + "TITLE_LINK_TASKBOARD": "Ir para o quadro de tarefas", + "TOTAL_POINTS": "total", + "ADD": "+ Adicionar uma nova User Story", + "ADD_BULK": "Adicionar User Stories em lote", + "PROMOTED": "Esta estória de uso foi promovida do caso:", + "TITLE_LINK_GO_TO_ISSUE": "Ir para caso", + "EXTERNAL_REFERENCE": "Esta EU foi criada de", + "GO_TO_EXTERNAL_REFERENCE": "Ir para a origem", + "BLOCKED": "Esta user story está bloqueada", + "PREVIOUS": "user story anterior", + "NEXT": "proxima user story", + "TITLE_DELETE_ACTION": "Apagar user story", + "LIGHTBOX_TITLE_BLOKING_US": "Bloqueando user story", + "TASK_COMPLETED": "{{totalClosedTasks}}/{{totalTasks}} tarefas completas", + "ASSIGN": "Atribuir User Story", + "NOT_ESTIMATED": "Não estimado", + "TOTAL_US_POINTS": "Pontos totais de US", + "FIELDS": { + "TEAM_REQUIREMENT": "Requisitos da Equipe", + "CLIENT_REQUIREMENT": "Requisitos do Cliente", + "FINISH_DATE": "Data de término" + } + }, + "COMMENTS": { + "DELETED_INFO": "Comentário apagado por {{user}} em {{date}}", + "TITLE": "Comentários", + "COMMENT": "Comentário", + "TYPE_NEW_COMMENT": "Escreva um novo comentário aqui", + "SHOW_DELETED": "Mostrar comentários apagados", + "HIDE_DELETED": "Esconder comentário apagado", + "RESTORE": "Restaurar comentário" + }, + "ACTIVITY": { + "SHOW_ACTIVITY": "Exibir atividade", + "DATETIME": "DD MMM YYYY HH:mm", + "SHOW_MORE": "+ Mostrar entradas anteriores (mais {{showMore}})", + "TITLE": "Atividade", + "REMOVED": "removido", + "ADDED": "adicionado", + "US_POINTS": "pontos EU ({{name}})", + "NEW_ATTACHMENT": "novo anexo", + "DELETED_ATTACHMENT": "apagar anexo", + "UPDATED_ATTACHMENT": "anexo atualizado {{filename}}", + "DELETED_CUSTOM_ATTRIBUTE": "apagar atributo personalizado", + "SIZE_CHANGE": "Feito {size, plural, one{one change} other{# changes}}", + "VALUES": { + "YES": "sim", + "NO": "não", + "EMPTY": "vazio", + "UNASSIGNED": "não atribuído" + }, + "FIELDS": { + "SUBJECT": "assunto", + "NAME": "nome", + "DESCRIPTION": "descrição", + "CONTENT": "conteúdo", + "STATUS": "Situação", + "IS_CLOSED": "está fechado", + "FINISH_DATE": "Data de término", + "TYPE": "Digite", + "PRIORITY": "prioridade", + "SEVERITY": "Severidade", + "ASSIGNED_TO": "Assinado à", + "WATCHERS": "Observadores", + "MILESTONE": "sprint", + "USER_STORY": "user story", + "PROJECT": "projeto", + "IS_BLOCKED": "está bloqueada", + "BLOCKED_NOTE": "Nota de bloqueio", + "POINTS": "pontos", + "CLIENT_REQUIREMENT": "requisitos do cliente", + "TEAM_REQUIREMENT": "requisitos da equipe", + "IS_IOCAINE": "É Iocaine", + "TAGS": "tags", + "ATTACHMENTS": "anexos", + "IS_DEPRECATED": "está obsoleto", + "ORDER": "ordem", + "BACKLOG_ORDER": "requisição do backlog", + "SPRINT_ORDER": "ordem de sprint ", + "KANBAN_ORDER": "pedido kanban", + "TASKBOARD_ORDER": "Ordem de quadro de tarefa", + "US_ORDER": "requisição US " + } + }, + "BACKLOG": { + "PAGE_TITLE": "Backlog - {{projectName}}", + "PAGE_DESCRIPTION": "O painel de backlog, com histórias de usuários e sprints do projeto {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Backlog", + "MOVE_US_TO_CURRENT_SPRINT": "Mover para Sprint Corrente", + "SHOW_FILTERS": "Mostrar filtros", + "SHOW_TAGS": "Exibir tags", + "EMPTY": "Seu backlog está vazio!", + "CREATE_NEW_US": "Criar uma nova EU", + "CREATE_NEW_US_EMPTY_HELP": "Você talvez queira criar uma nova user story", + "EXCESS_OF_POINTS": "Excesso de pontos", + "PENDING_POINTS": "Pontos Pendentes", + "CLOSED_POINTS": "fechado", + "COMPACT_SPRINT": "Sprint Resumido", + "GO_TO_TASKBOARD": "Ir ao quadro de tarefas de {{::name}}", + "EDIT_SPRINT": "Editar Sprint", + "TOTAL_POINTS": "total", + "STATUS_NAME": "Nome de Situação", + "SORTABLE_FILTER_ERROR": "Você não pode jogar sobre o backlog quando filtros estão abertos", + "DOOMLINE": "Escopo do projeto [Doomline]", + "CHART": { + "XAXIS_LABEL": "Sprintes", + "YAXIS_LABEL": "Pontos", + "OPTIMAL": "Ideal de pontos pendentes para o sprint \"{{sprintName}}\" deve ser {{value}}", + "REAL": "Real pending points for sprint \"{{sprintName}}\" is {{value}}", + "INCREMENT_TEAM": "Pontos incrementados pelos requerimentos do time para o sprint \"{{sprintName}}\" é {{value}}", + "INCREMENT_CLIENT": "Pontos incrementados pelos requerimentos do cliente para o sprint \"{{sprintName}}\" é {{value}}" + }, + "TAGS": { + "TOGGLE": "Alternar visibilidade das tags", + "SHOW": "Exibir tags", + "HIDE": "Esconder tags" + }, + "TABLE": { + "COLUMN_US": "Estórias de Uso", + "TITLE_COLUMN_POINTS": "Selecionar exibição por função" + }, + "SPRINT_SUMMARY": { + "TOTAL_POINTS": "pontos
totais", + "COMPLETED_POINTS": "pontos
completados", + "OPEN_TASKS": "tasks
abertas", + "CLOSED_TASKS": "tarefas
fechadas", + "IOCAINE_DOSES": "iocaine
doses", + "SHOW_STATISTICS_TITLE": "Mostrar estatísticas", + "TOGGLE_BAKLOG_GRAPH": "Mostrar/Esconder gráfico burndown" + }, + "SUMMARY": { + "PROJECT_POINTS": "pontos do
projeto", + "DEFINED_POINTS": "pontos
definidos", + "CLOSED_POINTS": "pontos
fechados", + "POINTS_PER_SPRINT": "pontos /
sprint" + }, + "FILTERS": { + "TOGGLE": "Alternar visibilidade de filtros", + "TITLE": "Filtros", + "REMOVE": "Remover filtros", + "HIDE": "Esconder Filtros", + "SHOW": "Mostrar Filtros", + "FILTER_CATEGORY_STATUS": "Situação", + "FILTER_CATEGORY_TAGS": "Tags" + }, + "SPRINTS": { + "TITLE": "SPRINTS", + "DATE": "DD MMM YYYY", + "LINK_TASKBOARD": "Sprint quadro de tarefas", + "TITLE_LINK_TASKBOARD": "ir para quadro de tarefas de \"{{name}}\"", + "NUMBER_SPRINTS": "
sprints", + "TITLE_ACTION_NEW_SPRINT": "+ Novo sprint", + "ACTION_NEW_SPRINT": "+ Novo sprint", + "ACTION_SHOW_CLOSED_SPRINTS": "Mostre os sprints fechados", + "ACTION_HIDE_CLOSED_SPRINTS": "Esconder sprints fechados" + } + }, + "ERROR": { + "TEXT1": "Alguma coisa aconteceu e nossos Oompa Loompas estão trabalhando nisso.", + "TEXT2": "Tente recarregar novamente daqui a pouco.", + "NOT_FOUND": "Não encontrado", + "NOT_FOUND_TEXT": "Erro 404. A página que você procura não existe mais. Você pode voltar para a página do TAIGA e ver se consegue encontrar o que está procurando.", + "PERMISSION_DENIED": "Permissão negada", + "PERMISSION_DENIED_CODE": "Erro 403.", + "VERSION_ERROR": "Alguém dentro da Taiga mudou isso antes e nosso Oompa Loompa não podem aplicar suas alterações. Recarregue a página e aplique-as novamente (elas serão perdidas, agora)." + }, + "TASKBOARD": { + "PAGE_TITLE": "{{sprintName}} - Quadro de Tarefas do Sprint - {{projectName}}", + "PAGE_DESCRIPTION": "Sprint {{sprintName}} (de{{startDate}} até {{endDate}}) para {{projectName}}. Completos {{completedPercentage}}% ({{completedPoints}} de {{totalPoints}} pontos). {{openTasks}} tarefas abertas de {{totalTasks}}.", + "SECTION_NAME": "Quadro de Tarefas", + "TITLE_ACTION_ADD": "Adicionar uma nova Tarefa", + "TITLE_ACTION_ADD_BULK": "Adicionar algumas tarefas em lote", + "TITLE_ACTION_ASSIGN": "Assinalar tarefa", + "TITLE_ACTION_EDIT": "Editar tarefa", + "TABLE": { + "COLUMN": "user story", + "TITLE_ACTION_FOLD": "Recolher coluna", + "TITLE_ACTION_UNFOLD": "Abrir coluna", + "TITLE_ACTION_FOLD_ROW": "Guardar Linha", + "TITLE_ACTION_UNFOLD_ROW": "Abrir linha", + "FIELD_POINTS": "pontos", + "ROW_UNASSIGED_TASKS_TITLE": "Tarefas não atribuídas" + }, + "CHARTS": { + "XAXIS_LABEL": "Dias", + "YAXIS_LABEL": "Pontos", + "OPTIMAL": "Pontos pendentes ideais para o dia {{formattedDate}} deve ser {{roundedValue}}", + "REAL": "\"Pontos pendentes reais para o dia {{formattedDate}} são {{roundedValue}}\"", + "DATE": "DD MMM YYYY" + } + }, + "TASK": { + "PAGE_TITLE": "{{taskSubject}} - Tarefa {{taskRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Estado: {{taskStatus }}. Descrição: {{taskDescription}}", + "SECTION_NAME": "Detalhes da Tarefa", + "LINK_TASKBOARD": "Quadro de Tarefas", + "TITLE_LINK_TASKBOARD": "Ir para o quadro de tarefas", + "PLACEHOLDER_SUBJECT": "Digite um novo titulo para tarefa", + "TITLE_SELECT_STATUS": "Nome de Situação", + "OWNER_US": "Esta tarefa pertence a ", + "TITLE_LINK_GO_OWNER": "Ir para user story", + "ORIGIN_US": "Essa tarefa foi criada a partir de", + "TITLE_LINK_GO_ORIGIN": "Ir para user story", + "BLOCKED": "Esta tarefa está bloqueada", + "PREVIOUS": "tarefa anterior", + "NEXT": "nova tarefa", + "TITLE_DELETE_ACTION": "Deletar Tarefa", + "LIGHTBOX_TITLE_BLOKING_TASK": "Tarefa bloqueadora", + "FIELDS": { + "MILESTONE": "Sprint", + "USER_STORY": "User story", + "IS_IOCAINE": "É Iocaine" + }, + "ACTION_IOCAINE": "Iocaine", + "TITLE_ACTION_IOCAINE": "Se sentindo sobrecarregado por uma tarefa? Assegure-se de que os outros saibam disso clicando em Iocaine quando estiver editando a tarefa. É possível se tornar imune a essse veneno mortal (fictício) consumindo pequenas quantidades ao longo do tempo, assim como é possível ficar melhor no que faz, ocasionalmente, por assumir desafios extras!" + }, + "NOTIFICATION": { + "OK": "Tudo está ok", + "WARNING": "Oops, aconteceu algo...", + "WARNING_TEXT": "Nossos Oompa Loompas estão tristes, suas alterações não foram salvas.", + "SAVED": "Nossos Oompa Loompas salvaram todas as suas mudanças!", + "CLOSE": "Fechar Notificação", + "MAIL": "Notificações por Email", + "ASK_DELETE": "Você tem certeza que quer apagar?" + }, + "CANCEL_ACCOUNT": { + "TITLE": "Cancelar sua conta", + "SUBTITLE": "Sentimos por você estar saindo. Esperamos que tenha gostado :)", + "PLACEHOLDER_INPUT_TOKEN": "cancelar o token da conta", + "ACTION_LEAVING": "Sim, estou indo embora!", + "SUCCESS": "Nossos Oompa Loompas removeram sua conta" + }, + "CHANGE_EMAIL_FORM": { + "TITLE": "Mudar seu email", + "SUBTITLE": "Só mais um clique e seu email será atualizado!", + "PLACEHOLDER_INPUT_TOKEN": "mudar token do email", + "ACTION_CHANGE_EMAIL": "Mudar email", + "SUCCESS": "Nossos Oompa Loompas atualizaram seu email" + }, + "ISSUES": { + "PAGE_TITLE": "Casos - {{projectName}}", + "PAGE_DESCRIPTION": "O painel de casos do projeto {{projectName}}: {{projectDescription}}", + "LIST_SECTION_NAME": "Casos", + "SECTION_NAME": "Detalhes do caso", + "ACTION_NEW_ISSUE": "+ NOVO CASO", + "ACTION_PROMOTE_TO_US": "Promover para User Story", + "PLACEHOLDER_FILTER_NAME": "Digite o nome do filtro e pressione Enter", + "PROMOTED": "Esse caso foi promovido para user strory", + "EXTERNAL_REFERENCE": "Esse caso foi criado a partir de", + "GO_TO_EXTERNAL_REFERENCE": "Ir para a origem", + "BLOCKED": "Esse caso está bloqueado", + "TITLE_PREVIOUS_ISSUE": "caso anterior", + "TITLE_NEXT_ISSUE": "próximo caso", + "ACTION_DELETE": "Caso deletado", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Caso que está bloqueando", + "FIELDS": { + "PRIORITY": "Prioridade", + "SEVERITY": "Severidade", + "TYPE": "Tipo" + }, + "CONFIRM_PROMOTE": { + "TITLE": "Promover esse caso para nova user story", + "MESSAGE": "Você tem certeza que deseja criar uma nova HU para esse caso?" + }, + "FILTERS": { + "TITLE": "Filtros", + "INPUT_SEARCH_PLACEHOLDER": "Assunto ou ref", + "TITLE_ACTION_SEARCH": "Procurar", + "ACTION_SAVE_CUSTOM_FILTER": "salve como filtro personalizado", + "BREADCRUMB": "Filtros", + "TITLE_BREADCRUMB": "Filtros", + "CATEGORIES": { + "TYPE": "Tipo", + "STATUS": "Situação", + "SEVERITY": "Severidade", + "PRIORITIES": "Prioridades", + "TAGS": "Tags", + "ASSIGNED_TO": "Atribuído a", + "CREATED_BY": "Criado por", + "CUSTOM_FILTERS": "Filtros personalizados" + }, + "CONFIRM_DELETE": { + "TITLE": "Apagar filtro personalizado", + "MESSAGE": "O filtro personalizado '{{customFilterName}}'" + } + }, + "TABLE": { + "COLUMNS": { + "TYPE": "Tipo", + "SEVERITY": "Severidade", + "PRIORITY": "Prioridade", + "SUBJECT": "Assunto", + "STATUS": "Situação", + "CREATED": "Criado", + "ASSIGNED_TO": "Atribuído a" + }, + "TITLE_ACTION_CHANGE_STATUS": "Mudar status", + "TITLE_ACTION_ASSIGNED_TO": "Atribuído a", + "EMPTY": { + "TITLE": "Não há casos para reportar :-)", + "SUBTITLE": "Você encontrou um caso ?", + "ACTION_CREATE_ISSUE": "Criar um novo caso" + } + } + }, + "ISSUE": { + "PAGE_TITLE": "{{issueSubject}} - caso {{issueRef}} - {{projectName}}", + "PAGE_DESCRIPTION": "Estado: {{issueStatus }}. Tipo: {{issueType}}, Prioridade: {{issuePriority}}. severidade: {{issueSeverity}}. Descrição: {{issueDescription}}" + }, + "KANBAN": { + "PAGE_TITLE": "Kanban - {{projectName}}", + "PAGE_DESCRIPTION": "O painel do kanban, contendo histórias de usuários do projeto {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Kanban", + "TITLE_ACTION_FOLD": "Recolher coluna", + "TITLE_ACTION_UNFOLD": "Abrir coluna", + "TITLE_ACTION_FOLD_CARDS": "Guardar cartões", + "TITLE_ACTION_UNFOLD_CARDS": "Mostrar cartões", + "TITLE_ACTION_ADD_US": "Adicionar Nova User Story", + "TITLE_ACTION_ADD_BULK": "Adicionar novo lote", + "ACTION_SHOW_ARCHIVED": "Mostrar arquivados", + "ACTION_HIDE_ARCHIVED": "esconder arquivados", + "HIDDEN_USER_STORIES": "As user stories nesse estatus estão escondidas por padrão", + "ARCHIVED": "Você arquivou", + "UNDO_ARCHIVED": "Pegue e arraste novamente para desfazer" + }, + "SEARCH": { + "PAGE_TITLE": "Buscar - {{projectName}}", + "PAGE_DESCRIPTION": "Busque qualquer coisa, user stories, casos, tarefas, ou páginas da wiki, no projeto {{projectName}}: {{projectDescription}}", + "FILTER_USER_STORIES": "Estórias de Uso", + "FILTER_ISSUES": "casos", + "FILTER_TASKS": "Tarefas", + "FILTER_WIKI": "Paginas Wiki", + "PLACEHOLDER_SEARCH": "Procurar em...", + "TITLE_ACTION_SEARCH": "procurar", + "EMPTY_TITLE": "Parece que nada foi encontrado com o critério de busca", + "EMPTY_DESCRIPTION": "Talvez tente uma das abas acima ou busque novamente" + }, + "TEAM": { + "PAGE_TITLE": "Equipe - {{projectName}}", + "PAGE_DESCRIPTION": "O painel do time irá exibir todos os membros envolvidos no projeto {{projectName}}: {{projectDescription}}", + "SECTION_NAME": "Time", + "APP_TITLE": "EQUIPE - {{projectName}}", + "PLACEHOLDER_INPUT_SEARCH": "Procurar pelo nome completo...", + "COLUMN_MR_WOLF": "Sr. Wolf", + "EXPLANATION_COLUMN_MR_WOLF": "Fechar caso", + "COLUMN_IOCAINE": "Bebedor de Iocaine", + "EXPLANATION_COLUMN_IOCAINE": "Doses de Iocaine ingeridas", + "COLUMN_CERVANTES": "Pero Vaz de Caminha", + "EXPLANATION_COLUMN_CERVANTES": "Páginas wiki editadas", + "COLUMN_BUG_HUNTER": "Caçador de bugs", + "EXPLANATION_COLUMN_BUG_HUNTER": "Caso reportado", + "COLUMN_NIGHT_SHIFT": "Periodo Noturno", + "EXPLANATION_COLUMN_NIGHT_SHIFT": "Tarefa fechada", + "COLUMN_TOTAL_POWER": "Total de poder", + "EXPLANATION_COLUMN_TOTAL_POWER": "Pontuação Total", + "SECTION_TITLE_TEAM": "Equipe >", + "SECTION_FILTER_ALL": "Tudo", + "CONFIRM_LEAVE_PROJECT": "Você tem certeza que quer deixar o projeto?", + "ACTION_LEAVE_PROJECT": "Deixar este projeto" + }, + "USER_SETTINGS": { + "AVATAR_MAX_SIZE": "[Tamanho máximo: {{maxFileSize}}]", + "MENU": { + "SECTION_TITLE": "Configurações de usuário", + "USER_PROFILE": "Perfil do Usuário", + "CHANGE_PASSWORD": "Alterar senha", + "EMAIL_NOTIFICATIONS": "Notificações por email" + }, + "NOTIFICATIONS": { + "SECTION_NAME": "Notificações por email", + "COLUMN_PROJECT": "Projeto", + "COLUMN_RECEIVE_ALL": "Receber todos", + "COLUMN_ONLY_INVOLVED": "Apenas involvido", + "COLUMN_NO_NOTIFICATIONS": "Sem notificações", + "OPTION_ALL": "Tudo", + "OPTION_INVOLVED": "Envolvido", + "OPTION_NONE": "Nada" + }, + "POPOVER": { + "USER_PROFILE": "Perfil do Usuário", + "CHANGE_PASSWORD": "Alterar Senha", + "NOTIFICATIONS": "Notificações", + "FEEDBACK": "Feedback", + "TITLE_AVATAR": "Preferências do Usuário" + } + }, + "USER_PROFILE": { + "IMAGE_HELP": "A imagem será redimensionada para 80x80px", + "ACTION_CHANGE_IMAGE": "Alterar", + "ACTION_USE_GRAVATAR": "Usar imagem do gravatar", + "ACTION_DELETE_ACCOUNT": "Apagar conta Taiga", + "CHANGE_EMAIL_SUCCESS": "Verifique sua caixa de entrada!
Enviamos um e-mail para sua conta
com as instruções para definir seu novo endereço", + "CHANGE_PHOTO": "Mudar foto", + "FIELD": { + "USERNAME": "Nome do usuário", + "EMAIL": "Email", + "FULL_NAME": "Nome completo", + "PLACEHOLDER_FULL_NAME": "Preencha seu nome completo (ex. Íñigo Montoya)", + "BIO": "Bio (max. 210 caracteres)", + "PLACEHOLDER_BIO": "Diga algo sobre você", + "LANGUAGE": "Idioma", + "LANGUAGE_DEFAULT": "-- usar idioma padrão --", + "THEME": "Tema", + "THEME_DEFAULT": "-- user tema padrão --" + } + }, + "WIZARD": { + "SECTION_TITLE_CHOOSE_TEMPLATE": "Escolher um template", + "CHOOSE_TEMPLATE_TEXT": "Qual template se encaixa melhor no seu projeto?", + "SECTION_TITLE_CREATE_PROJECT": "Criar Projeto", + "CREATE_PROJECT_TEXT": "Novo em folha. Tão excitante!", + "PROGRESS_TEMPLATE_SELECTION": "Seleção de template", + "PROGRESS_NAME_DESCRIPTION": "Nome e descrição" + }, + "WIKI": { + "PAGE_TITLE": "{{wikiPageName}} - Wiki - {{projectName}}", + "PAGE_DESCRIPTION": "Ultima edição em {{lastModifiedDate}} ({{totalEditions}} total de edições) Conteúdo: {{ wikiPageContent }}", + "DATETIME": "DD MMM YYYY HH:mm", + "PLACEHOLDER_PAGE": "Escreve sua página wiki", + "REMOVE": "Remover essa página wiki", + "DELETE_LIGHTBOX_TITLE": "Deletar página Wiki", + "NAVIGATION": { + "SECTION_NAME": "Links", + "ACTION_ADD_LINK": "Adicionar link" + }, + "SUMMARY": { + "TIMES_EDITED": "vezes
editadas", + "LAST_EDIT": "última
edição", + "LAST_MODIFICATION": "ultima modificação" + } + }, + "HINTS": { + "SECTION_NAME": "Sugestões", + "LINK": "Se você quer saber como usar visite nossa página de suporte", + "LINK_TITLE": "Visite nossa página de suporte", + "HINT1_TITLE": "Você sabia que você pode importar e exportar projetos?", + "HINT1_TEXT": "Isso permite você extrair todo o seu conteúdo de um Taiga e mover para outro.", + "HINT2_TITLE": "Você sabia que pode criar campos personalizados?", + "HINT2_TEXT": "Times podem agora criar campos personalizados flexíveis como entrar valores relevantes especificamente para seus escopos de trabalho", + "HINT3_TITLE": "Reordenar seus projetos para evidenciar os mais relevantes para você", + "HINT3_TEXT": "The top 10 project will be in your top bar direct access\nOs 10 projetos com maior destaque estarão na sua barra de acesso direto", + "HINT4_TITLE": "Você esqueceu no que está trabalhando?", + "HINT4_TEXT": "Não se preocupe, no seu painel você vai encontrar suas tarefas abertas, casos, e histórias de uso na ordem que você trabalha neles." + }, + "TIMELINE": { + "UPLOAD_ATTACHMENT": "{{username}} adicionou um novo anexo em {{obj_name}}", + "US_CREATED": "{{username}} criou uma nova US {{obj_name}} em {{project_name}}", + "ISSUE_CREATED": "{{username}} criou um novo caso {{obj_name}} em {{project_name}}", + "TASK_CREATED": "{{username}} criou uma nova tarefa {{obj_name}} em {{project_name}}", + "TASK_CREATED_WITH_US": "{{username}} criou nova tarefa {{obj_name}} em {{project_name}} que pertence a US {{us_name}}", + "WIKI_CREATED": "{{username}} criou uma página wiki {{obj_name}} em {{project_name}}", + "MILESTONE_CREATED": "{{username}} criou um novo sprint {{obj_name}} em {{project_name}}", + "NEW_PROJECT": "{{username}} criou o projeto {{project_name}}", + "MILESTONE_UPDATED": "{{username}} atualizou o sprint {{obj_name}}", + "US_UPDATED": "{{username}} atualizou o atributo \"{{field_name}}\" da US {{obj_name}}", + "US_UPDATED_WITH_NEW_VALUE": "{{username}} atualizou o trabalho \"{{field_name}}\" da US {{obj_name}} para {{new_value}}", + "US_UPDATED_POINTS": "{{username}} atualizou pontos de '{{role_name}}' da US {{obj_name}} para {{new_value}}", + "ISSUE_UPDATED": "{{username}} atualizou o atributo \"{{field_name}}\" do caso {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} atualizou o atributo \"{{field_name}}\" do caso {{obj_name}} para {{new_value}}", + "TASK_UPDATED": "{{username}} atualizou o atributo \"{{field_name}}\" da tarefa {{obj_name}} para {{new_value}}", + "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} Atualizou o atributo \"{{field_name}}\" da tarefa {{obj_name}} para {{new_value}}", + "TASK_UPDATED_WITH_US": "{{username}} atualizou o atributo \"{{field_name}}\" da tarefa{{obj_name}} que pertence a US {{us_name}}", + "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} atualizou o atributo \"{{field_name}}\" da tarefa {{obj_name}} que pertence a US {{us_name}} para {{new_value}}", + "WIKI_UPDATED": "{{username}} atualizou a página wiki {{obj_name}}", + "NEW_COMMENT_US": "{{username}} comentou na US {{obj_name}}", + "NEW_COMMENT_ISSUE": "{{username}} comentou no issue {{obj_name}}", + "NEW_COMMENT_TASK": "{{username}} comentou na tarefa {{obj_name}}", + "NEW_MEMBER": "{{project_name}} tem um membro novo", + "US_ADDED_MILESTONE": "{{username}} adicionou a US {{obj_name}} a {{sprint_name}}", + "US_MOVED": "{{username}} moveu a US {{obj_name}}", + "US_REMOVED_FROM_MILESTONE": "{{username}} adicionou a US {{obj_name}} ao backlog", + "BLOCKED": "{{username}} bloqueou {{obj_name}}", + "UNBLOCKED": "{{username}} desbloqueou {{obj_name}}", + "NEW_USER": "{{username}} ingressou no taiga" + } +} \ No newline at end of file From 3b05871b0e984e5a5c97a2e959bfe8692312d093 Mon Sep 17 00:00:00 2001 From: Brett Profitt Date: Fri, 21 Aug 2015 19:11:38 -0400 Subject: [PATCH 103/403] Added autocomplete for @mentions, #USs, #tasks, #issues, and [[wikipages]] in MD textareas. --- CHANGELOG.md | 1 + app/coffee/modules/common/wisiwyg.coffee | 104 +++++++++++++++++++++- app/styles/vendor/jquery.textcomplete.css | 6 +- bower.json | 2 +- gulpfile.js | 2 +- 5 files changed, 110 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 99ea3606..d310bc17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Make burndown chart collapsible at the backlog panel. - Ability to choose a theme (thanks to [@astagi](https://github.com/astagi)) - Inline viewing of image attachments (thanks to [@brettp](https://github.com/brettp)). +- Autocomplete for usernames, user stories, tasks, issues, and wiki pages in text areas (thanks to [@brettp](https://github.com/brettp)). - i18n. - Add polish (pl) translation. - Add portuguese (Brazil) (pt_BR) translation. diff --git a/app/coffee/modules/common/wisiwyg.coffee b/app/coffee/modules/common/wisiwyg.coffee index cfd6a6bb..2918ffc1 100644 --- a/app/coffee/modules/common/wisiwyg.coffee +++ b/app/coffee/modules/common/wisiwyg.coffee @@ -181,7 +181,11 @@ MarkitupDirective = ($rootscope, $rs, $selectedText, $template, $compile, $trans onShiftEnter: {keepDefault:false, openWith:"\n\n"} onEnter: keepDefault: false, - replaceWith: () -> "\n" + replaceWith: () -> + # Allow textcomplete to intercept the enter key if the options list is displayed + # @todo There doesn't seem to be a more graceful way to do this with the textcomplete API. + if not $('.textcomplete-dropdown').is(':visible') + "\n" afterInsert: (data) -> lines = data.textarea.value.split("\n") # Detect if we are in this situation +- aa at the beginning if the textarea @@ -347,6 +351,104 @@ MarkitupDirective = ($rootscope, $rs, $selectedText, $template, $compile, $trans element .markItUpRemove() .markItUp(markdownSettings) + .textcomplete([ + # us, task, and issue autocomplete: #id or # + { + cache: true + match: /(^|\s)#([a-z0-9]+)$/i, + search: (term, callback) -> + term = taiga.slugify(term) + + searchTypes = ['issues', 'tasks', 'userstories'] + searchProps = ['ref', 'subject'] + + filter = (item) => + for prop in searchProps + if taiga.slugify(item[prop]).indexOf(term) >= 0 + return true + return false + + $rs.search.do($scope.projectId, term).then (res) => + # ignore wikipages if they're the only results. can't exclude them in search + if res.count < 1 or res.count == res.wikipages.length + callback([]) + + else + for type in searchTypes + if res[type] and res[type].length > 0 + callback(res[type].filter(filter), true) + + # must signal end of lists + callback([]) + + replace: (res) -> + return "$1\##{res.ref} " + + template: (res, term) -> + return "\##{res.ref} - #{res.subject}" + } + + # username autocomplete: @username or @ + { + cache: true + match: /(^|\s)@([a-z0-9\-\._]{2,})$/i + search: (term, callback) -> + username = taiga.slugify(term) + searchProps = ['username', 'full_name', 'full_name_display'] + + if $scope.project.members.length < 1 + callback([]) + + else + callback $scope.project.members.filter (user) => + for prop in searchProps + if taiga.slugify(user[prop]).indexOf(username) >= 0 + return true + return false + + replace: (user) -> + return "$1@#{user.username} " + + template: (user) -> + return "#{user.username} - #{user.full_name_display}" + } + + # wiki pages autocomplete: [[slug or [[ + # if the search function was called with the 3rd param the regex + # like the docs claim, we could combine this with the #123 search + { + cache: true + match: /(^|\s)\[\[([a-z0-9\-]+)$/i + search: (term, callback) -> + term = taiga.slugify(term) + + $rs.search.do($scope.projectId, term).then (res) => + if res.count < 1 + callback([]) + + if res.count < 1 or not res.wikipages or res.wikipages.length <= 0 + callback([]) + + else + callback res.wikipages.filter((page) => + return taiga.slugify(page['slug']).indexOf(term) >= 0 + ), true + + # must signal end of lists + callback([]) + + + replace: (res) -> + return "$1[[#{res.slug}]]" + + template: (res, term) -> + return res.slug + } + ], + { + debounce: 200 + } + ) renderMarkItUp() diff --git a/app/styles/vendor/jquery.textcomplete.css b/app/styles/vendor/jquery.textcomplete.css index ce74c742..978cc324 100644 --- a/app/styles/vendor/jquery.textcomplete.css +++ b/app/styles/vendor/jquery.textcomplete.css @@ -17,10 +17,12 @@ .dropdown-menu li:hover, .dropdown-menu .active { background-color: rgb(110, 183, 219); + color: white; } -.textcomplete-wrapper { - width: 100%; +.dropdown-menu .active > a, +.dropdown-menu .active > a:hover { + color: white; } /* SHOULD not modify */ diff --git a/bower.json b/bower.json index 7291fcec..be586d1e 100644 --- a/bower.json +++ b/bower.json @@ -62,7 +62,7 @@ "google-diff-match-patch-js": "~1.0.0", "underscore.string": "~2.3.3", "markitup-1x": "~1.1.14", - "jquery-textcomplete": "yuku-t/jquery-textcomplete#~0.1.1", + "jquery-textcomplete": "yuku-t/jquery-textcomplete#~0.7", "flot-orderBars": "emmerich/flot-orderBars", "flot-axislabels": "markrcote/flot-axislabels", "flot.tooltip": "~0.8.4", diff --git a/gulpfile.js b/gulpfile.js index c923045c..41c62d57 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -154,7 +154,7 @@ paths.libs = [ paths.vendor + "jquery-flot/jquery.flot.time.js", paths.vendor + "flot-axislabels/jquery.flot.axislabels.js", paths.vendor + "flot.tooltip/js/jquery.flot.tooltip.js", - paths.vendor + "jquery-textcomplete/jquery.textcomplete.js", + paths.vendor + "jquery-textcomplete/dist/jquery.textcomplete.js", paths.vendor + "markitup-1x/markitup/jquery.markitup.js", paths.vendor + "malihu-custom-scrollbar-plugin/jquery.mCustomScrollbar.concat.min.js", paths.vendor + "raven-js/dist/raven.js", From e222c9c12819e3b227cd4e40e182dd23381dd904 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 31 Aug 2015 10:21:51 +0200 Subject: [PATCH 104/403] always add a fallback language --- app/coffee/app.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index a978156d..5e14f9ce 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -498,9 +498,7 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven .addInterpolation('$translateMessageFormatInterpolation') .preferredLanguage(preferedLangCode) - if not window.taigaConfig.debugInfo - $translateProvider.fallbackLanguage(preferedLangCode) - + $translateProvider.fallbackLanguage(preferedLangCode) i18nInit = (lang, $translate) -> # i18n - moment.js From e8ea2a558d4e58c679c35a7825debb96fab32b11 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 31 Aug 2015 10:00:39 +0200 Subject: [PATCH 105/403] hide new related task button when the form is open --- app/coffee/app.coffee | 5 ++++- app/coffee/modules/related-tasks.coffee | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index a978156d..d2b378a5 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -39,7 +39,9 @@ taiga.sessionId = taiga.generateUniqueSessionIdentifier() configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEventsProvider, - $compileProvider, $translateProvider) -> + $compileProvider, $translateProvider, $animateProvider) -> + + $animateProvider.classNameFilter(/^(?:(?!ng-animate-disabled).)*$/) # wait until the trasnlation is ready to resolve the page originalWhen = $routeProvider.when @@ -648,6 +650,7 @@ module.config([ "$tgEventsProvider", "$compileProvider", "$translateProvider", + "$animateProvider", configure ]) diff --git a/app/coffee/modules/related-tasks.coffee b/app/coffee/modules/related-tasks.coffee index 81eda43b..b2a4595f 100644 --- a/app/coffee/modules/related-tasks.coffee +++ b/app/coffee/modules/related-tasks.coffee @@ -146,8 +146,14 @@ RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, return promise - render = -> + close = () -> $el.off() + $el.html("") + + $scope.newRelatedTaskFormOpen = false + + render = -> + $scope.newRelatedTaskFormOpen = true $el.html($compile(template())($scope)) $el.find('input').focus().select() @@ -158,14 +164,14 @@ RelatedTaskCreateFormDirective = ($repo, $compile, $confirm, $tgmodel, $loading, createTask(newTask).then -> render() else if event.keyCode == 27 - $el.html("") + $scope.$apply () -> close() $el.on "click", ".icon-delete", (event)-> - $el.html("") + $scope.$apply () -> close() $el.on "click", ".icon-floppy", (event)-> createTask(newTask).then -> - $el.html("") + close() taiga.bindOnce $scope, "us", (val) -> newTask["status"] = $scope.project.default_task_status @@ -185,7 +191,7 @@ module.directive("tgRelatedTaskCreateForm", ["$tgRepo", "$compile", "$tgConfirm" RelatedTaskCreateButtonDirective = ($repo, $compile, $confirm, $tgmodel) -> template = _.template(""" - + """) link = ($scope, $el, $attrs) -> @@ -193,7 +199,7 @@ RelatedTaskCreateButtonDirective = ($repo, $compile, $confirm, $tgmodel) -> return if not val $el.off() if $scope.project.my_permissions.indexOf("add_task") != -1 - $el.html(template()) + $el.html($compile(template())($scope)) else $el.html("") From 5e4f02d5714763755258bb974806d18a11ac6aa1 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 1 Sep 2015 09:04:53 +0200 Subject: [PATCH 106/403] add delete member email in the delete confirmation popup --- app/coffee/modules/admin/memberships.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/admin/memberships.coffee b/app/coffee/modules/admin/memberships.coffee index 3cb8ae9b..e734b90b 100644 --- a/app/coffee/modules/admin/memberships.coffee +++ b/app/coffee/modules/admin/memberships.coffee @@ -394,7 +394,7 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla event.preventDefault() title = $translate.instant("ADMIN.MEMBERSHIP.DELETE_MEMBER") - defaultMsg = $translate.instant("ADMIN.MEMBERSHIP.DEFAULT_DELETE_MESSAGE") + defaultMsg = $translate.instant("ADMIN.MEMBERSHIP.DEFAULT_DELETE_MESSAGE", {email: member.email}) message = if member.user then member.full_name else defaultMsg $confirm.askOnDelete(title, message).then (finish) -> From 14e8429dba67568600f2f3c4e5932afc4be26297 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 1 Sep 2015 09:22:21 +0200 Subject: [PATCH 107/403] fix reload backlog stats after us change --- app/coffee/modules/backlog/main.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index 8cd5d696..d8b4290d 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -485,7 +485,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F updateUserStoryStatus: () -> @.setSearchDataFilters() - @.generateFilters().then () -> + @.generateFilters().then () => @rootscope.$broadcast("filters:update") @.loadProjectStats() From 5bb81c403533d40f540c8d88c153b0bf90fc95a2 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 1 Sep 2015 08:21:26 +0200 Subject: [PATCH 108/403] fix membership pagination --- app/coffee/modules/admin/memberships.coffee | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/coffee/modules/admin/memberships.coffee b/app/coffee/modules/admin/memberships.coffee index e734b90b..505419fe 100644 --- a/app/coffee/modules/admin/memberships.coffee +++ b/app/coffee/modules/admin/memberships.coffee @@ -82,6 +82,7 @@ class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin, tai return @rs.memberships.list(@scope.projectId, httpFilters).then (data) => @scope.memberships = _.filter(data.models, (membership) -> membership.user == null or membership.is_user_active) + @scope.page = data.current @scope.count = data.count @scope.paginatedBy = data.paginatedBy @@ -110,7 +111,7 @@ module.controller("MembershipsController", MembershipsController) ## Member Avatar Directive ############################################################################# -MembershipsDirective = ($template) -> +MembershipsDirective = ($template, $compile) -> template = $template.get("admin/admin-membership-paginator.html", true) linkPagination = ($scope, $el, $attrs, $ctrl) -> @@ -158,7 +159,11 @@ MembershipsDirective = ($template) -> else pages.push({classes: "page", num: i, type: "page"}) - $pagEl.html(template(options)) + html = template(options) + html = $compile(html)($scope) + + $pagEl.html(html) + $pagEl.show() $scope.$watch "memberships", (value) -> # Do nothing if value is not logical true @@ -198,7 +203,7 @@ MembershipsDirective = ($template) -> return {link:link} -module.directive("tgMemberships", ["$tgTemplate", MembershipsDirective]) +module.directive("tgMemberships", ["$tgTemplate", "$compile", MembershipsDirective]) ############################################################################# @@ -400,6 +405,10 @@ MembershipsRowActionsDirective = ($log, $repo, $rs, $confirm, $compile, $transla $confirm.askOnDelete(title, message).then (finish) -> onSuccess = -> finish() + + if $scope.page > 1 && ($scope.count - 1) <= $scope.paginatedBy + $ctrl.selectFilter("page", $scope.page - 1) + $ctrl.loadMembers() text = $translate.instant("ADMIN.MEMBERSHIP.SUCCESS_DELETE") From 9abd94ca1b99c08bc86fc9c051f303e1703f8466 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 1 Sep 2015 12:33:59 +0100 Subject: [PATCH 109/403] Adding Date field type to custom fields --- .../modules/common/custom-field-values.coffee | 21 ++++++++++++++++++- app/locales/locale-en.json | 3 ++- .../custom-attribute-value-edit.jade | 10 ++++++++- .../admin/admin-custom-attributes.jade | 4 ++-- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/app/coffee/modules/common/custom-field-values.coffee b/app/coffee/modules/common/custom-field-values.coffee index 7e031615..1dad3100 100644 --- a/app/coffee/modules/common/custom-field-values.coffee +++ b/app/coffee/modules/common/custom-field-values.coffee @@ -148,6 +148,20 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> $el.html(html) + if attributeValue.field_type == "DATE" + + selectedDate = null + + $el.picker = new Pikaday( + field: $el.find('input')[0] + onSelect: (date) => + selectedDate = date + onOpen: => + $el.picker.setDate(selectedDate) if selectedDate? + firstDay: 1 + format: 'DD MMM YYYY' + ) + isEditable = -> permissions = $scope.project.my_permissions requiredEditionPerm = $attrs.requiredEditionPerm @@ -156,6 +170,9 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> saveAttributeValue = -> attributeValue.value = $el.find("input, textarea").val() + if attributeValue.field_type == "DATE" and attributeValue.value != '' + return if moment(attributeValue.value).isValid() != true + $scope.$apply -> $ctrl.updateAttributeValue(attributeValue).then -> render(attributeValue, false) @@ -164,7 +181,9 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> if event.keyCode == 13 and event.currentTarget.type != "textarea" submit(event) else if event.keyCode == 27 - render(attributeValue, false) + return if attributeValue.field_type == "DATE" and moment(attributeValue.value).isValid() != true + + render(attributeValue, false) ## Actions (on view mode) $el.on "click", ".custom-field-value.read-mode", -> diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index f9f7d90d..6014c43e 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -456,7 +456,8 @@ "ISSUE_DESCRIPTION": "Issues custom fields", "ISSUE_ADD": "Add a custom field in issues", "FIELD_TYPE_TEXT": "Text", - "FIELD_TYPE_MULTI": "Multi-line" + "FIELD_TYPE_MULTI": "Multi-line", + "FIELD_TYPE_DATE": "Date" }, "PROJECT_VALUES": { "PAGE_TITLE": "{{sectionName}} - Project values - {{projectName}}", diff --git a/app/partials/custom-attributes/custom-attribute-value-edit.jade b/app/partials/custom-attributes/custom-attribute-value-edit.jade index a03bebd6..5ac1edbd 100644 --- a/app/partials/custom-attributes/custom-attribute-value-edit.jade +++ b/app/partials/custom-attributes/custom-attribute-value-edit.jade @@ -8,7 +8,7 @@ form.custom-field-single.editable <% } %> div.custom-field-value - + <% if (field_type=="MULTI") { %> textarea#custom-field-description(name="description") <%- value %> @@ -18,5 +18,13 @@ form.custom-field-single.editable input#custom-field-description(name="description", type="text", value!="<%- value %>") <% } %> + <% if (field_type=="DATE" && value!="") { %> + input#custom-field-description(name="description", type="text", value!="<%- moment(value).format('DD MMM YYYY') %>") + <% } %> + + <% if (field_type=="DATE" && value=="") { %> + input#custom-field-description(name="description", type="text", value!="") + <% } %> + div.custom-field-options a.icon.icon-floppy(href="", title="{{'COMMON.CUSTOM_ATTRIBUTES.SAVE' | translate}}") diff --git a/app/partials/includes/modules/admin/admin-custom-attributes.jade b/app/partials/includes/modules/admin/admin-custom-attributes.jade index 9d4130b7..b26cf9f8 100644 --- a/app/partials/includes/modules/admin/admin-custom-attributes.jade +++ b/app/partials/includes/modules/admin/admin-custom-attributes.jade @@ -40,7 +40,7 @@ section.custom-fields-table.basic-table ng-model="attr.description") fieldset.custom-field-type select(ng-model="attr.field_type", - ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") + ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'},{'id':'DATE', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE'}]") fieldset.custom-options div.custom-options-wrapper a.js-update-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_UPDATE' | translate}}") @@ -55,7 +55,7 @@ section.custom-fields-table.basic-table ng-model="newAttr.description") fieldset.custom-field-type select(ng-model="newAttr.field_type", - ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'}]") + ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'},{'id':'DATE', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE'}]") fieldset.custom-options div.custom-options-wrapper From c99db279565aca7ef4b3f4189e07d063e030dc67 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 3 Sep 2015 10:36:44 +0200 Subject: [PATCH 110/403] remove old loader clearInterval --- app/coffee/modules/common/loader.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/app/coffee/modules/common/loader.coffee b/app/coffee/modules/common/loader.coffee index aebc6a30..3081263e 100644 --- a/app/coffee/modules/common/loader.coffee +++ b/app/coffee/modules/common/loader.coffee @@ -82,7 +82,6 @@ Loader = ($rootscope) -> pageLoaded() clearInterval(intervalAuto) - clearTimeout(timeoutAuto) ), 50 start = () -> From 43c23ed81934716ae6f6aea9c157f35beef05bd7 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 1 Sep 2015 12:45:16 +0200 Subject: [PATCH 111/403] fix 'show closed sprints' visibility --- app/coffee/modules/backlog/lightboxes.coffee | 2 +- app/coffee/modules/backlog/main.coffee | 56 +++++++++++++++----- app/coffee/modules/base/repository.coffee | 9 +++- app/coffee/modules/resources/sprints.coffee | 12 ++++- 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/app/coffee/modules/backlog/lightboxes.coffee b/app/coffee/modules/backlog/lightboxes.coffee index 2915e19d..26f35ca3 100644 --- a/app/coffee/modules/backlog/lightboxes.coffee +++ b/app/coffee/modules/backlog/lightboxes.coffee @@ -100,7 +100,7 @@ CreateEditSprint = ($repo, $confirm, $rs, $rootscope, lightboxService, $loading, finish() $scope.milestonesCounter -= 1 lightboxService.close($el) - $rootscope.$broadcast("sprintform:remove:success") + $rootscope.$broadcast("sprintform:remove:success", $scope.sprint) onError = -> finish(false) diff --git a/app/coffee/modules/backlog/main.coffee b/app/coffee/modules/backlog/main.coffee index d8b4290d..2d79f42e 100644 --- a/app/coffee/modules/backlog/main.coffee +++ b/app/coffee/modules/backlog/main.coffee @@ -104,10 +104,14 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.$on "sprintform:edit:success", => @.loadProjectStats() - @scope.$on "sprintform:remove:success", => + @scope.$on "sprintform:remove:success", (event, sprint) => @.loadSprints() @.loadProjectStats() @.loadUserstories() + + if sprint.closed + @.loadClosedSprints() + @rootscope.$broadcast("filters:update") @scope.$on "usform:edit:success", => @@ -157,17 +161,26 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F loadClosedSprints: -> params = {closed: true} - return @rs.sprints.list(@scope.projectId, params).then (sprints) => + return @rs.sprints.list(@scope.projectId, params).then (result) => + sprints = result.milestones + + @scope.totalClosedMilestones = result.closed + # NOTE: Fix order of USs because the filter orderBy does not work propertly in partials files for sprint in sprints sprint.user_stories = _.sortBy(sprint.user_stories, "sprint_order") @scope.closedSprints = sprints + @scope.closedSprintsById = groupBy(sprints, (x) -> x.id) @rootscope.$broadcast("closed-sprints:reloaded", sprints) return sprints loadSprints: -> params = {closed: false} - return @rs.sprints.list(@scope.projectId, params).then (sprints) => + return @rs.sprints.list(@scope.projectId, params).then (result) => + sprints = result.milestones + + @scope.totalClosedMilestones = result.closed + # NOTE: Fix order of USs because the filter orderBy does not work propertly in partials files for sprint in sprints sprint.user_stories = _.sortBy(sprint.user_stories, "sprint_order") @@ -231,7 +244,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F @scope.projectId = project.id @scope.project = project - @scope.totalClosedMilestones = project.total_closed_milestones + @scope.closedMilestones = !!project.total_closed_milestones @scope.$emit('project:loaded', project) @scope.points = _.sortBy(project.points, "order") @scope.pointsById = groupBy(project.points, (x) -> x.id) @@ -267,6 +280,23 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F oldSprintId = usList[0].milestone project = usList[0].project + movedFromClosedSprint = false + movedToClosedSprint = false + + sprint = @scope.sprintsById[oldSprintId] + + # Move from closed sprint + if !sprint && @scope.closedSprintsById + sprint = @scope.closedSprintsById[oldSprintId] + movedFromClosedSprint = true if sprint + + newSprint = @scope.sprintsById[newSprintId] + + # Move to closed sprint + if !newSprint + newSprint = @scope.closedSprintsById[newSprintId] + movedToClosedSprint = true if newSprint + # In the same sprint or in the backlog if newSprintId == oldSprintId items = null @@ -275,7 +305,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F if newSprintId == null userstories = @scope.userstories else - userstories = @scope.sprintsById[newSprintId].user_stories + userstories = newSprint.user_stories @scope.$apply -> for us, key in usList @@ -322,8 +352,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F args = [newUsIndex, 0].concat(usList) Array.prototype.splice.apply(@scope.userstories, args) - # Remove the us from the sprint list. - sprint = @scope.sprintsById[oldSprintId] for us, key in usList r = sprint.user_stories.indexOf(us) sprint.user_stories.splice(r, 1) @@ -339,13 +367,15 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F return @rs.userstories.bulkUpdateBacklogOrder(us.project, data).then => @rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId) + if movedFromClosedSprint + @rootscope.$broadcast("backlog:load-closed-sprints") + promise.then null, -> console.log "FAIL" # TODO return promise # From backlog to sprint - newSprint = @scope.sprintsById[newSprintId] if oldSprintId == null us.milestone = newSprintId for us in usList @@ -372,9 +402,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F # Remove the us from the sprint list. for us in usList - oldSprint = @scope.sprintsById[oldSprintId] - r = oldSprint.user_stories.indexOf(us) - oldSprint.user_stories.splice(r, 1) + r = sprint.user_stories.indexOf(us) + sprint.user_stories.splice(r, 1) # Persist the milestone change of userstory promises = _.map usList, (us) => @repo.save(us) @@ -385,13 +414,16 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F items = @.resortUserStories(newSprint.user_stories, "sprint_order") data = @.prepareBulkUpdateData(items, "sprint_order") - @rs.userstories.bulkUpdateSprintOrder(project, data).then => + @rs.userstories.bulkUpdateSprintOrder(project, data).then (result) => @rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId) @rs.userstories.bulkUpdateBacklogOrder(project, data).then => for us in usList @rootscope.$broadcast("sprint:us:moved", us, oldSprintId, newSprintId) + if movedToClosedSprint || movedFromClosedSprint + @scope.$broadcast("backlog:load-closed-sprints") + promise.then null, -> console.log "FAIL" # TODO diff --git a/app/coffee/modules/base/repository.coffee b/app/coffee/modules/base/repository.coffee index 0089ad3d..c51a89dd 100644 --- a/app/coffee/modules/base/repository.coffee +++ b/app/coffee/modules/base/repository.coffee @@ -140,7 +140,7 @@ class RepositoryService extends taiga.Service return defered.promise - queryMany: (name, params, options={}) -> + queryMany: (name, params, options={}, headers=false) -> url = @urls.resolve(name) httpOptions = {headers: {}} @@ -148,7 +148,12 @@ class RepositoryService extends taiga.Service httpOptions.headers["x-disable-pagination"] = "1" return @http.get(url, params, httpOptions).then (data) => - return _.map(data.data, (x) => @model.make_model(name, x)) + result = _.map(data.data, (x) => @model.make_model(name, x)) + + if headers + return [result, data.headers] + + return result queryOneAttribute: (name, id, attribute, params, options={}) -> url = @urls.resolve(name, id) diff --git a/app/coffee/modules/resources/sprints.coffee b/app/coffee/modules/resources/sprints.coffee index d9f5ccdc..5f94ba2e 100644 --- a/app/coffee/modules/resources/sprints.coffee +++ b/app/coffee/modules/resources/sprints.coffee @@ -39,12 +39,20 @@ resourceProvider = ($repo, $model, $storage) -> service.list = (projectId, filters) -> params = {"project": projectId} params = _.extend({}, params, filters or {}) - return $repo.queryMany("milestones", params).then (milestones) => + return $repo.queryMany("milestones", params, {}, true).then (result) => + milestones = result[0] + headers = result[1] + for m in milestones uses = m.user_stories uses = _.map(uses, (u) => $model.make_model("userstories", u)) m._attrs.user_stories = uses - return milestones + + return { + milestones: milestones, + closed: parseInt(headers("Taiga-Info-Total-Closed-Milestones"), 10), + open: parseInt(headers("Taiga-Info-Total-Opened-Milestones"), 10) + } return (instance) -> From e644262624989ec542c20520799b4441c8a9b659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 7 Sep 2015 11:45:11 +0200 Subject: [PATCH 112/403] [i18n] Update locales --- app/locales/locale-pt-br.json | 2 +- app/locales/locale-ru.json | 116 +++++++++++++++++----------------- 2 files changed, 59 insertions(+), 59 deletions(-) diff --git a/app/locales/locale-pt-br.json b/app/locales/locale-pt-br.json index 91e0419c..ed9be5aa 100644 --- a/app/locales/locale-pt-br.json +++ b/app/locales/locale-pt-br.json @@ -1162,7 +1162,7 @@ "SECTION_NAME": "Notificações por email", "COLUMN_PROJECT": "Projeto", "COLUMN_RECEIVE_ALL": "Receber todos", - "COLUMN_ONLY_INVOLVED": "Apenas involvido", + "COLUMN_ONLY_INVOLVED": "Apenas envolvido", "COLUMN_NO_NOTIFICATIONS": "Sem notificações", "OPTION_ALL": "Tudo", "OPTION_INVOLVED": "Envolvido", diff --git a/app/locales/locale-ru.json b/app/locales/locale-ru.json index 0f5531ad..103beed8 100644 --- a/app/locales/locale-ru.json +++ b/app/locales/locale-ru.json @@ -36,7 +36,7 @@ "EXTERNAL_USER": "внешний пользователь", "GENERIC_ERROR": "Один из Умпа-Лумп говорит {{error}}.", "IOCAINE_TEXT": "Чувствуете, что задание берет верх над вами? Дайте другим знать об этом, нажав на \"Иокаин\", когда редактируете задание. Возможно стать неуязвимым к этому (выдуманному) смертельном яду, потребляя небольшие количества время от времени, так же как возможно стать лучше в том, что вы делаете, временами беря на себя дополнительные препятствия!", - "CAPSLOCK_WARNING": "Be careful! You're writing with capital letters and this input is case sensitive.", + "CAPSLOCK_WARNING": "Будьте внимательны! Введённый текст состоит из заглавных букв, а регистр имеет значение.", "FORM_ERRORS": { "DEFAULT_MESSAGE": "Кажется, это значение некорректно.", "TYPE_EMAIL": "Это значение должно быть корректным email-адресом.", @@ -104,7 +104,7 @@ "SEE_USER_PROFILE": "Посмотреть профиль {{username }}", "USER_STORY": "Пользовательская история", "TASK": "Задача", - "ISSUE": "Проблема", + "ISSUE": "Задача", "TAGS": { "PLACEHOLDER": "Назначьте тэг", "DELETE": "Удалить тэг", @@ -221,11 +221,11 @@ "DELETE_TASKS": "Удалить задачи" }, "ISSUES": { - "NAME": "Проблемы", - "VIEW_ISSUES": "Посмотреть проблемы", - "ADD_ISSUES": "Добавить проблемы", - "MODIFY_ISSUES": "Изменить проблемы", - "DELETE_ISSUES": "Удалить проблемы" + "NAME": "Задачи", + "VIEW_ISSUES": "Посмотреть задачи", + "ADD_ISSUES": "Добавить задачи", + "MODIFY_ISSUES": "Изменить задачи", + "DELETE_ISSUES": "Удалить задачи" }, "WIKI": { "NAME": "Вики", @@ -327,8 +327,8 @@ }, "HOME": { "PAGE_TITLE": "Домашняя страница - Taiga", - "PAGE_DESCRIPTION": "Главная страница Тайги, с вашими основными проектами, назначенными и отслеживаемыми задачами, проблемами и историями от пользователей", - "EMPTY_WATCHING": "Следите за проектами, историями от пользователей, задачами, проблемами... о которых хотите знать :)", + "PAGE_DESCRIPTION": "Главная страница Тайги, с вашими основными проектами, назначенными и отслеживаемыми задачами и историями от пользователей", + "EMPTY_WATCHING": "Следите за проектами, историями от пользователей, задачами... о которых хотите знать :)", "EMPTY_PROJECT_LIST": "У Вас пока нет проектов", "WORKING_ON_SECTION": "Работает над", "WATCHING_SECTION": "Отслеживаемые" @@ -401,7 +401,7 @@ "BACKLOG_DESCRIPTION": "Управляйте историями от пользователей, чтобы организовывать вашу ближайшую и приоритетную работу", "KANBAN": "Kanban", "KANBAN_DESCRIPTION": "Организуйте эффективную работу с проектом с помощью этой панели", - "ISSUES": "Проблемы", + "ISSUES": "Задачи", "ISSUES_DESCRIPTION": "Следите за ошибками, вопросами и улучшениями вашего проекта. Ничего не пропустите!", "WIKI": "Вики", "WIKI_DESCRIPTION": "Добавляйте, изменяйте или удаляйте контент совместно с остальными. Это самое правильное место для документации вашего проекта.", @@ -439,7 +439,7 @@ "CSV": { "SECTION_TITLE_US": "Отчёты об историях от пользователей", "SECTION_TITLE_TASK": "отчёты о задачах", - "SECTION_TITLE_ISSUE": "отчёты о проблемах", + "SECTION_TITLE_ISSUE": "отчёты о задачах", "DOWNLOAD": "Скачать CSV", "URL_FIELD_PLACEHOLDER": "Упс, забыли пароль?", "TITLE_REGENERATE_URL": " Сделать CSV ссылку ещё раз", @@ -448,13 +448,13 @@ }, "CUSTOM_FIELDS": { "TITLE": "Пользовательские поля", - "SUBTITLE": "Укажите специальные поля для ваших задач, историй от пользователей и проблем", + "SUBTITLE": "Укажите специальные поля для ваших задач и историй от пользователей", "US_DESCRIPTION": "Специальные поля для историй от пользователей", "US_ADD": "Добавить специальное поле для историй от пользователей", "TASK_DESCRIPTION": "Специальные поля задач", "TASK_ADD": "Добавить новые типы задач", - "ISSUE_DESCRIPTION": "Специальные поля проблем", - "ISSUE_ADD": "Добавить специальное поле для проблем", + "ISSUE_DESCRIPTION": "Специальные поля задач", + "ISSUE_ADD": "Добавить специальное поле для задач", "FIELD_TYPE_TEXT": "Текст", "FIELD_TYPE_MULTI": "Многостроковое" }, @@ -471,27 +471,27 @@ }, "PROJECT_VALUES_PRIORITIES": { "TITLE": "Приоритеты", - "SUBTITLE": "Укажите, какие приоритеты будут иметь ваши проблемы", - "ISSUE_TITLE": "Приоритеты проблем", + "SUBTITLE": "Укажите, какие приоритеты будут иметь ваши задачи", + "ISSUE_TITLE": "Приоритеты задач", "ACTION_ADD": "Добавить новый приоритет" }, "PROJECT_VALUES_SEVERITIES": { "TITLE": "Степени важности", - "SUBTITLE": "Укажите степени важности, которые будут иметь ваши проблемы", - "ISSUE_TITLE": "Степени важности проблем", + "SUBTITLE": "Укажите степени важности, которые будут иметь ваши задачи", + "ISSUE_TITLE": "Степени важности задач", "ACTION_ADD": "Добавить новую степень важности" }, "PROJECT_VALUES_STATUS": { "TITLE": "Статус", - "SUBTITLE": "Укажите, какие статусы будут принимать ваши задачи, истории от пользователей и проблемы", + "SUBTITLE": "Укажите, какие статусы будут принимать ваши задачи и истории от пользователей", "US_TITLE": "Статусы ПИ", "TASK_TITLE": "Статус задач", - "ISSUE_TITLE": "Статусы проблем" + "ISSUE_TITLE": "Статусы задач" }, "PROJECT_VALUES_TYPES": { "TITLE": "Типы", - "SUBTITLE": "Укажите, какие типы смогут иметь ваши проблемы", - "ISSUE_TITLE": "Типы проблем", + "SUBTITLE": "Укажите, какие типы смогут иметь ваши задачи", + "ISSUE_TITLE": "Типы задач", "ACTION_ADD": "Добавить новый" }, "ROLES": { @@ -582,8 +582,8 @@ "LABEL_TASK_STATUS": "Значение по умолчанию для статуса задачи", "LABEL_PRIORITY": "Значение по умолчанию для выбора приоритета", "LABEL_SEVERITY": "Значение важности по умолчанию", - "LABEL_ISSUE_TYPE": "Значение по умолчанию для типа проблемы", - "LABEL_ISSUE_STATUS": "Значение по умолчанию для статуса проблемы" + "LABEL_ISSUE_TYPE": "Значение по умолчанию для типа задачи", + "LABEL_ISSUE_STATUS": "Значение по умолчанию для статуса задачи" }, "STATUS": { "PLACEHOLDER_WRITE_STATUS_NAME": "Укажите название для нового статуса" @@ -670,7 +670,7 @@ "TIMELINE": "График работ", "BACKLOG": "Список задач", "KANBAN": "Kanban", - "ISSUES": "Проблемы", + "ISSUES": "Задачи", "WIKI": "Wiki", "TEAM": "Команда", "MEETUP": "Созвониться", @@ -731,7 +731,7 @@ "DELETE_PROJECT": { "TITLE": "Удалить проект", "QUESTION": "Вы уверены, что хотите удалить данный проект?", - "SUBTITLE": "Все данные проекта (истории от пользователей, задачи, проблемы, спринты и вики страницы) будут утрачены! :-(", + "SUBTITLE": "Все данные проекта (истории от пользователей, задачи, спринты и вики страницы) будут утрачены! :-(", "CONFIRM": "Да, я уверен" }, "ASSIGNED_TO": { @@ -743,7 +743,7 @@ "HELP_TEXT": "Если пользователи уже зарегистрированы в Тайге они добавятся автоматически. В противном случае им будет отправлено приглашение." }, "CREATE_ISSUE": { - "TITLE": "Добавить проблему" + "TITLE": "Добавить задачу" }, "FEEDBACK": { "TITLE": "Расскажи что-нибудь...", @@ -794,8 +794,8 @@ "TOTAL_POINTS": "всего", "ADD": "+ Добавить Пользовательскую Историю", "ADD_BULK": "Добавить несколько Историй от Пользователей пакетно", - "PROMOTED": "Эта ПИ была сформирована из Проблемы:", - "TITLE_LINK_GO_TO_ISSUE": "Перейти к проблеме", + "PROMOTED": "Эта ПИ была сформирована из задачи:", + "TITLE_LINK_GO_TO_ISSUE": "Перейти к задаче", "EXTERNAL_REFERENCE": "Эта ПИ была создана из:", "GO_TO_EXTERNAL_REFERENCE": "Перейти в начало", "BLOCKED": "Эта пользовательская история заблокирована ", @@ -918,7 +918,7 @@ "CLOSED_TASKS": "завершённые
задачи", "IOCAINE_DOSES": "иокаина
дозы", "SHOW_STATISTICS_TITLE": "Показать статистику", - "TOGGLE_BAKLOG_GRAPH": "Показать/Скрыть график решения проблем" + "TOGGLE_BAKLOG_GRAPH": "Показать/Скрыть график решения задач" }, "SUMMARY": { "PROJECT_POINTS": "проектные
очки", @@ -1030,29 +1030,29 @@ "SUCCESS": "Oompa Loompas обновил ваш e-mail" }, "ISSUES": { - "PAGE_TITLE": "Проблемы - {{projectName}}", - "PAGE_DESCRIPTION": "Панель проблем проекта {{projectName}}: {{projectDescription}}", - "LIST_SECTION_NAME": "Проблемы", - "SECTION_NAME": "Детали проблемы", - "ACTION_NEW_ISSUE": "+НОВАЯ ПРОБЛЕМА", + "PAGE_TITLE": "Задачи - {{projectName}}", + "PAGE_DESCRIPTION": "Панель задач проекта {{projectName}}: {{projectDescription}}", + "LIST_SECTION_NAME": "Задачи", + "SECTION_NAME": "Детали задачи", + "ACTION_NEW_ISSUE": "+НОВАЯ ЗАДАЧА", "ACTION_PROMOTE_TO_US": "Повысить до пользовательской истории", "PLACEHOLDER_FILTER_NAME": "Введите название фильтра и нажмите \"ввод\"", - "PROMOTED": "Эта проблема была переделана в ПИ", - "EXTERNAL_REFERENCE": "Эта проблема была создана из:", + "PROMOTED": "Эта задача была переделана в ПИ", + "EXTERNAL_REFERENCE": "Эта задача была создана из:", "GO_TO_EXTERNAL_REFERENCE": "Перейти в начало", - "BLOCKED": "Эта проблема заблокирована", - "TITLE_PREVIOUS_ISSUE": "предыдущая проблема", - "TITLE_NEXT_ISSUE": "следующая проблема", - "ACTION_DELETE": "Удалить проблему", - "LIGHTBOX_TITLE_BLOKING_ISSUE": "Блокирующая проблема", + "BLOCKED": "Эта задача заблокирована", + "TITLE_PREVIOUS_ISSUE": "предыдущая задача", + "TITLE_NEXT_ISSUE": "следующая задача", + "ACTION_DELETE": "Удалить задачу", + "LIGHTBOX_TITLE_BLOKING_ISSUE": "Блокирующая задача", "FIELDS": { "PRIORITY": "Приоритет", "SEVERITY": "Важность", "TYPE": "Тип" }, "CONFIRM_PROMOTE": { - "TITLE": "Превратить эту проблему в новую история от пользователя", - "MESSAGE": "Вы уверены, что хотите создать новую ПИ из этой проблемы?" + "TITLE": "Превратить эту задачу в новую историю от пользователя", + "MESSAGE": "Вы уверены, что хотите создать новую ПИ из этой задачи?" }, "FILTERS": { "TITLE": "Фильтры", @@ -1089,14 +1089,14 @@ "TITLE_ACTION_CHANGE_STATUS": "Изменить статус", "TITLE_ACTION_ASSIGNED_TO": "Назначено", "EMPTY": { - "TITLE": "Нет проблем для отчёта :-)", - "SUBTITLE": "Вы нашли проблему?", - "ACTION_CREATE_ISSUE": "Создать новую проблему" + "TITLE": "Нет сообщённых задач :-)", + "SUBTITLE": "Вы нашли задачу?", + "ACTION_CREATE_ISSUE": "Создать новую задачу" } } }, "ISSUE": { - "PAGE_TITLE": "{{issueSubject}} - Проблема {{issueRef}} - {{projectName}}", + "PAGE_TITLE": "{{issueSubject}} - Задача {{issueRef}} - {{projectName}}", "PAGE_DESCRIPTION": "Статус: {{issueStatus }}. Тип: {{issueType}}, Приоритет: {{issuePriority}}. Важность: {{issueSeverity}}. Описание: {{issueDescription}}" }, "KANBAN": { @@ -1117,9 +1117,9 @@ }, "SEARCH": { "PAGE_TITLE": "Поиск - {{projectName}}", - "PAGE_DESCRIPTION": "Ищите что угодно, задачи, истории от пользователей, проблемы и вики-страницы, в проекте {{projectName}}: {{projectDescription}}", + "PAGE_DESCRIPTION": "Ищите что угодно, задачи, истории от пользователей и вики-страницы, в проекте {{projectName}}: {{projectDescription}}", "FILTER_USER_STORIES": "Истории от Пользователей", - "FILTER_ISSUES": "Проблемы", + "FILTER_ISSUES": "Задачи", "FILTER_TASKS": "Задачи", "FILTER_WIKI": "Вики страницы", "PLACEHOLDER_SEARCH": "Искать в...", @@ -1134,13 +1134,13 @@ "APP_TITLE": "КОМАНДА - {{projectName}}", "PLACEHOLDER_INPUT_SEARCH": "Искать по имени", "COLUMN_MR_WOLF": "Мр. Вульф", - "EXPLANATION_COLUMN_MR_WOLF": "Решёные проблемы", + "EXPLANATION_COLUMN_MR_WOLF": "Решёные задачи", "COLUMN_IOCAINE": "Употребляющий иокаин", "EXPLANATION_COLUMN_IOCAINE": "потреблено доз иокаина", "COLUMN_CERVANTES": "Сервантес", "EXPLANATION_COLUMN_CERVANTES": "Отредактировано вики-страниц", "COLUMN_BUG_HUNTER": "Охотник за ошибками", - "EXPLANATION_COLUMN_BUG_HUNTER": "Сообщенные проблемы", + "EXPLANATION_COLUMN_BUG_HUNTER": "Сообщенные задачи", "COLUMN_NIGHT_SHIFT": "Ночная смена", "EXPLANATION_COLUMN_NIGHT_SHIFT": "Задача закрыта", "COLUMN_TOTAL_POWER": "Могущество", @@ -1232,12 +1232,12 @@ "HINT3_TITLE": "Отсортируйте ваши проекты по признаку, наиболее важному для вас", "HINT3_TEXT": "Главные 10 проектов будут доступны непосредственно из верхней панели", "HINT4_TITLE": "Вы забыли над чем работали?", - "HINT4_TEXT": "Не переживайте, на вашем рабочем столе вы найдёте ваши активные задачи, проблемы, и истории от пользователей в том порядке, в котором вы над ними работали." + "HINT4_TEXT": "Не переживайте, на вашем рабочем столе вы найдёте ваши активные задачи и истории от пользователей в том порядке, в котором вы над ними работали." }, "TIMELINE": { "UPLOAD_ATTACHMENT": "{{username}} приложил новый файл к {{obj_name}}", "US_CREATED": "{{username}} создал новую ПИ {{obj_name}} в {{project_name}}", - "ISSUE_CREATED": "{{username}} указал на новую проблему {{obj_name}} в {{project_name}}", + "ISSUE_CREATED": "{{username}} создал новую задачу {{obj_name}} в {{project_name}}", "TASK_CREATED": "{{username}} создал новую задачу {{obj_name}} в {{project_name}}", "TASK_CREATED_WITH_US": "{{username}} создал новую задачу {{obj_name}} в {{project_name}}, которая принадлежит Задаче от Пользователя {{us_name}}", "WIKI_CREATED": "{{username}} создал новую вики-страницу {{obj_name}} в {{project_name}}", @@ -1247,19 +1247,19 @@ "US_UPDATED": "{{username}} обновил атрибут \"{{field_name}}\" ПИ {{obj_name}}", "US_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" для ПИ {{obj_name}} на {{new_value}}", "US_UPDATED_POINTS": "{{username}} установил очки для '{{role_name}}' для ПИ {{obj_name}} на {{new_value}}", - "ISSUE_UPDATED": "{{username}} обновил атрибут \"{{field_name}}\" проблемы {{obj_name}}", - "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" проблемы {{obj_name}} на {{new_value}}", + "ISSUE_UPDATED": "{{username}} обновил атрибут \"{{field_name}}\" задачи {{obj_name}}", + "ISSUE_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}} на {{new_value}}", "TASK_UPDATED": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}} на {{new_value}}", "TASK_UPDATED_WITH_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}} на {{new_value}}", "TASK_UPDATED_WITH_US": "{{username}} изменил атрибут \"{{field_name}}\" задачи {{obj_name}}, которая принадлежит ПИ {{us_name}}", "TASK_UPDATED_WITH_US_NEW_VALUE": "{{username}} установил атрибут \"{{field_name}}\" задачи {{obj_name}}, которая принадлежит ПИ {{us_name}}, на {{new_value}}", "WIKI_UPDATED": "{{username}} обновил вики-страницу {{obj_name}}", "NEW_COMMENT_US": "{{username}} прокомментировал ПИ {{obj_name}}", - "NEW_COMMENT_ISSUE": "{{username}} прокомментировал проблему {{obj_name}}", + "NEW_COMMENT_ISSUE": "{{username}} прокомментировал задачу {{obj_name}}", "NEW_COMMENT_TASK": "{{username}} прокомментировал задачу {{obj_name}}", "NEW_MEMBER": "У {{project_name}} появился новый участник", "US_ADDED_MILESTONE": "{{username}} добавил ПИ {{obj_name}} для {{sprint_name}}", - "US_MOVED": "{{username}} has moved the US {{obj_name}}", + "US_MOVED": "{{username}} переместил ПИ {{obj_name}}", "US_REMOVED_FROM_MILESTONE": "{{username}} добавил ПИ {{obj_name}} к списку задач", "BLOCKED": "{{username}} заблокировал {{obj_name}}", "UNBLOCKED": "{{username}} разблокировал {{obj_name}}", From 7c39dfbb8413634f9f71f6b31c10333bf422d9b2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 7 Sep 2015 12:19:10 +0100 Subject: [PATCH 113/403] Adding internationalization to date selector --- .../modules/common/custom-field-values.coffee | 43 ++++++++++++++++--- 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/app/coffee/modules/common/custom-field-values.coffee b/app/coffee/modules/common/custom-field-values.coffee index 1dad3100..4c8dd6be 100644 --- a/app/coffee/modules/common/custom-field-values.coffee +++ b/app/coffee/modules/common/custom-field-values.coffee @@ -118,10 +118,10 @@ CustomAttributesValuesDirective = ($templates, $storage) -> template: templateFn } -module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", CustomAttributesValuesDirective]) +module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", "$translate", CustomAttributesValuesDirective]) -CustomAttributeValueDirective = ($template, $selectedText, $compile) -> +CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate) -> template = $template.get("custom-attributes/custom-attribute-value.html", true) templateEdit = $template.get("custom-attributes/custom-attribute-value-edit.html", true) @@ -158,9 +158,40 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> selectedDate = date onOpen: => $el.picker.setDate(selectedDate) if selectedDate? - firstDay: 1 - format: 'DD MMM YYYY' - ) + i18n: { + previousMonth: $translate.instant("COMMON.PICKERDATE.PREV_MONTH"), + nextMonth: $translate.instant("COMMON.PICKERDATE.NEXT_MONTH"), + months: [$translate.instant("COMMON.PICKERDATE.MONTHS.JAN"), + $translate.instant("COMMON.PICKERDATE.MONTHS.FEB"), + $translate.instant("COMMON.PICKERDATE.MONTHS.MAR"), + $translate.instant("COMMON.PICKERDATE.MONTHS.APR"), + $translate.instant("COMMON.PICKERDATE.MONTHS.MAY"), + $translate.instant("COMMON.PICKERDATE.MONTHS.JUN"), + $translate.instant("COMMON.PICKERDATE.MONTHS.JUL"), + $translate.instant("COMMON.PICKERDATE.MONTHS.AUG"), + $translate.instant("COMMON.PICKERDATE.MONTHS.SEP"), + $translate.instant("COMMON.PICKERDATE.MONTHS.OCT"), + $translate.instant("COMMON.PICKERDATE.MONTHS.NOV"), + $translate.instant("COMMON.PICKERDATE.MONTHS.DEC")], + weekdays: [$translate.instant("COMMON.PICKERDATE.WEEK_DAYS.SUN"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.MON"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.TUE"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.WED"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.THU"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.FRI"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS.SAT")], + weekdaysShort: [$translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.SUN"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.MON"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.TUE"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.WED"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.THU"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.FRI"), + $translate.instant("COMMON.PICKERDATE.WEEK_DAYS_SHORT.SAT")] + }, + isRTL: $translate.instant("COMMON.PICKERDATE.IS_RTL") == "true", + firstDay: parseInt($translate.instant("COMMON.PICKERDATE.FIRST_DAY_OF_WEEK"), 10), + format: $translate.instant("COMMON.PICKERDATE.FORMAT") + ) isEditable = -> permissions = $scope.project.my_permissions @@ -218,4 +249,4 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile) -> restrict: "AE" } -module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", CustomAttributeValueDirective]) +module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", "$translate", CustomAttributeValueDirective]) From f12e664eec2b293dcea501b31cb90f280938c361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Mon, 7 Sep 2015 14:26:57 +0200 Subject: [PATCH 114/403] Fix permission error texts --- app/locales/locale-ca.json | 2 +- app/locales/locale-de.json | 2 +- app/locales/locale-en.json | 2 +- app/locales/locale-es.json | 2 +- app/locales/locale-fi.json | 2 +- app/locales/locale-fr.json | 2 +- app/locales/locale-nl.json | 2 +- app/locales/locale-pl.json | 2 +- app/locales/locale-pt-br.json | 2 +- app/locales/locale-ru.json | 2 +- app/locales/locale-zh-hant.json | 2 +- app/partials/error/permission-denied.jade | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/locales/locale-ca.json b/app/locales/locale-ca.json index c09e6d28..74ed7e34 100644 --- a/app/locales/locale-ca.json +++ b/app/locales/locale-ca.json @@ -953,7 +953,7 @@ "NOT_FOUND": "No trobat", "NOT_FOUND_TEXT": "Error 404. La pàgina que busques no existeix. Pots tornar a la página principal de taiga i provar desde allí.", "PERMISSION_DENIED": "Permis denegat", - "PERMISSION_DENIED_CODE": "Error 403", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Algú dins de Taiga ha canviat aȯ abans i els Oompa Loompas no pode aplicar els teus canvis. Per favor recarrega i aplica els teus canvis (es perdràn)" }, "TASKBOARD": { diff --git a/app/locales/locale-de.json b/app/locales/locale-de.json index 93d919b2..906e8e71 100644 --- a/app/locales/locale-de.json +++ b/app/locales/locale-de.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Nicht gefunden", "NOT_FOUND_TEXT": "Fehler 404. Die angeforderte Seite existiert nicht mehr. Möglicherweise finden Sie das Gesuchte, wenn Sie zur TAIGA Homepage zurückkehren. ", "PERMISSION_DENIED": "Berechtigung verweigert", - "PERMISSION_DENIED_CODE": "Fehler 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Jemand anderes hat dies schon geändert und unsere Helferlein können Ihre Änderungen deshalb nicht übernehmen. Bitte laden Sie die Seite neu und machen Sie die Änderungen erneut (die aktuelle Eingabe geht dabei verloren)." }, "TASKBOARD": { diff --git a/app/locales/locale-en.json b/app/locales/locale-en.json index f9f7d90d..1238244a 100644 --- a/app/locales/locale-en.json +++ b/app/locales/locale-en.json @@ -956,7 +956,7 @@ "NOT_FOUND": "Not found", "NOT_FOUND_TEXT": "Error 404. The page you are looking for no longer exists. Perhaps you can return back to TAIGA homepage and see if you can find what you are looking for.", "PERMISSION_DENIED": "Permission denied", - "PERMISSION_DENIED_CODE": "Error 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Someone inside Taiga has changed this before and our Oompa Loompas cannot apply your changes. Please reload and apply your changes again (they will be lost)." }, "TASKBOARD": { diff --git a/app/locales/locale-es.json b/app/locales/locale-es.json index b98ad82f..c7266d55 100644 --- a/app/locales/locale-es.json +++ b/app/locales/locale-es.json @@ -953,7 +953,7 @@ "NOT_FOUND": "No encontrado", "NOT_FOUND_TEXT": "Error 404. La página que estás buscando ya no existe. Puedes volver a la página de inicio de TAIGA y ver si encuentras lo que estás buscando. ", "PERMISSION_DENIED": "Permiso denegado", - "PERMISSION_DENIED_CODE": "Error 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Algún compañero se te ha adelantado y ha actualizado esto, nuestros Oompa Loompas no pueden aplicar tus cambios. Por favor, recarga la página y aplícalos nuevamente (se perderán)." }, "TASKBOARD": { diff --git a/app/locales/locale-fi.json b/app/locales/locale-fi.json index 542d260e..7292a3b1 100644 --- a/app/locales/locale-fi.json +++ b/app/locales/locale-fi.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Ei löytynyt", "NOT_FOUND_TEXT": "Virhe 404. Sivua ei löydy. Palaa takaisin TAIGA etusivulle ja katso löydätkö haluamasi sieltä.", "PERMISSION_DENIED": "Ei oikeutta", - "PERMISSION_DENIED_CODE": "Virhe 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Joku Taigassa on päivittänyt tätä ennen sinua. Muutoksiasi ei voida tallentaa. Lataa sivu uudestaan ja korjaa tilanne." }, "TASKBOARD": { diff --git a/app/locales/locale-fr.json b/app/locales/locale-fr.json index 92c30f84..24a3282c 100644 --- a/app/locales/locale-fr.json +++ b/app/locales/locale-fr.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Non trouvé", "NOT_FOUND_TEXT": "Erreur 404. La page que vous cherchez n'existe plus. Peut-être pouvez-vous retourner à la page d'accueil de Taiga et voir si vous trouvez ce que vous cherchez.", "PERMISSION_DENIED": "Permission refusée", - "PERMISSION_DENIED_CODE": "Erreur 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Quelqu'un a changé ça auparavant dans Taiga et nos Oompa Loompas ne peuvent appliquer vos modifications. Veuillez recharger la page et appliquer vos modifications de nouveaux (elles seront perdues)." }, "TASKBOARD": { diff --git a/app/locales/locale-nl.json b/app/locales/locale-nl.json index dead6855..a89c22e6 100644 --- a/app/locales/locale-nl.json +++ b/app/locales/locale-nl.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Niet gevonden", "NOT_FOUND_TEXT": "Error 404. De pagina die je zoekt bestaat niet meer. Misschien kan je terugkeren naar de TAIGA startpagina en kijken of je kan vinden wat je zoekt.", "PERMISSION_DENIED": "Niet toegestaan", - "PERMISSION_DENIED_CODE": "Error 403", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Iemand bij Taiga heeft dit vooraf veranderd en onze Oempa-Loempa's konden je veranderingen niet toepassen. Gelieve te herladen en je veranderingen opnieuw toe te passen (ze zullen verloren gaan)" }, "TASKBOARD": { diff --git a/app/locales/locale-pl.json b/app/locales/locale-pl.json index ad2c80ca..be851787 100644 --- a/app/locales/locale-pl.json +++ b/app/locales/locale-pl.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Nie znaleziono", "NOT_FOUND_TEXT": "Błąd 404 - strona której szukasz nie istnieje. Wróć do strony głównej Taiga i zobacz, czy znajdziesz tam to, czego szukasz.", "PERMISSION_DENIED": "Dostęp zabroniony", - "PERMISSION_DENIED_CODE": "Błąd 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Odśwież i zastosuj zmiany ponownie gdyż może ktoś przed Tobą zapisał jakieś zmiany." }, "TASKBOARD": { diff --git a/app/locales/locale-pt-br.json b/app/locales/locale-pt-br.json index ed9be5aa..dbb3f69a 100644 --- a/app/locales/locale-pt-br.json +++ b/app/locales/locale-pt-br.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Não encontrado", "NOT_FOUND_TEXT": "Erro 404. A página que você procura não existe mais. Você pode voltar para a página do TAIGA e ver se consegue encontrar o que está procurando.", "PERMISSION_DENIED": "Permissão negada", - "PERMISSION_DENIED_CODE": "Erro 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Alguém dentro da Taiga mudou isso antes e nosso Oompa Loompa não podem aplicar suas alterações. Recarregue a página e aplique-as novamente (elas serão perdidas, agora)." }, "TASKBOARD": { diff --git a/app/locales/locale-ru.json b/app/locales/locale-ru.json index 103beed8..ba427e56 100644 --- a/app/locales/locale-ru.json +++ b/app/locales/locale-ru.json @@ -953,7 +953,7 @@ "NOT_FOUND": "Не найдено", "NOT_FOUND_TEXT": "Ошибка 404. Страница не найдена.", "PERMISSION_DENIED": "Доступ закрыт", - "PERMISSION_DENIED_CODE": "Ошибка 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Кто-то в Тайге изменил это раньше вас и Умпа-Лумпы не могут применить ваши изменения. Пожалуйста обновите страницу (Внимание! При обновлении страницы текущие правки будут утеряны) и внесите правки еще раз." }, "TASKBOARD": { diff --git a/app/locales/locale-zh-hant.json b/app/locales/locale-zh-hant.json index 859ffa28..c8f495ae 100644 --- a/app/locales/locale-zh-hant.json +++ b/app/locales/locale-zh-hant.json @@ -953,7 +953,7 @@ "NOT_FOUND": "找不到", "NOT_FOUND_TEXT": "Error 404,你要找的網頁不存在,你可以稍後再回來TAIGA首頁,看看是否能再次找到要找的東西。", "PERMISSION_DENIED": "無此權限", - "PERMISSION_DENIED_CODE": "Error 403.", + "PERMISSION_DENIED_TEXT": "You don't have permission to access to this page.", "VERSION_ERROR": "Taiga某人之前更改了這個,而我們的工程師無法再做改變。請重新載入頁面來使用你的更新(之前設定將消失)" }, "TASKBOARD": { diff --git a/app/partials/error/permission-denied.jade b/app/partials/error/permission-denied.jade index 6f3b8efb..12869f63 100644 --- a/app/partials/error/permission-denied.jade +++ b/app/partials/error/permission-denied.jade @@ -5,5 +5,5 @@ div.error-main object.logo-svg(type="image/svg+xml", data="/svg/logo.svg") img(src="/images/logo.png", alt="TAIGA") h1.logo(translate="ERROR.PERMISSION_DENIED") - p.error-text(translate="ERROR.PERMISSION_DENIED_CODE") + p.error-text(translate="ERROR.PERMISSION_DENIED_TEXT") a(href="/", title="", translate="COMMON.GO_HOME") From 8acc9d1d3610e7238bf717c56859040826db2de7 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 8 Sep 2015 13:05:13 +0200 Subject: [PATCH 115/403] fix taiga-theme load twice --- app/coffee/modules/auth.coffee | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/app/coffee/modules/auth.coffee b/app/coffee/modules/auth.coffee index 55e7ea9a..ddab6374 100644 --- a/app/coffee/modules/auth.coffee +++ b/app/coffee/modules/auth.coffee @@ -43,6 +43,9 @@ class AuthService extends taiga.Service constructor: (@rootscope, @storage, @model, @rs, @http, @urls, @config, @translate, @currentUserService, @themeService) -> super() + + @._currentTheme = @config.get("defaultTheme") || "taiga" # load on index.jade + userModel = @.getUser() @.setUserdata(userModel) @@ -53,9 +56,15 @@ class AuthService extends taiga.Service else @.userData = null + _getUserTheme: -> + return @rootscope.user?.theme || @config.get("defaultTheme") || "taiga" + _setTheme: -> - theme = @rootscope.user?.theme || @config.get("defaultTheme") || "taiga" - @themeService.use(theme) + newTheme = @._getUserTheme() + + if @._currentTheme != newTheme + @._currentTheme = newTheme + @themeService.use(@._currentTheme) _setLocales: -> lang = @rootscope.user?.lang || @config.get("defaultLanguage") || "en" @@ -71,7 +80,9 @@ class AuthService extends taiga.Service user = @model.make_model("users", userData) @rootscope.user = user @._setLocales() + @._setTheme() + return user return null From a24762a6fba2dff4d84c789f32d4f9b135ccac27 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 8 Sep 2015 14:31:59 +0200 Subject: [PATCH 116/403] Fixing codehilite css file --- app/styles/vendor/codehilite.github.css | 125 ++++++++++++------------ 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/app/styles/vendor/codehilite.github.css b/app/styles/vendor/codehilite.github.css index fea31ecd..6121071b 100644 --- a/app/styles/vendor/codehilite.github.css +++ b/app/styles/vendor/codehilite.github.css @@ -1,61 +1,64 @@ -.hll { background-color: #ffc; } -.c { color: #998; font-style: italic; } // Comment -.err { background-color: #e3d2d2; color: #a61717; } // Error -.k { color: #000; font-weight: bold; } // Keyword -.o { color: #000; font-weight: bold; } // Operator -.cm { color: #998; font-style: italic; } // Comment.Multiline -.cp { color: #999; font-style: italic; font-weight: bold; } // Comment.Preproc -.c1 { color: #998; font-style: italic; } // Comment.Single -.cs { color: #999; font-style: italic; font-weight: bold; } // Comment.Special -.gd { background-color: #fdd; color: #000; } // Generic.Deleted -.ge { color: #000; font-style: italic; } // Generic.Emph -.gr { color: #a00; } // Generic.Error -.gh { color: #999; } // Generic.Heading -.gi { background-color: #dfd; color: #000; } // Generic.Inserted -.go { color: #888; } // Generic.Output -.gp { color: #555; } // Generic.Prompt -.gs { font-weight: bold; } // Generic.Strong -.gu { color: #aaa; } // Generic.Subheading -.gt { color: #a00; } // Generic.Traceback -.kc { color: #000; font-weight: bold; } // Keyword.Constant -.kd { color: #000; font-weight: bold; } // Keyword.Declaration -.kn { color: #000; font-weight: bold; } // Keyword.Namespace -.kp { color: #000; font-weight: bold; } // Keyword.Pseudo -.kr { color: #000; font-weight: bold; } // Keyword.Reserved -.kt { color: #458; font-weight: bold; } // Keyword.Type -.m { color: #099; } // Literal.Number -.s { color: #d01040; } // Literal.String -.na { color: #008080; } // Name.Attribute -.nb { color: #0086b3; } // Name.Builtin -.nc { color: #458; font-weight: bold; } // Name.Class -.no { color: #008080; } // Name.Constant -.nd { color: #3c5d5d; font-weight: bold; } // Name.Decorator -.ni { color: #800080; } // Name.Entity -.ne { color: #900; font-weight: bold; } // Name.Exception -.nf { color: #900; font-weight: bold; } // Name.Function -.nl { color: #900; font-weight: bold; } // Name.Label -.nn { color: #555; } // Name.Namespace -.nt { color: #000080; } // Name.Tag -.nv { color: #008080; } // Name.Variable -.ow { color: #000; font-weight: bold; } // Operator.Word -.w { color: #bbb; } // Text.Whitespace -.mf { color: #099; } // Literal.Number.Float -.mh { color: #099; } // Literal.Number.Hex -.mi { color: #099; } // Literal.Number.Integer -.mo { color: #099; } // Literal.Number.Oct -.sb { color: #d01040; } // Literal.String.Backtick -.sc { color: #d01040; } // Literal.String.Char -.sd { color: #d01040; } // Literal.String.Doc -.s2 { color: #d01040; } // Literal.String.Double -.se { color: #d01040; } // Literal.String.Escape -.sh { color: #d01040; } // Literal.String.Heredoc -.si { color: #d01040; } // Literal.String.Interpol -.sx { color: #d01040; } // Literal.String.Other -.sr { color: #009926; } // Literal.String.Regex -.s1 { color: #d01040; } // Literal.String.Single -.ss { color: #990073; } // Literal.String.Symbol -.bp { color: #999; } // Name.Builtin.Pseudo -.vc { color: #008080; } // Name.Variable.Class -.vg { color: #008080; } // Name.Variable.Global -.vi { color: #008080; } // Name.Variable.Instance -.il { color: #099; } // Literal.Number.Integer.Long +.codehilite .hll { background-color: #49483e } +.codehilite .c { color: #75715e } /* Comment */ +.codehilite .err { color: #960050; background-color: #1e0010 } /* Error */ +.codehilite .k { color: #66d9ef } /* Keyword */ +.codehilite .l { color: #ae81ff } /* Literal */ +.codehilite .n { color: #f8f8f2 } /* Name */ +.codehilite .o { color: #f92672 } /* Operator */ +.codehilite .p { color: #f8f8f2 } /* Punctuation */ +.codehilite .cm { color: #75715e } /* Comment.Multiline */ +.codehilite .cp { color: #75715e } /* Comment.Preproc */ +.codehilite .c1 { color: #75715e } /* Comment.Single */ +.codehilite .cs { color: #75715e } /* Comment.Special */ +.codehilite .ge { font-style: italic } /* Generic.Emph */ +.codehilite .gs { font-weight: bold } /* Generic.Strong */ +.codehilite .kc { color: #66d9ef } /* Keyword.Constant */ +.codehilite .kd { color: #66d9ef } /* Keyword.Declaration */ +.codehilite .kn { color: #f92672 } /* Keyword.Namespace */ +.codehilite .kp { color: #66d9ef } /* Keyword.Pseudo */ +.codehilite .kr { color: #66d9ef } /* Keyword.Reserved */ +.codehilite .kt { color: #66d9ef } /* Keyword.Type */ +.codehilite .ld { color: #e6db74 } /* Literal.Date */ +.codehilite .m { color: #ae81ff } /* Literal.Number */ +.codehilite .s { color: #e6db74 } /* Literal.String */ +.codehilite .na { color: #a6e22e } /* Name.Attribute */ +.codehilite .nb { color: #f8f8f2 } /* Name.Builtin */ +.codehilite .nc { color: #a6e22e } /* Name.Class */ +.codehilite .no { color: #66d9ef } /* Name.Constant */ +.codehilite .nd { color: #a6e22e } /* Name.Decorator */ +.codehilite .ni { color: #f8f8f2 } /* Name.Entity */ +.codehilite .ne { color: #a6e22e } /* Name.Exception */ +.codehilite .nf { color: #a6e22e } /* Name.Function */ +.codehilite .nl { color: #f8f8f2 } /* Name.Label */ +.codehilite .nn { color: #f8f8f2 } /* Name.Namespace */ +.codehilite .nx { color: #a6e22e } /* Name.Other */ +.codehilite .py { color: #f8f8f2 } /* Name.Property */ +.codehilite .nt { color: #f92672 } /* Name.Tag */ +.codehilite .nv { color: #f8f8f2 } /* Name.Variable */ +.codehilite .ow { color: #f92672 } /* Operator.Word */ +.codehilite .w { color: #f8f8f2 } /* Text.Whitespace */ +.codehilite .mf { color: #ae81ff } /* Literal.Number.Float */ +.codehilite .mh { color: #ae81ff } /* Literal.Number.Hex */ +.codehilite .mi { color: #ae81ff } /* Literal.Number.Integer */ +.codehilite .mo { color: #ae81ff } /* Literal.Number.Oct */ +.codehilite .sb { color: #e6db74 } /* Literal.String.Backtick */ +.codehilite .sc { color: #e6db74 } /* Literal.String.Char */ +.codehilite .sd { color: #e6db74 } /* Literal.String.Doc */ +.codehilite .s2 { color: #e6db74 } /* Literal.String.Double */ +.codehilite .se { color: #ae81ff } /* Literal.String.Escape */ +.codehilite .sh { color: #e6db74 } /* Literal.String.Heredoc */ +.codehilite .si { color: #e6db74 } /* Literal.String.Interpol */ +.codehilite .sx { color: #e6db74 } /* Literal.String.Other */ +.codehilite .sr { color: #e6db74 } /* Literal.String.Regex */ +.codehilite .s1 { color: #e6db74 } /* Literal.String.Single */ +.codehilite .ss { color: #e6db74 } /* Literal.String.Symbol */ +.codehilite .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +.codehilite .vc { color: #f8f8f2 } /* Name.Variable.Class */ +.codehilite .vg { color: #f8f8f2 } /* Name.Variable.Global */ +.codehilite .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +.codehilite .il { color: #ae81ff } /* Literal.Number.Integer.Long */ + +.codehilite .gh { } /* Generic Heading & Diff Header */ +.codehilite .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ +.codehilite .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ +.codehilite .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ From da12bdde932af6fba7430f6c7c905e40ac3fb3d9 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 15 Jun 2015 08:32:16 +0200 Subject: [PATCH 117/403] integration test infrastructure --- .gitignore | 1 + integration-test-conf.js | 34 +++++ integration/auth/auth.integrationSpec.js | 161 +++++++++++++++++++++++ integration/full/home.integrationSpec.js | 11 ++ integration/utils/common.js | 77 +++++++++++ integration/utils/index.js | 3 + integration/utils/lightbox.js | 40 ++++++ integration/utils/notifications.js | 50 +++++++ package.json | 1 + 9 files changed, 378 insertions(+) create mode 100644 integration-test-conf.js create mode 100644 integration/auth/auth.integrationSpec.js create mode 100644 integration/full/home.integrationSpec.js create mode 100644 integration/utils/common.js create mode 100644 integration/utils/index.js create mode 100644 integration/utils/lightbox.js create mode 100644 integration/utils/notifications.js diff --git a/.gitignore b/.gitignore index 18a1d2d1..81383148 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ tmp/ app/config/main.coffee app/plugins/taiga-front-extras scss-lint.log +integration/screenshots/ \ No newline at end of file diff --git a/integration-test-conf.js b/integration-test-conf.js new file mode 100644 index 00000000..1d037acf --- /dev/null +++ b/integration-test-conf.js @@ -0,0 +1,34 @@ +var utils = require('./integration/utils'); + +exports.config = { + seleniumAddress: 'http://localhost:4444/wd/hub', + framework: 'mocha', + mochaOpts: { + timeout: 5000 + }, + suites: { + auth: 'integration/auth/*.integrationSpec.js', + full: 'integration/full/**/*integrationSpec.js' + }, + onPrepare: function() { + browser.get('http://localhost:9001/login'); + + var username = $('input[name="username"]'); + username.sendKeys('admin'); + + var password = $('input[name="password"]'); + password.sendKeys('123123'); + + $('.submit-button').click(); + + return browser.driver.wait(function() { + return utils.common.closeCookies() + .then(function() { + return browser.driver.getCurrentUrl() + }) + .then(function(url) { + return url === 'http://localhost:9001/'; + }); + }, 10000); + } +} diff --git a/integration/auth/auth.integrationSpec.js b/integration/auth/auth.integrationSpec.js new file mode 100644 index 00000000..161b2048 --- /dev/null +++ b/integration/auth/auth.integrationSpec.js @@ -0,0 +1,161 @@ +var utils = require('../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('auth', function() { + it('login', function() { + browser.get('http://localhost:9001/login'); + + return utils.common.waitLoader().then(function() { + utils.common.takeScreenshot("auth", "login"); + + var username = $('input[name="username"]'); + username.sendKeys('admin'); + + var password = $('input[name="password"]'); + password.sendKeys('123123'); + + $('.submit-button').click(); + + return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); + }); + }); + + describe("user", function() { + var user = {}; + + describe("register", function() { + it('screenshot', function() { + browser.get('http://localhost:9001/register'); + + utils.common.waitLoader().then(function() { + utils.common.takeScreenshot("auth", "register"); + }); + }); + + it('register validation', function() { + browser.get('http://localhost:9001/register'); + + $('.submit-button').click(); + + utils.common.takeScreenshot("auth", "register-validation"); + + return expect($$('.checksley-required').count()).to.be.eventually.equal(4); + }); + + it('register ok', function() { + browser.get('http://localhost:9001/register'); + + user.username = "username-" + Math.random(); + user.fullname = "fullname-" + Math.random(); + user.password = "passsword-" + Math.random(); + user.email = "email-" + Math.random() + "@taiga.io"; + + $('input[name="username"]').sendKeys(user.username); + $('input[name="full_name"]').sendKeys(user.fullname); + $('input[name="email"]').sendKeys(user.email); + $('input[name="password"]').sendKeys(user.password); + + $('.submit-button').click(); + + return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); + }); + }); + + describe("change password", function() { + beforeEach(function(done) { + utils.common.login(user.username, user.password).then(function() { + browser.get('http://localhost:9001/user-settings/user-change-password'); + done(); + }); + }); + + it("error", function() { + $('#current-password').sendKeys('wrong'); + $('#new-password').sendKeys('123123'); + $('#retype-password').sendKeys('123123'); + + $('.submit-button').click(); + + return expect(utils.notifications.error.open()).to.be.eventually.equal(true); + }); + + it("success", function() { + $('#current-password').sendKeys(user.password); + $('#new-password').sendKeys(user.password); + $('#retype-password').sendKeys(user.password); + + $('.submit-button').click(); + + return expect(utils.notifications.success.open()).to.be.eventually.equal(true); + }); + }); + + describe("remember password", function() { + beforeEach(function() { + browser.get('http://localhost:9001/forgot-password'); + }); + + it ("screenshot", function() { + utils.common.waitLoader().then(function() { + utils.common.takeScreenshot("auth", "remember-password"); + }); + }); + + it ("error", function() { + $('input[name="username"]').sendKeys("xxxxxxxx"); + $('.submit-button').click(); + + return expect(utils.notifications.errorLight.open()).to.be.eventually.equal(true); + }); + + it ("success", function() { + $('input[name="username"]').sendKeys(user.username); + $('.submit-button').click(); + + return utils.lightbox.open('.lightbox-generic-success').then(function() { + utils.common.takeScreenshot('auth', 'remember-password-success'); + + $('.lightbox-generic-success .button-green').click(); + + return expect(utils.lightbox.close('.lightbox-generic-success')).to.be.eventually.equal(true); + }); + }); + }); + + describe("", function() { + it("logout", function() { + return utils.common.login(user.username, user.password) + .then(function() { + browser.actions().mouseMove($('div[tg-dropdown-user]')).perform(); + $$('.dropdown-user li a').last().click(); + + return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/login'); + }) + }); + + it("delete account", function() { + return utils.common.login(user.username, user.password) + .then(function() { + browser.get('http://localhost:9001/user-settings/user-profile'); + $('.delete-account').click(); + + return utils.lightbox.open('.lightbox-delete-account'); + }) + .then(function() { + utils.common.takeScreenshot("auth", "delete-account"); + + $('#unsuscribe').click(); + $('.lightbox-delete-account .button-green').click(); + + return expect(browser.getCurrentUrl()) + .to.be.eventually.equal('http://localhost:9001/login'); + }); + }); + }); + }); +}); diff --git a/integration/full/home.integrationSpec.js b/integration/full/home.integrationSpec.js new file mode 100644 index 00000000..bc2c0716 --- /dev/null +++ b/integration/full/home.integrationSpec.js @@ -0,0 +1,11 @@ +var utils = require('../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('home', function() { + +}); diff --git a/integration/utils/common.js b/integration/utils/common.js new file mode 100644 index 00000000..fd9bed66 --- /dev/null +++ b/integration/utils/common.js @@ -0,0 +1,77 @@ +var common = module.exports; + +var fs = require('fs'); + +common.hasClass = function (element, cls) { + return element.getAttribute('class').then(function (classes) { + return classes.split(' ').indexOf(cls) !== -1; + }); +}; + +common.waitLoader = function () { + var el = $(".loader"); + + return browser.wait(function() { + return common.hasClass(el, 'active').then(function(active) { + return !active; + }); + }, 5000); +}; + +common.takeScreenshot = function (section, filename) { + var screenshotsFolder = __dirname + "/../screenshots/"; + var dir = screenshotsFolder + section + "/"; + + if (!fs.existsSync(screenshotsFolder)) { + fs.mkdirSync(screenshotsFolder); + } + + return browser.takeScreenshot().then(function (data) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } + + var path = dir + filename + ".png"; + var stream = fs.createWriteStream(path); + + stream.write(new Buffer(data, 'base64')); + stream.end(); + }); +}; + +common.closeCookies = function() { + return browser.executeScript(function() { + document.cookie='cookieConsent=1'; + }); +}; + +// common.waitLoad = function() { +// var deferred = protractor.promise.defer(); + +// common.waitLoader().then(function() { +// deferred.fulfill(); +// }); + +// return deferred.promise; +// }; + +common.login = function(username, password) { + browser.get('http://localhost:9001/login'); + + $('input[name="username"]').sendKeys(username); + $('input[name="password"]').sendKeys(password); + + $('.submit-button').click(); + + return browser.driver.wait(function() { + return browser.driver.getCurrentUrl().then(function(url) { + return url === 'http://localhost:9001/'; + }); + }, 10000); +}; + +common.prepare = function() { + browser.get('http://localhost:9001/'); + + return common.closeCookies() +} diff --git a/integration/utils/index.js b/integration/utils/index.js new file mode 100644 index 00000000..1e63c735 --- /dev/null +++ b/integration/utils/index.js @@ -0,0 +1,3 @@ +module.exports.common = require("./common"); +module.exports.notifications = require("./notifications"); +module.exports.lightbox = require("./lightbox"); diff --git a/integration/utils/lightbox.js b/integration/utils/lightbox.js new file mode 100644 index 00000000..949d3660 --- /dev/null +++ b/integration/utils/lightbox.js @@ -0,0 +1,40 @@ +var common = require('./common') + +var lightbox = module.exports; +var transition = 300; + +lightbox.open = function(el) { + var deferred = protractor.promise.defer(); + + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + browser + .wait(function() { + return common.hasClass(el, 'open') + }, 2000) + .then(function(open) { + return browser.sleep(transition).then(function() { + if (open) { + deferred.fulfill(open); + } else { + deferred.reject(new Error('Lightbox doesn\'t open')); + } + }); + }); + + return deferred.promise; +}; + +lightbox.close = function(el) { + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + return browser.wait(function() { + return common.hasClass(el, 'open').then(function(open) { + return !open; + }); + }, 2000); +}; diff --git a/integration/utils/notifications.js b/integration/utils/notifications.js new file mode 100644 index 00000000..cd242b9b --- /dev/null +++ b/integration/utils/notifications.js @@ -0,0 +1,50 @@ +var common = require('./common') + +var notifications = module.exports; + +var transition = 600; + +notifications.success = {}; +notifications.success.open = function() { + var el = $('.notification-message-success'); + + return browser + .wait(function() { + return common.hasClass(el, 'active') + }, 2000) + .then(function(active) { + return browser.sleep(transition).then(function() { + return active; + }); + }); +}; + +notifications.error = {}; +notifications.error.open = function() { + var el = $('.notification-message-error'); + + return browser + .wait(function() { + return common.hasClass(el, 'active') + }, 2000) + .then(function(active) { + return browser.sleep(transition).then(function() { + return active; + }); + }); +}; + +notifications.errorLight = {}; +notifications.errorLight.open = function() { + var el = $('.notification-message-light-error'); + + return browser + .wait(function() { + return common.hasClass(el, 'active') + }, 2000) + .then(function(active) { + return browser.sleep(transition).then(function() { + return active; + }); + }); +}; diff --git a/package.json b/package.json index bfd6dd6b..6b518ffd 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "devDependencies": { "angular-mocks": "^1.3.15", "chai": "^2.2.0", + "chai-as-promised": "^5.1.0", "chai-jquery": "^2.0.0", "cli-color": "^0.3.3", "coffee-script": "^1.9.1", From 79ad02ea6e8301f6932161de84f3ae8e56071f4e Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 23 Jun 2015 15:44:48 +0200 Subject: [PATCH 118/403] home integration test --- .../components/sort-projects.directive.coffee | 2 +- integration/full/home.integrationSpec.js | 74 +++++++++++++++++++ integration/utils/common.js | 19 +++++ integration/utils/lightbox.js | 35 +++++---- 4 files changed, 115 insertions(+), 15 deletions(-) diff --git a/app/modules/projects/components/sort-projects.directive.coffee b/app/modules/projects/components/sort-projects.directive.coffee index b25d4573..476e0db9 100644 --- a/app/modules/projects/components/sort-projects.directive.coffee +++ b/app/modules/projects/components/sort-projects.directive.coffee @@ -8,7 +8,7 @@ SortProjectsDirective = (currentUserService) -> axis: "y" opacity: .95 placeholder: 'placeholder' - cancel: '.project-name' + cancel: '.project-name' }) el.on "sortstop", (event, ui) -> diff --git a/integration/full/home.integrationSpec.js b/integration/full/home.integrationSpec.js index bc2c0716..16f59217 100644 --- a/integration/full/home.integrationSpec.js +++ b/integration/full/home.integrationSpec.js @@ -7,5 +7,79 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('home', function() { + before(function(){ + browser.get('http://localhost:9001/'); + return utils.common.waitLoader().then(function() { + return utils.common.takeScreenshot("home", "dashboard"); + }); + }); + + it('working on filled', function() { + return expect($$('.working-on div[tg-duty]').count()).to.be.eventually.above(0); + }); + + it('watching filled', function() { + return expect($$('.watching div[tg-duty]').count()).to.be.eventually.above(0); + }); + + it('project list filled', function() { + return expect($$('.home-project-list-single').count()).to.be.eventually.above(0); + }); + + describe('projects list', function() { + before(function() { + browser.get('http://localhost:9001/projects/'); + + return utils.common.waitLoader().then(function() { + return utils.common.takeScreenshot("home", "projects"); + }); + }); + + it('open create project lightbox', function() { + $('.master .create-project-btn').click(); + + return expect(utils.lightbox.open('div[tg-lb-create-project]')).to.be.eventually.equal(true); + }); + + it('close create project lightbox', function() { + $('div[tg-lb-create-project] .icon-delete').click(); + + return expect(utils.lightbox.close('div[tg-lb-create-project]')).to.be.eventually.equal(true); + }); + }); + + describe("project drag and drop", function() { + var draggedElementText; + + before(function() { + browser.get('http://localhost:9001/projects/'); + + var dragableElements = element.all(by.css('.project-list-single')); + var dragElement = dragableElements.get(3); + var dragElementLink = dragElement.element(by.css('a')); + + return utils.common.waitLoader() + .then(function() { + return dragElementLink.getText() + }) + .then(function(_draggedElementText_) { + draggedElementText = _draggedElementText_; + + return utils.common.drag(dragElement, dragableElements.get(0)) + }); + }); + + it('projects list has the new order', function() { + var firstElement = $$('.project-list-single a').first().getText(); + + expect(firstElement).to.be.eventually.equal(draggedElementText); + }); + + it('projects menu has the new order', function() { + var firstElementText = $$('div[tg-dropdown-project-list] ul a').first().getInnerHtml(); + + expect(firstElementText).to.be.eventually.equal(draggedElementText); + }); + }); }); diff --git a/integration/utils/common.js b/integration/utils/common.js index fd9bed66..7695ee71 100644 --- a/integration/utils/common.js +++ b/integration/utils/common.js @@ -75,3 +75,22 @@ common.prepare = function() { return common.closeCookies() } + +common.dragEnd = function(elm) { + return browser.wait(function() { + return element.all(by.css('.ui-sortable-helper')).count() + .then(function(count) { + return count === 0; + }); + }, 1000); +}; + +common.drag = function(elm, location) { + return browser + .actions() + .dragAndDrop(elm, location) + .perform() + .then(function() { + return common.dragEnd(); + }) +}; diff --git a/integration/utils/lightbox.js b/integration/utils/lightbox.js index 949d3660..10c9ccba 100644 --- a/integration/utils/lightbox.js +++ b/integration/utils/lightbox.js @@ -6,18 +6,14 @@ var transition = 300; lightbox.open = function(el) { var deferred = protractor.promise.defer(); - if (typeof el == 'string' || el instanceof String) { - el = $(el); - } - browser .wait(function() { - return common.hasClass(el, 'open') + return common.hasClass($(el), 'open') }, 2000) .then(function(open) { return browser.sleep(transition).then(function() { if (open) { - deferred.fulfill(open); + deferred.fulfill(true); } else { deferred.reject(new Error('Lightbox doesn\'t open')); } @@ -28,13 +24,24 @@ lightbox.open = function(el) { }; lightbox.close = function(el) { - if (typeof el == 'string' || el instanceof String) { - el = $(el); - } + var deferred = protractor.promise.defer(); - return browser.wait(function() { - return common.hasClass(el, 'open').then(function(open) { - return !open; - }); - }, 2000); + $(el).isPresent().then(function(present) { + if (!present) { + deferred.fulfill(true); + } else { + return browser.wait(function() { + return common.hasClass($(el), 'open').then(function(open) { + return !open; + }); + }, 2000) + .then(function() { + return deferred.fulfill(true); + }, function() { + deferred.reject(new Error('Lightbox doesn\'t close')); + }); + } + }) + + return deferred.promise; }; From 0dee45b2f6dc00c68a89a9919db3a68901395b9d Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 24 Jun 2015 13:47:31 +0200 Subject: [PATCH 119/403] project home --- .../full/project-home.integrationSpec.js | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 integration/full/project-home.integrationSpec.js diff --git a/integration/full/project-home.integrationSpec.js b/integration/full/project-home.integrationSpec.js new file mode 100644 index 00000000..8e253d21 --- /dev/null +++ b/integration/full/project-home.integrationSpec.js @@ -0,0 +1,52 @@ +var utils = require('../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('project home', function() { + before(function(){ + browser.get('http://localhost:9001/'); + + return utils.common.waitLoader().then(function() { + return utils.common.takeScreenshot("project", "home"); + }); + }); + + it('go to project', function() { + browser.actions().mouseMove($('div[tg-dropdown-project-list]')).perform(); + $$('div[tg-dropdown-project-list] ul a').first().click(); + }); + + it('timeline filled', function() { + return expect($$('div[tg-user-timeline-item]').count()).to.be.eventually.above(0); + }); + + it('timeline pagination', function(done) { + $$('div[tg-user-timeline-item]') + .count() + .then(function(startTotal) { + return browser.executeScript('window.scrollTo(0,document.body.scrollHeight)') + .then(function() { + return browser.waitForAngular(); + }) + .then(function() { + return $$('div[tg-user-timeline-item]').count(); + }) + .then(function(endTotal) { + return startTotal < endTotal; + }); + }) + .then(function(hasMoreItems) { + expect(hasMoreItems).to.be.equal(true); + + done(); + }); + }); + + it('team filled', function() { + return expect($$('ul.involved-team a').count()).to.be.eventually.above(0); + }); +}); From 43f1732122226c3f91e90f30459a48dadc89153b Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 25 Jun 2015 07:54:48 +0200 Subject: [PATCH 120/403] add babel in the integration tests --- integration-test-conf.js | 4 + integration/auth/auth.integrationSpec.js | 105 +++++++++--------- integration/full/backlog.integrationSpec.js | 25 +++++ integration/full/home.integrationSpec.js | 36 +++--- .../full/project-home.integrationSpec.js | 36 +++--- integration/utils/common.js | 69 +++++------- integration/utils/lightbox.js | 26 ++--- package.json | 1 + 8 files changed, 150 insertions(+), 152 deletions(-) create mode 100644 integration/full/backlog.integrationSpec.js diff --git a/integration-test-conf.js b/integration-test-conf.js index 1d037acf..d6013ba8 100644 --- a/integration-test-conf.js +++ b/integration-test-conf.js @@ -1,3 +1,7 @@ +require("babel/register")({ + stage: 1 +}); + var utils = require('./integration/utils'); exports.config = { diff --git a/integration/auth/auth.integrationSpec.js b/integration/auth/auth.integrationSpec.js index 161b2048..59082059 100644 --- a/integration/auth/auth.integrationSpec.js +++ b/integration/auth/auth.integrationSpec.js @@ -7,34 +7,34 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('auth', function() { - it('login', function() { + it('login', async function() { browser.get('http://localhost:9001/login'); - return utils.common.waitLoader().then(function() { - utils.common.takeScreenshot("auth", "login"); + await utils.common.waitLoader(); - var username = $('input[name="username"]'); - username.sendKeys('admin'); + utils.common.takeScreenshot("auth", "login"); - var password = $('input[name="password"]'); - password.sendKeys('123123'); + var username = $('input[name="username"]'); + username.sendKeys('admin'); - $('.submit-button').click(); + var password = $('input[name="password"]'); + password.sendKeys('123123'); - return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); - }); + $('.submit-button').click(); + + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); }); describe("user", function() { var user = {}; describe("register", function() { - it('screenshot', function() { + it('screenshot', async function() { browser.get('http://localhost:9001/register'); - utils.common.waitLoader().then(function() { - utils.common.takeScreenshot("auth", "register"); - }); + await utils.common.waitLoader(); + + utils.common.takeScreenshot("auth", "register"); }); it('register validation', function() { @@ -44,7 +44,7 @@ describe('auth', function() { utils.common.takeScreenshot("auth", "register-validation"); - return expect($$('.checksley-required').count()).to.be.eventually.equal(4); + expect($$('.checksley-required').count()).to.be.eventually.equal(4); }); it('register ok', function() { @@ -62,16 +62,15 @@ describe('auth', function() { $('.submit-button').click(); - return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/'); }); }); describe("change password", function() { - beforeEach(function(done) { - utils.common.login(user.username, user.password).then(function() { - browser.get('http://localhost:9001/user-settings/user-change-password'); - done(); - }); + beforeEach(async function() { + await utils.common.login(user.username, user.password); + + browser.get('http://localhost:9001/user-settings/user-change-password'); }); it("error", function() { @@ -81,7 +80,7 @@ describe('auth', function() { $('.submit-button').click(); - return expect(utils.notifications.error.open()).to.be.eventually.equal(true); + expect(utils.notifications.error.open()).to.be.eventually.equal(true); }); it("success", function() { @@ -91,7 +90,7 @@ describe('auth', function() { $('.submit-button').click(); - return expect(utils.notifications.success.open()).to.be.eventually.equal(true); + expect(utils.notifications.success.open()).to.be.eventually.equal(true); }); }); @@ -100,61 +99,57 @@ describe('auth', function() { browser.get('http://localhost:9001/forgot-password'); }); - it ("screenshot", function() { - utils.common.waitLoader().then(function() { - utils.common.takeScreenshot("auth", "remember-password"); - }); + it ("screenshot", async function() { + await utils.common.waitLoader(); + + utils.common.takeScreenshot("auth", "remember-password"); }); it ("error", function() { $('input[name="username"]').sendKeys("xxxxxxxx"); $('.submit-button').click(); - return expect(utils.notifications.errorLight.open()).to.be.eventually.equal(true); + expect(utils.notifications.errorLight.open()).to.be.eventually.equal(true); }); - it ("success", function() { + it ("success", async function() { $('input[name="username"]').sendKeys(user.username); $('.submit-button').click(); - return utils.lightbox.open('.lightbox-generic-success').then(function() { - utils.common.takeScreenshot('auth', 'remember-password-success'); + await utils.lightbox.open('.lightbox-generic-success'); - $('.lightbox-generic-success .button-green').click(); + utils.common.takeScreenshot('auth', 'remember-password-success'); - return expect(utils.lightbox.close('.lightbox-generic-success')).to.be.eventually.equal(true); - }); + $('.lightbox-generic-success .button-green').click(); + + expect(utils.lightbox.close('.lightbox-generic-success')).to.be.eventually.equal(true); }); }); describe("", function() { - it("logout", function() { - return utils.common.login(user.username, user.password) - .then(function() { - browser.actions().mouseMove($('div[tg-dropdown-user]')).perform(); - $$('.dropdown-user li a').last().click(); + it("logout", async function() { + await utils.common.login(user.username, user.password); - return expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/login'); - }) + browser.actions().mouseMove($('div[tg-dropdown-user]')).perform(); + $$('.dropdown-user li a').last().click(); + + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/login'); }); - it("delete account", function() { - return utils.common.login(user.username, user.password) - .then(function() { - browser.get('http://localhost:9001/user-settings/user-profile'); - $('.delete-account').click(); + it("delete account", async function() { + await utils.common.login(user.username, user.password); - return utils.lightbox.open('.lightbox-delete-account'); - }) - .then(function() { - utils.common.takeScreenshot("auth", "delete-account"); + browser.get('http://localhost:9001/user-settings/user-profile'); + $('.delete-account').click(); - $('#unsuscribe').click(); - $('.lightbox-delete-account .button-green').click(); + await utils.lightbox.open('.lightbox-delete-account'); - return expect(browser.getCurrentUrl()) - .to.be.eventually.equal('http://localhost:9001/login'); - }); + utils.common.takeScreenshot("auth", "delete-account"); + + $('#unsuscribe').click(); + $('.lightbox-delete-account .button-green').click(); + + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/login'); }); }); }); diff --git a/integration/full/backlog.integrationSpec.js b/integration/full/backlog.integrationSpec.js new file mode 100644 index 00000000..4ebdef1f --- /dev/null +++ b/integration/full/backlog.integrationSpec.js @@ -0,0 +1,25 @@ +var utils = require('../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe.skip('backlog', function() { + before(function(){ + browser.get('http://localhost:9001/project/user7-project-example-0/'); + + return utils.common.waitLoader().then(function() { + return utils.common.takeScreenshot('backlog', 'backlog'); + }); + }); + + it('create US', function() { + $('.new-us a').click(); + + lightbox.open('div[tg-lb-create-edit-userstory]').then(function() { + + }); + }); +}); diff --git a/integration/full/home.integrationSpec.js b/integration/full/home.integrationSpec.js index 16f59217..ea7b4911 100644 --- a/integration/full/home.integrationSpec.js +++ b/integration/full/home.integrationSpec.js @@ -7,12 +7,11 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('home', function() { - before(function(){ + before(async function(){ browser.get('http://localhost:9001/'); - return utils.common.waitLoader().then(function() { - return utils.common.takeScreenshot("home", "dashboard"); - }); + await utils.common.waitLoader(); + utils.common.takeScreenshot("home", "dashboard"); }); it('working on filled', function() { @@ -28,12 +27,11 @@ describe('home', function() { }); describe('projects list', function() { - before(function() { + before(async function() { browser.get('http://localhost:9001/projects/'); - return utils.common.waitLoader().then(function() { - return utils.common.takeScreenshot("home", "projects"); - }); + await utils.common.waitLoader(); + utils.common.takeScreenshot("home", "projects"); }); it('open create project lightbox', function() { @@ -52,22 +50,19 @@ describe('home', function() { describe("project drag and drop", function() { var draggedElementText; - before(function() { + before(async function() { browser.get('http://localhost:9001/projects/'); - var dragableElements = element.all(by.css('.project-list-single')); - var dragElement = dragableElements.get(3); - var dragElementLink = dragElement.element(by.css('a')); + let dragableElements = element.all(by.css('.project-list-single')); + let dragElement = dragableElements.get(3); + let dragElementLink = dragElement.element(by.css('a')); - return utils.common.waitLoader() - .then(function() { - return dragElementLink.getText() - }) - .then(function(_draggedElementText_) { - draggedElementText = _draggedElementText_; + await utils.common.waitLoader(); - return utils.common.drag(dragElement, dragableElements.get(0)) - }); + draggedElementText = await dragElementLink.getText(); + + await utils.common.drag(dragElement, dragableElements.get(0)); + await browser.waitForAngular(); }); it('projects list has the new order', function() { @@ -81,5 +76,6 @@ describe('home', function() { expect(firstElementText).to.be.eventually.equal(draggedElementText); }); + }); }); diff --git a/integration/full/project-home.integrationSpec.js b/integration/full/project-home.integrationSpec.js index 8e253d21..b19cdf62 100644 --- a/integration/full/project-home.integrationSpec.js +++ b/integration/full/project-home.integrationSpec.js @@ -7,12 +7,11 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('project home', function() { - before(function(){ + before(async function(){ browser.get('http://localhost:9001/'); - return utils.common.waitLoader().then(function() { - return utils.common.takeScreenshot("project", "home"); - }); + await utils.common.waitLoader(); + await utils.common.takeScreenshot("project", "home"); }); it('go to project', function() { @@ -24,26 +23,17 @@ describe('project home', function() { return expect($$('div[tg-user-timeline-item]').count()).to.be.eventually.above(0); }); - it('timeline pagination', function(done) { - $$('div[tg-user-timeline-item]') - .count() - .then(function(startTotal) { - return browser.executeScript('window.scrollTo(0,document.body.scrollHeight)') - .then(function() { - return browser.waitForAngular(); - }) - .then(function() { - return $$('div[tg-user-timeline-item]').count(); - }) - .then(function(endTotal) { - return startTotal < endTotal; - }); - }) - .then(function(hasMoreItems) { - expect(hasMoreItems).to.be.equal(true); + it('timeline pagination', async function() { + let startTotal = await $$('div[tg-user-timeline-item]').count(); - done(); - }); + await browser.executeScript('window.scrollTo(0,document.body.scrollHeight)'); + await browser.waitForAngular(); + + let endTotal = await $$('div[tg-user-timeline-item]').count(); + + let hasMoreItems = startTotal < endTotal; + + expect(hasMoreItems).to.be.equal(true); }); it('team filled', function() { diff --git a/integration/utils/common.js b/integration/utils/common.js index 7695ee71..575aa450 100644 --- a/integration/utils/common.js +++ b/integration/utils/common.js @@ -2,41 +2,41 @@ var common = module.exports; var fs = require('fs'); -common.hasClass = function (element, cls) { - return element.getAttribute('class').then(function (classes) { - return classes.split(' ').indexOf(cls) !== -1; - }); +common.hasClass = async function (element, cls) { + let classes = await element.getAttribute('class'); + + return classes.split(' ').indexOf(cls) !== -1; }; common.waitLoader = function () { - var el = $(".loader"); + let el = $(".loader"); - return browser.wait(function() { - return common.hasClass(el, 'active').then(function(active) { - return !active; - }); + return browser.wait(async function() { + let active = await common.hasClass(el, 'active'); + + return !active; }, 5000); }; -common.takeScreenshot = function (section, filename) { - var screenshotsFolder = __dirname + "/../screenshots/"; - var dir = screenshotsFolder + section + "/"; +common.takeScreenshot = async function (section, filename) { + let screenshotsFolder = __dirname + "/../screenshots/"; + let dir = screenshotsFolder + section + "/"; if (!fs.existsSync(screenshotsFolder)) { fs.mkdirSync(screenshotsFolder); } - return browser.takeScreenshot().then(function (data) { - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir); - } + let data = await browser.takeScreenshot(); - var path = dir + filename + ".png"; - var stream = fs.createWriteStream(path); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir); + } - stream.write(new Buffer(data, 'base64')); - stream.end(); - }); + let path = dir + filename + ".png"; + let stream = fs.createWriteStream(path); + + stream.write(new Buffer(data, 'base64')); + stream.end(); }; common.closeCookies = function() { @@ -45,16 +45,6 @@ common.closeCookies = function() { }); }; -// common.waitLoad = function() { -// var deferred = protractor.promise.defer(); - -// common.waitLoader().then(function() { -// deferred.fulfill(); -// }); - -// return deferred.promise; -// }; - common.login = function(username, password) { browser.get('http://localhost:9001/login'); @@ -63,10 +53,10 @@ common.login = function(username, password) { $('.submit-button').click(); - return browser.driver.wait(function() { - return browser.driver.getCurrentUrl().then(function(url) { - return url === 'http://localhost:9001/'; - }); + return browser.driver.wait(async function() { + let url = await browser.driver.getCurrentUrl(); + + return url === 'http://localhost:9001/'; }, 10000); }; @@ -77,11 +67,10 @@ common.prepare = function() { } common.dragEnd = function(elm) { - return browser.wait(function() { - return element.all(by.css('.ui-sortable-helper')).count() - .then(function(count) { - return count === 0; - }); + return browser.wait(async function() { + let count = await element.all(by.css('.ui-sortable-helper')).count() + + return count === 0; }, 1000); }; diff --git a/integration/utils/lightbox.js b/integration/utils/lightbox.js index 10c9ccba..df5d0e82 100644 --- a/integration/utils/lightbox.js +++ b/integration/utils/lightbox.js @@ -3,22 +3,20 @@ var common = require('./common') var lightbox = module.exports; var transition = 300; -lightbox.open = function(el) { +lightbox.open = async function(el) { var deferred = protractor.promise.defer(); - browser - .wait(function() { - return common.hasClass($(el), 'open') - }, 2000) - .then(function(open) { - return browser.sleep(transition).then(function() { - if (open) { - deferred.fulfill(true); - } else { - deferred.reject(new Error('Lightbox doesn\'t open')); - } - }); - }); + let open = await browser.wait(function() { + return common.hasClass($(el), 'open') + }, 2000); + + await browser.sleep(transition); + + if (open) { + deferred.fulfill(true); + } else { + deferred.reject(new Error('Lightbox doesn\'t open')); + } return deferred.promise; }; diff --git a/package.json b/package.json index 6b518ffd..5280d7b9 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "devDependencies": { "angular-mocks": "^1.3.15", + "babel": "^5.6.5", "chai": "^2.2.0", "chai-as-promised": "^5.1.0", "chai-jquery": "^2.0.0", From 05290fbb04afedc35cb08e936ed09a72b740f00a Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 25 Jun 2015 08:02:05 +0200 Subject: [PATCH 121/403] rename integrationSpec to e2e --- .gitignore | 2 +- integration-test-conf.js => conf.e2e.js | 6 +++--- .../auth/auth.integrationSpec.js => e2e/auth/auth.e2e.js | 0 .../backlog.integrationSpec.js => e2e/full/backlog.e2e.js | 0 .../full/home.integrationSpec.js => e2e/full/home.e2e.js | 0 .../full/project-home.e2e.js | 4 ++-- {integration => e2e}/utils/common.js | 0 {integration => e2e}/utils/index.js | 0 {integration => e2e}/utils/lightbox.js | 0 {integration => e2e}/utils/notifications.js | 0 10 files changed, 6 insertions(+), 6 deletions(-) rename integration-test-conf.js => conf.e2e.js (84%) rename integration/auth/auth.integrationSpec.js => e2e/auth/auth.e2e.js (100%) rename integration/full/backlog.integrationSpec.js => e2e/full/backlog.e2e.js (100%) rename integration/full/home.integrationSpec.js => e2e/full/home.e2e.js (100%) rename integration/full/project-home.integrationSpec.js => e2e/full/project-home.e2e.js (86%) rename {integration => e2e}/utils/common.js (100%) rename {integration => e2e}/utils/index.js (100%) rename {integration => e2e}/utils/lightbox.js (100%) rename {integration => e2e}/utils/notifications.js (100%) diff --git a/.gitignore b/.gitignore index 81383148..1731e03e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,4 @@ tmp/ app/config/main.coffee app/plugins/taiga-front-extras scss-lint.log -integration/screenshots/ \ No newline at end of file +e2e/screenshots/ \ No newline at end of file diff --git a/integration-test-conf.js b/conf.e2e.js similarity index 84% rename from integration-test-conf.js rename to conf.e2e.js index d6013ba8..27afdcb1 100644 --- a/integration-test-conf.js +++ b/conf.e2e.js @@ -2,7 +2,7 @@ require("babel/register")({ stage: 1 }); -var utils = require('./integration/utils'); +var utils = require('./e2e/utils'); exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', @@ -11,8 +11,8 @@ exports.config = { timeout: 5000 }, suites: { - auth: 'integration/auth/*.integrationSpec.js', - full: 'integration/full/**/*integrationSpec.js' + auth: 'e2e/auth/*.e2e.js', + full: 'e2e/full/**/*.e2e.js' }, onPrepare: function() { browser.get('http://localhost:9001/login'); diff --git a/integration/auth/auth.integrationSpec.js b/e2e/auth/auth.e2e.js similarity index 100% rename from integration/auth/auth.integrationSpec.js rename to e2e/auth/auth.e2e.js diff --git a/integration/full/backlog.integrationSpec.js b/e2e/full/backlog.e2e.js similarity index 100% rename from integration/full/backlog.integrationSpec.js rename to e2e/full/backlog.e2e.js diff --git a/integration/full/home.integrationSpec.js b/e2e/full/home.e2e.js similarity index 100% rename from integration/full/home.integrationSpec.js rename to e2e/full/home.e2e.js diff --git a/integration/full/project-home.integrationSpec.js b/e2e/full/project-home.e2e.js similarity index 86% rename from integration/full/project-home.integrationSpec.js rename to e2e/full/project-home.e2e.js index b19cdf62..faf9e716 100644 --- a/integration/full/project-home.integrationSpec.js +++ b/e2e/full/project-home.e2e.js @@ -20,7 +20,7 @@ describe('project home', function() { }); it('timeline filled', function() { - return expect($$('div[tg-user-timeline-item]').count()).to.be.eventually.above(0); + expect($$('div[tg-user-timeline-item]').count()).to.be.eventually.above(0); }); it('timeline pagination', async function() { @@ -37,6 +37,6 @@ describe('project home', function() { }); it('team filled', function() { - return expect($$('ul.involved-team a').count()).to.be.eventually.above(0); + expect($$('ul.involved-team a').count()).to.be.eventually.above(0); }); }); diff --git a/integration/utils/common.js b/e2e/utils/common.js similarity index 100% rename from integration/utils/common.js rename to e2e/utils/common.js diff --git a/integration/utils/index.js b/e2e/utils/index.js similarity index 100% rename from integration/utils/index.js rename to e2e/utils/index.js diff --git a/integration/utils/lightbox.js b/e2e/utils/lightbox.js similarity index 100% rename from integration/utils/lightbox.js rename to e2e/utils/lightbox.js diff --git a/integration/utils/notifications.js b/e2e/utils/notifications.js similarity index 100% rename from integration/utils/notifications.js rename to e2e/utils/notifications.js From 6a9c4922ed995c5acdd3242286a4fc84eba652a5 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 25 Jun 2015 11:39:54 +0200 Subject: [PATCH 122/403] testing backlog --- conf.e2e.js | 4 +- e2e/full/backlog.e2e.js | 554 +++++++++++++++++++++++++++++++++- e2e/full/project-home.e2e.js | 8 +- e2e/helpers/backlog-helper.js | 160 ++++++++++ e2e/helpers/index.js | 1 + e2e/utils/common.js | 116 ++++++- e2e/utils/index.js | 1 + e2e/utils/lightbox.js | 58 ++-- e2e/utils/notifications.js | 6 +- e2e/utils/popover.js | 36 +++ package.json | 1 + 11 files changed, 909 insertions(+), 36 deletions(-) create mode 100644 e2e/helpers/backlog-helper.js create mode 100644 e2e/helpers/index.js create mode 100644 e2e/utils/popover.js diff --git a/conf.e2e.js b/conf.e2e.js index 27afdcb1..7a937d79 100644 --- a/conf.e2e.js +++ b/conf.e2e.js @@ -8,7 +8,7 @@ exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', framework: 'mocha', mochaOpts: { - timeout: 5000 + timeout: 11000 }, suites: { auth: 'e2e/auth/*.e2e.js', @@ -28,7 +28,7 @@ exports.config = { return browser.driver.wait(function() { return utils.common.closeCookies() .then(function() { - return browser.driver.getCurrentUrl() + return browser.driver.getCurrentUrl(); }) .then(function(url) { return url === 'http://localhost:9001/'; diff --git a/e2e/full/backlog.e2e.js b/e2e/full/backlog.e2e.js index 4ebdef1f..bde0c4b9 100644 --- a/e2e/full/backlog.e2e.js +++ b/e2e/full/backlog.e2e.js @@ -1,4 +1,5 @@ var utils = require('../utils'); +var backlogHelper = require('../helpers').backlog; var chai = require('chai'); var chaiAsPromised = require('chai-as-promised'); @@ -6,20 +7,557 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe.skip('backlog', function() { - before(function(){ - browser.get('http://localhost:9001/project/user7-project-example-0/'); +describe('backlog', function() { + before(async function() { + browser.get('http://localhost:9001/project/user7-project-example-0/backlog'); + await utils.common.waitLoader(); - return utils.common.waitLoader().then(function() { - return utils.common.takeScreenshot('backlog', 'backlog'); + utils.common.takeScreenshot('backlog', 'backlog'); + }); + + describe('create US', function() { + let createUSLightbox = null; + + before(async function() { + backlogHelper.openNewUs(); + + createUSLightbox = backlogHelper.getCreateEditUsLightbox(); + await createUSLightbox.waitOpen(); + }); + + it('capture screen', function() { + utils.common.takeScreenshot('backlog', 'create-us'); + }); + + it('fill form', async function() { + // subject + createUSLightbox.subject().sendKeys('subject'); + + // roles + createUSLightbox.setRole(1, 3); + createUSLightbox.setRole(3, 4); + + let totalPoints = await createUSLightbox.getRolePoints(); + + expect(totalPoints).to.be.equal('3'); + + // status + createUSLightbox.status(2).click(); + + // tags + createUSLightbox.tags().sendKeys('aaa'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createUSLightbox.tags().sendKeys('bbb'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + // description + createUSLightbox.description().sendKeys('test test'); + + //settings + createUSLightbox.settings(0).click(); + + + await utils.common.waitTransitionTime(createUSLightbox.settings(0)); + + utils.common.takeScreenshot('backlog', 'create-us-filled'); + }); + + it('send form', async function() { + let usCount = await backlogHelper.userStories().count(); + + createUSLightbox.submit(); + + await utils.lightbox.close(createUSLightbox.el); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.equal(usCount + 1); }); }); - it('create US', function() { - $('.new-us a').click(); + describe('bulk create US', function() { + let createUSLightbox = null; - lightbox.open('div[tg-lb-create-edit-userstory]').then(function() { + before(async function() { + backlogHelper.openBulk(); + createUSLightbox = backlogHelper.getBulkCreateLightbox(); + + await createUSLightbox.waitOpen(); }); + + it('fill form', function() { + createUSLightbox.textarea().sendKeys('aaa'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createUSLightbox.textarea().sendKeys('bbb'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + }); + + it('send form', async function() { + let usCount = await backlogHelper.userStories().count(); + + createUSLightbox.submit(); + + await createUSLightbox.waitClose(); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.equal(usCount + 2); + }); + }); + + describe('edit US', function() { + let editUSLightbox = null; + + before(async function() { + backlogHelper.openUsBacklogEdit(0); + + editUSLightbox = backlogHelper.getCreateEditUsLightbox(); + + await editUSLightbox.waitOpen(); + }); + + it('fill form', async function() { + // subject + editUSLightbox.subject().sendKeys('subjectedit'); + + // roles + editUSLightbox.setRole(1, 3); + editUSLightbox.setRole(2, 3); + editUSLightbox.setRole(3, 3); + editUSLightbox.setRole(4, 3); + + let totalPoints = await editUSLightbox.getRolePoints(); + + expect(totalPoints).to.be.equal('4'); + + // status + editUSLightbox.status(3).click(); + + // tags + editUSLightbox.tags().sendKeys('www'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + editUSLightbox.tags().sendKeys('xxx'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + // description + editUSLightbox.description().sendKeys('test test test test'); + + //settings + editUSLightbox.settings(1).click(); + }); + + it('send form', async function() { + editUSLightbox.submit(); + + await editUSLightbox.waitClose(); + }); + }); + + it('edit status inline', async function() { + await backlogHelper.setUsStatus(0, 1); + + // debounce + await browser.sleep(2000); + + let statusText = await backlogHelper.setUsStatus(0, 2); + + expect(statusText).to.be.equal('In progress'); + }); + + it('edit points inline', async function() { + await backlogHelper.setUsPoints(0, 1, 1); + + expect(utils.notifications.success.open()).to.be.eventually.true; + }); + + it('delete US', async function() { + let usCount = await backlogHelper.userStories().count(); + + backlogHelper.deleteUs(0); + + await utils.lightbox.confirm.ok(); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.equal(usCount - 1); + }); + + it('drag backlog us', async function() { + let dragableElements = backlogHelper.userStories(); + let dragElement = dragableElements.get(5); + + let draggedElementRef = await backlogHelper.getUsRef(dragElement); + + await utils.common.drag(dragElement, dragableElements.get(0)); + await browser.waitForAngular(); + + let firstElementTextRef = await backlogHelper.getUsRef(dragableElements.get(0)); + + expect(firstElementTextRef).to.be.equal(draggedElementRef); + }); + + it('reorder multiple us', async function() { + let dragableElements = backlogHelper.userStories(); + + let count = await dragableElements.count(); + + let draggedRefs = []; + + //element 1 + let dragElement = dragableElements.get(count - 1); + let dragElementHandler = dragElement.$('.icon-drag-v'); + dragElement.$('input[type="checkbox"]').click(); + draggedRefs.push(await backlogHelper.getUsRef(dragElement)); + + //element 2 + dragElement = dragableElements.get(count - 2); + dragElement.$('input[type="checkbox"]').click(); + draggedRefs.push(await backlogHelper.getUsRef(dragElement)); + + await utils.common.drag(dragElementHandler, dragableElements.get(0)); + await browser.waitForAngular(); + + let elementRef1 = await backlogHelper.getUsRef(dragableElements.get(0)); + let elementRef2 = await backlogHelper.getUsRef(dragableElements.get(1)); + + expect(elementRef2).to.be.equal(draggedRefs[0]); + expect(elementRef1).to.be.equal(draggedRefs[1]); + }); + + it('drag us to milestone', async function() { + let sprint = backlogHelper.sprints().get(1); + + let dragableElements = backlogHelper.userStories(); + let dragElement = dragableElements.get(0); + + let draggedElementRef = await backlogHelper.getUsRef(dragElement); + + await utils.common.drag(dragElement, sprint); + await browser.waitForAngular(); + + let firstElementSprint = await backlogHelper.getSprintUsertories(sprint).first(); + let firstElementSprintRef = await backlogHelper.getUsRef(firstElementSprint); + + expect(draggedElementRef).to.be.equal(firstElementSprintRef); + }); + + it('drag multiple us to milestone', async function() { + let sprint = backlogHelper.sprints().get(1); + + let dragableElements = backlogHelper.userStories(); + + let draggedRefs = []; + + //elefirment 1 + let dragElement = dragableElements.get(0); + dragElement.$('input[type="checkbox"]').click(); + draggedRefs.push(await backlogHelper.getUsRef(dragElement)); + + //element 2 + dragElement = dragableElements.get(1); + dragElement.$('input[type="checkbox"]').click(); + draggedRefs.push(await backlogHelper.getUsRef(dragElement)); + + await utils.common.drag(dragElement, sprint); + await browser.waitForAngular(); + + let elementSprint1 = await backlogHelper.getSprintUsertories(sprint).get(0); + let elementSprintRef1 = await backlogHelper.getUsRef(elementSprint1); + + let elementSprint2 = await backlogHelper.getSprintUsertories(sprint).get(1); + let elementSprintRef2 = await backlogHelper.getUsRef(elementSprint2); + + expect(elementSprintRef1).to.be.equal(draggedRefs[0]); + expect(elementSprintRef2).to.be.equal(draggedRefs[1]); + }); + + it('move to current sprint button', async function() { + let dragableElements = backlogHelper.userStories(); + let count = await dragableElements.count(); + let dragElement = dragableElements.get(count - 1); + + dragElement.$('input[type="checkbox"]').click(); + + let draggedRef = await backlogHelper.getUsRef(dragElement); + + $('#move-to-current-sprint').click(); + + let sprint = backlogHelper.sprintsOpen().last(); + + let sprintRefs = await backlogHelper.getSprintsRefs(sprint); + + expect(sprintRefs.indexOf(draggedRef)).to.be.not.equal(-1); + }); + + it('reorder milestone us', async function() { + let sprint = backlogHelper.sprints().get(0); + let dragableElements = backlogHelper.getSprintUsertories(sprint); + + let dragElement = await dragableElements.get(3); + let draggedElementRef = await backlogHelper.getUsRef(dragElement); + + await utils.common.drag(dragElement, dragableElements.get(0)); + await browser.waitForAngular(); + + let firstElementRef = await backlogHelper.getUsRef(dragableElements.get(0)); + + expect(firstElementRef).to.be.equal(firstElementRef); + }); + + it('drag us from milestone to milestone', async function() { + let sprint1 = backlogHelper.sprints().get(0); + let sprint2 = backlogHelper.sprints().get(1); + + let dragElement = backlogHelper.getSprintUsertories(sprint1).get(0); + let dragElementRef = await backlogHelper.getUsRef(dragElement); + + await utils.common.drag(dragElement, sprint2); + await browser.waitForAngular(); + + let firstElement = backlogHelper.getSprintUsertories(sprint2).get(0); + let firstElementRef = await backlogHelper.getUsRef(firstElement); + + expect(dragElementRef).to.be.equal(firstElementRef); + }); + + it('select us with SHIFT', async function() { + let dragableElements = backlogHelper.userStories(); + + let firstInput = dragableElements.get(0).$('input[type="checkbox"]'); + let lastInput = dragableElements.get(3).$('input[type="checkbox"]'); + + browser.actions() + .mouseMove(firstInput) + .keyDown(protractor.Key.SHIFT) + .click() + .mouseMove(lastInput) + .click() + .perform(); + + let count = await backlogHelper.selectedUserStories().count(); + + expect(count).to.be.equal(4); + }); + + describe('milestones', function() { + it('create', async function() { + $('.add-sprint').click(); + + let createMilestoneLightbox = backlogHelper.getCreateEditMilestone(); + + await createMilestoneLightbox.waitOpen(); + + utils.common.takeScreenshot('backlog', 'create-milestone'); + + let sprintName = 'sprintName' + new Date().getTime(); + + createMilestoneLightbox.name().sendKeys(sprintName); + + createMilestoneLightbox.submit(); + await browser.waitForAngular(); + + // debounce + await browser.sleep(2000); + + let sprintTitles = await backlogHelper.getSprintsTitles(); + + expect(sprintTitles.indexOf(sprintName)).to.be.not.equal(-1); + }); + + it('edit', async function() { + backlogHelper.openMilestoneEdit(0); + + let createMilestoneLightbox = backlogHelper.getCreateEditMilestone(); + + await createMilestoneLightbox.waitOpen(); + + let sprintName = 'sprintName' + new Date().getTime(); + + createMilestoneLightbox.name().sendKeys(sprintName); + + createMilestoneLightbox.submit(); + await browser.waitForAngular(); + + let sprintTitles = await backlogHelper.getSprintsTitles(); + + expect(sprintTitles.indexOf(sprintName)).to.be.not.equal(-1); + }); + + it('delete', async function() { + backlogHelper.openMilestoneEdit(0); + + let createMilestoneLightbox = backlogHelper.getCreateEditMilestone(); + + await createMilestoneLightbox.waitOpen(); + + createMilestoneLightbox.delete(); + + await utils.lightbox.confirm.ok(); + await browser.waitForAngular(); + + let sprintName = createMilestoneLightbox.name().getAttribute('value'); + let sprintTitles = await backlogHelper.getSprintsTitles(); + + expect(sprintTitles.indexOf(sprintName)).to.be.equal(-1); + }); + }); + + describe('tags', function() { + it('show', function() { + $('#show-tags').click(); + + utils.common.takeScreenshot('backlog', 'backlog-tags'); + + let tag = $$('.backlog-table .tag').get(0); + + expect(tag.isDisplayed()).to.be.eventually.true; + }); + + it('hide', function() { + $('#show-tags').click(); + + let tag = $$('.backlog-table .tag').get(0); + + expect(tag.isDisplayed()).to.be.eventually.false; + }); + }); + + describe('filters', function() { + it('show filters', async function() { + let transition = utils.common.transitionend('.menu-secondary.filters-bar', 'opacity'); + + $('#show-filters-button').click(); + + await transition(); + + utils.common.takeScreenshot('backlog', 'backlog-filters'); + }); + + it('filter by subject', async function() { + let usCount = await backlogHelper.userStories().count(); + let filterQ = element(by.model('filtersQ')); + + let htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + await filterQ.sendKeys('add'); + + await htmlChanges(); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.below(usCount); + + // clear status + await filterQ.clear(); + + htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + await htmlChanges(); + }); + + it('filter by ref', async function() { + let userstories = backlogHelper.userStories(); + let filterQ = element(by.model('filtersQ')); + let htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + let firstUs = userstories.first(); + let ref = await backlogHelper.getUsRef(firstUs); + + ref = ref.replace('#', ''); + + await filterQ.sendKeys(ref); + await htmlChanges(); + + let newUsCount = await userstories.count(); + + expect(newUsCount).to.be.equal(1); + + // clear status + await filterQ.clear(); + + htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + await htmlChanges(); + }); + + it('filter by status', async function() { + let usCount = await backlogHelper.userStories().count(); + + let htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + $$('.filters-cats a').first().click(); + $$('.filter-list a').first().click(); + + await htmlChanges(); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.below(usCount); + + //remove status + htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + $$('.filters-applied a').first().click(); + + await htmlChanges(); + + newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.equal(usCount); + }); + + it('filter by tags', async function() { + let usCount = await backlogHelper.userStories().count(); + + let htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + $$('.filters-cats a').get(1).click(); + $$('.filter-list a').first().click(); + + await htmlChanges(); + + let newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.below(usCount); + + //remove tags + htmlChanges = await utils.common.outerHtmlChanges('.backlog-table-body'); + + $$('.filters-applied a').first().click(); + + await htmlChanges(); + + newUsCount = await backlogHelper.userStories().count(); + + expect(newUsCount).to.be.equal(usCount); + }); + + it('trying drag with filters open', async function() { + let dragableElements = backlogHelper.userStories(); + let dragElement = dragableElements.get(5); + + await utils.common.drag(dragElement, dragableElements.get(0)); + + expect(utils.notifications.error.open()).to.be.eventually.true; + }); + + it('hide filters', async function() { + let menu = $('.menu-secondary.filters-bar'); + let transition = utils.common.transitionend('.menu-secondary.filters-bar', 'width'); + + $('#show-filters-button').click(); + + await transition(); + + expect(menu.getCssValue('width')).to.be.eventually.equal('0px'); + }); + }); + + describe.skip('closed sprints', function() { + // TODO }); }); diff --git a/e2e/full/project-home.e2e.js b/e2e/full/project-home.e2e.js index faf9e716..b95a9d35 100644 --- a/e2e/full/project-home.e2e.js +++ b/e2e/full/project-home.e2e.js @@ -7,10 +7,12 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('project home', function() { - before(async function(){ - browser.get('http://localhost:9001/'); - + beforeEach(async function() { + browser.get('http://localhost:9001/project/user7-project-example-1/'); await utils.common.waitLoader(); + }); + + it('screenshot', async function() { await utils.common.takeScreenshot("project", "home"); }); diff --git a/e2e/helpers/backlog-helper.js b/e2e/helpers/backlog-helper.js new file mode 100644 index 00000000..75f1873e --- /dev/null +++ b/e2e/helpers/backlog-helper.js @@ -0,0 +1,160 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.getCreateEditUsLightbox = function() { + let el = $('div[tg-lb-create-edit-userstory]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + waitClose: function() { + return utils.lightbox.close(el); + }, + roles: function() { + return el.$$('.points-per-role li'); + }, + subject: function() { + return el.$('input[name="subject"]'); + }, + tags: function() { + return el.$('.tag-input'); + }, + description: function() { + return el.$('textarea[name="description"]'); + }, + status: function(item) { + return el.$(`select option:nth-child(${item})`); + }, + settings: function(item) { + return el.$$('.settings label').get(item).click(); + }, + submit: function() { + el.$('button[type="submit"]').click(); + }, + setRole: function(roleItem, value) { + let role = obj.roles().get(roleItem); + + return utils.popover.open(role, value); + }, + getRolePoints: function() { + let role = obj.roles().get(0); + + return role.$('.points').getText(); + } + }; + + return obj; +}; + +helper.getBulkCreateLightbox = function() { + let el = $('div[tg-lb-create-bulk-userstories]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + textarea: function() { + return el.$('textarea'); + }, + submit: function() { + el.$('button[type="submit"]').click(); + }, + waitClose: function() { + return utils.lightbox.close(el); + } + }; + + return obj; +}; + +helper.getCreateEditMilestone = function() { + let el = $('div[tg-lb-create-edit-sprint]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + name: function() { + return el.element(by.model('sprint.name')); + }, + submit: function() { + el.$('button[type="submit"]').click(); + }, + delete: function() { + el.$('.delete-sprint .icon-delete').click(); + } + }; + + return obj; +}; + +helper.userStories = function() { + return $$('.backlog-table-body > div'); +}; + +helper.selectedUserStories = function() { + return $$('.backlog-table-body input[type="checkbox"]:checked'); +}; + +helper.sprints = function() { + return $$('div[tg-backlog-sprint="sprint"]'); +}; + +helper.sprintsOpen = function() { + return $$('div[tg-backlog-sprint="sprint"].sprint-open'); +}; + +helper.openBulk = function() { + $$('.new-us a').get(1).click(); +}; + +helper.openNewUs = function() { + $$('.new-us a').get(0).click(); +}; + +helper.openUsBacklogEdit = function(item) { + $$('.backlog-table-body .icon-edit').get(item).click(); +}; + +helper.openMilestoneEdit = function(item) { + $$('div[tg-backlog-sprint="sprint"] .icon-edit').get(item).click(); +}; + +helper.setUsStatus = async function(item, value) { + let status = $$('.backlog-table-body > div .us-status').get(item); + + await utils.popover.open(status, value); + + return status.$$('span').first().getText(); +}; + +helper.setUsPoints = function(item, value1, value2) { + let points = $$('.backlog-table-body > div .us-points').get(item); + + return utils.popover.open(points, value1, value2); +}; + +helper.deleteUs = function(item) { + $$('.backlog-table-body > div .icon-delete').get(item).click(); +}; + +helper.getUsRef = function(elm) { + return elm.$('span[tg-bo-ref]').getText(); +}; + +helper.getSprintUsertories = function(sprint) { + return sprint.$$('.milestone-us-item-row'); +}; + +helper.getSprintsRefs = function(sprint) { + return sprint.$$('span[tg-bo-ref]').getText(); +}; + +helper.getSprintsTitles = function() { + return $$('div[tg-backlog-sprint="sprint"] .sprint-name span').getText(); +}; diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js new file mode 100644 index 00000000..527db3e7 --- /dev/null +++ b/e2e/helpers/index.js @@ -0,0 +1 @@ +module.exports.backlog = require("./backlog-helper"); diff --git a/e2e/utils/common.js b/e2e/utils/common.js index 575aa450..aca15b79 100644 --- a/e2e/utils/common.js +++ b/e2e/utils/common.js @@ -1,6 +1,7 @@ var common = module.exports; var fs = require('fs'); +var uuid = require('node-uuid'); common.hasClass = async function (element, cls) { let classes = await element.getAttribute('class'); @@ -68,7 +69,7 @@ common.prepare = function() { common.dragEnd = function(elm) { return browser.wait(async function() { - let count = await element.all(by.css('.ui-sortable-helper')).count() + let count = await $$('.ui-sortable-helper').count(); return count === 0; }, 1000); @@ -83,3 +84,116 @@ common.drag = function(elm, location) { return common.dragEnd(); }) }; + +common.transitionend = function(selector, property) { + let script = ` + window.e2e = {}; + + var callback = arguments[1]; + var property = arguments[0]; + var sel = document.querySelector('${selector}'); + + var listener = function(event) { + var finish = function() { + window.e2e.transition = false; + sel.removeEventListener('transitionend', listener); + callback(); + }; + + if (property) { + if(event.propertyName === property) { + finish(); + } + } else { + finish(); + } + }; + + window.e2e.transition = true; + + sel.addEventListener('transitionend', listener); + `; + + browser.executeScript(script, property); + + return function() { + return browser.wait(async function() { + let ts = await browser.executeScript(function() { + return window.e2e.transition === false; + }); + + return ts; + }, 5000); + } +}; + +common.waitTransitionTime = async function(el) { + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + let transition = await el.getCssValue('transition'); + let time = parseFloat(transition.split(' ')[1].replace('s', '')) * 1000; + + return browser.sleep(time); +}; + +common.waitRequestAnimationFrame = function() { + let script = ` + var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; + + var callback = arguments[0]; + + requestAnimationFrame(callback); + `; + + return browser.executeAsyncScript(script); +}; + +common.outerHtmlChanges = async function(el='body') { + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + let html = await el.getOuterHtml(); + + return function() { + return browser.wait(async function() { + let newhtml = await el.getOuterHtml(); + + return html !== newhtml; + }, 5000).then(function() { + return common.waitRequestAnimationFrame(); + }); + }; +} + +common.innerHtmlChanges = async function(el='body') { + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + let html = await el.getInnerHtml(); + + return function() { + return browser.wait(async function() { + let newhtml = await el.getOuterHtml(); + + return html !== newhtml; + }, 5000).then(function() { + return common.waitRequestAnimationFrame(); + }); + }; +}; + +common.clear = function(elem, length) { + length = length || 100; + let backspaceSeries = ''; + + for (var i = 0; i < length; i++) { + backspaceSeries += protractor.Key.BACK_SPACE; + } + + return elem.sendKeys(backspaceSeries); +}; diff --git a/e2e/utils/index.js b/e2e/utils/index.js index 1e63c735..7a8ba243 100644 --- a/e2e/utils/index.js +++ b/e2e/utils/index.js @@ -1,3 +1,4 @@ module.exports.common = require("./common"); module.exports.notifications = require("./notifications"); module.exports.lightbox = require("./lightbox"); +module.exports.popover = require("./popover"); diff --git a/e2e/utils/lightbox.js b/e2e/utils/lightbox.js index df5d0e82..07e76234 100644 --- a/e2e/utils/lightbox.js +++ b/e2e/utils/lightbox.js @@ -6,9 +6,13 @@ var transition = 300; lightbox.open = async function(el) { var deferred = protractor.promise.defer(); + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + let open = await browser.wait(function() { - return common.hasClass($(el), 'open') - }, 2000); + return common.hasClass(el, 'open') + }, 4000); await browser.sleep(transition); @@ -21,25 +25,41 @@ lightbox.open = async function(el) { return deferred.promise; }; -lightbox.close = function(el) { +lightbox.close = async function(el) { var deferred = protractor.promise.defer(); + var present = true; - $(el).isPresent().then(function(present) { - if (!present) { - deferred.fulfill(true); - } else { - return browser.wait(function() { - return common.hasClass($(el), 'open').then(function(open) { - return !open; - }); - }, 2000) - .then(function() { - return deferred.fulfill(true); - }, function() { - deferred.reject(new Error('Lightbox doesn\'t close')); - }); - } - }) + if (typeof el == 'string' || el instanceof String) { + el = $(el); + } + + present = await el.isPresent(); + + if (!present) { + deferred.fulfill(true); + } else { + return browser.wait(function() { + return common.hasClass(el, 'open').then(function(open) { + return !open; + }); + }, 4000) + .then(function() { + return deferred.fulfill(true); + }, function() { + deferred.reject(new Error('Lightbox doesn\'t close')); + }); + } return deferred.promise; }; + +lightbox.confirm = {}; + +lightbox.confirm.ok = async function() { + let lb = $('.lightbox-generic-ask'); + await lightbox.open(lb); + + lb.$('.button-green').click(); + + await lightbox.close(lb); +}; diff --git a/e2e/utils/notifications.js b/e2e/utils/notifications.js index cd242b9b..75483bd6 100644 --- a/e2e/utils/notifications.js +++ b/e2e/utils/notifications.js @@ -10,7 +10,7 @@ notifications.success.open = function() { return browser .wait(function() { - return common.hasClass(el, 'active') + return common.hasClass(el, 'active'); }, 2000) .then(function(active) { return browser.sleep(transition).then(function() { @@ -25,7 +25,7 @@ notifications.error.open = function() { return browser .wait(function() { - return common.hasClass(el, 'active') + return common.hasClass(el, 'active'); }, 2000) .then(function(active) { return browser.sleep(transition).then(function() { @@ -40,7 +40,7 @@ notifications.errorLight.open = function() { return browser .wait(function() { - return common.hasClass(el, 'active') + return common.hasClass(el, 'active'); }, 2000) .then(function(active) { return browser.sleep(transition).then(function() { diff --git a/e2e/utils/popover.js b/e2e/utils/popover.js new file mode 100644 index 00000000..cd55f284 --- /dev/null +++ b/e2e/utils/popover.js @@ -0,0 +1,36 @@ +var common = require('./common') + +var popover = module.exports; + +var transition = 400; + +async function selectPopoverItem(popover, item) { + popover.$$('a').get(item).click(); + + await browser.sleep(transition); +} + +popover.wait = async function() { + await browser.wait(async function() { + return await $$('.popover.active').count() === 1; + }, 1000); + + return $('.popover.active'); +}; + +popover.open = async function(el, item, item2) { + el.click(); + + var pop = await popover.wait(); + + if (item) { + await selectPopoverItem(pop, item); + + if (item2) { + pop = await popover.wait(); + await selectPopoverItem(pop, item2); + } + } + + return pop; +}; diff --git a/package.json b/package.json index 5280d7b9..c1620063 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "karma-sourcemap-loader": "^0.3.4", "minimist": "^1.1.1", "mocha": "^2.2.4", + "node-uuid": "^1.4.3", "pre-commit": "^1.0.5", "readable-stream": "~1.0.33", "run-sequence": "^1.0.2", From 0e774a4fa39f5796b09f34e3c54d5f1be2f7cda6 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Tue, 21 Jul 2015 07:46:31 +0200 Subject: [PATCH 123/403] init taskboard tests --- e2e/full/taskboard.e2e.js | 61 +++++++++++++++++++++++++++++++++ e2e/helpers/index.js | 1 + e2e/helpers/taskboard-helper.js | 45 ++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 e2e/full/taskboard.e2e.js create mode 100644 e2e/helpers/taskboard-helper.js diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js new file mode 100644 index 00000000..4ef6559d --- /dev/null +++ b/e2e/full/taskboard.e2e.js @@ -0,0 +1,61 @@ +var utils = require('../utils'); +var backlogHelper = require('../helpers').backlog; +var taskboardHelper = require('../helpers').taskboard; + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe.only('taskboard', function() { + before(async function() { + browser.get('http://localhost:9001/project/user7-project-example-0/backlog'); + await utils.common.waitLoader(); + + let sprint = backlogHelper.sprints().get(0); + + sprint.$('.button-gray').click(); + + await utils.common.waitLoader(); + + utils.common.takeScreenshot('taskboard', 'taskboard'); + }); + + describe('create task', function() { + let createTaskLightbox = null; + let formFields = {}; + + before(async function() { + taskboardHelper.openNewTaskLb(0); + + createTaskLightbox = taskboardHelper.getCreateTask(); + + await createTaskLightbox.waitOpen(); + }); + + it('capture screen', function() { + utils.common.takeScreenshot('taskboard', 'create-task'); + }); + + it('fill form', async function() { + let date = Date.now(); + formFields.subject = 'test subject' + date; + formFields.description = 'test description' + date; + + createTaskLightbox.subject().sendKeys(formFields.subject); + createTaskLightbox.description().sendKeys(formFields.description); + }); + + it('send form', async function() { + createTaskLightbox.submit(); + + await utils.lightbox.close(createTaskLightbox.el); + + let task = taskboardHelper.getBoxTasks(0, 0).last(); + let taskSubject = task.$('.task-name').getText(); + + expect(taskSubject).to.be.eventually.equal(formFields.subject); + }); + }); +}); diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index 527db3e7..1cccb975 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -1 +1,2 @@ module.exports.backlog = require("./backlog-helper"); +module.exports.taskboard = require("./taskboard-helper"); diff --git a/e2e/helpers/taskboard-helper.js b/e2e/helpers/taskboard-helper.js new file mode 100644 index 00000000..02eed900 --- /dev/null +++ b/e2e/helpers/taskboard-helper.js @@ -0,0 +1,45 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.usertories = function() { + return $$('.task-row'); +}; + +helper.getBox = function(row, column) { + return $$('.task-row').get(row).$$('.taskboard-tasks-box').get(column); +}; + +helper.getBoxTasks = function(row, column) { + let box = helper.getBox(row, column); + + return box.$$('.taskboard-task'); +}; + +helper.openNewTaskLb = function(row) { + let us = helper.usertories().get(row); + + us.$('.icon-plus').click(); +}; + +helper.getCreateTask = function() { + let el = $('div[tg-lb-create-edit-task]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + subject: function() { + return el.element(by.model('task.subject')); + }, + description: function() { + return el.element(by.model('task.description')); + }, + submit: function() { + el.$('button[type="submit"]').click(); + } + }; + + return obj; +}; From 4448c59047aed47adbd7dc538f397bb8287c8dc8 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 22 Jul 2015 12:01:54 +0200 Subject: [PATCH 124/403] Adding team testing --- e2e/full/taskboard.e2e.js | 2 +- e2e/helpers/index.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 4ef6559d..595f7066 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -8,7 +8,7 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe.only('taskboard', function() { +describe('taskboard', function() { before(async function() { browser.get('http://localhost:9001/project/user7-project-example-0/backlog'); await utils.common.waitLoader(); diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index 1cccb975..0acefa66 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -1,2 +1,3 @@ module.exports.backlog = require("./backlog-helper"); module.exports.taskboard = require("./taskboard-helper"); +module.exports.team = require("./team-helper"); From 4ad1c4af07c45ac6b14029f8301e3670aa8da789 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 22 Jul 2015 12:44:47 +0200 Subject: [PATCH 125/403] Fixing tests with new project slugs --- e2e/full/backlog.e2e.js | 2 +- e2e/full/project-home.e2e.js | 2 +- e2e/full/taskboard.e2e.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/full/backlog.e2e.js b/e2e/full/backlog.e2e.js index bde0c4b9..90e5e32c 100644 --- a/e2e/full/backlog.e2e.js +++ b/e2e/full/backlog.e2e.js @@ -9,7 +9,7 @@ var expect = chai.expect; describe('backlog', function() { before(async function() { - browser.get('http://localhost:9001/project/user7-project-example-0/backlog'); + browser.get('http://localhost:9001/project/project-0/backlog'); await utils.common.waitLoader(); utils.common.takeScreenshot('backlog', 'backlog'); diff --git a/e2e/full/project-home.e2e.js b/e2e/full/project-home.e2e.js index b95a9d35..31b03717 100644 --- a/e2e/full/project-home.e2e.js +++ b/e2e/full/project-home.e2e.js @@ -8,7 +8,7 @@ var expect = chai.expect; describe('project home', function() { beforeEach(async function() { - browser.get('http://localhost:9001/project/user7-project-example-1/'); + browser.get('http://localhost:9001/project/project-1/'); await utils.common.waitLoader(); }); diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 595f7066..38e09603 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -10,7 +10,7 @@ var expect = chai.expect; describe('taskboard', function() { before(async function() { - browser.get('http://localhost:9001/project/user7-project-example-0/backlog'); + browser.get('http://localhost:9001/project/project-0/backlog'); await utils.common.waitLoader(); let sprint = backlogHelper.sprints().get(0); From ccf7f67a533c61a18fbbfa93ef03936a5ce2609a Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 23 Jul 2015 08:13:52 +0200 Subject: [PATCH 126/403] Adding team tests --- e2e/full/team.e2e.js | 57 ++++++++++++++++++++++++++++++++++++++ e2e/helpers/team-helper.js | 55 ++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 e2e/full/team.e2e.js create mode 100644 e2e/helpers/team-helper.js diff --git a/e2e/full/team.e2e.js b/e2e/full/team.e2e.js new file mode 100644 index 00000000..85b50f23 --- /dev/null +++ b/e2e/full/team.e2e.js @@ -0,0 +1,57 @@ +var utils = require('../utils'); +var teamHelper = require('../helpers').team; + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('leaving project', function(){ + before(async function(){ + browser.get('http://localhost:9001/project/project-4/team'); + await utils.common.waitLoader(); + }); + + it('leave project', async function(){ + teamHelper.team().leave(); + await utils.lightbox.confirm.ok(); + await utils.common.takeScreenshot("team", "after-leaving"); + }); +}) + +describe('team', function() { + before(async function(){ + browser.get('http://localhost:9001/project/project-5/team'); + await utils.common.waitLoader(); + }); + + it('screenshot', async function() { + await utils.common.takeScreenshot("team", "team"); + }); + + it('team filled', async function() { + let total = await teamHelper.team().count(); + expect(total).to.be.equal(10); + }); + + it('search username', async function() { + let firstMemberName = await teamHelper.team().firstMember().getText(); + teamHelper.filters().searchText(firstMemberName); + let total = await teamHelper.team().count(); + expect(total).to.be.equal(1); + await utils.common.takeScreenshot("team", "searching-by-name"); + }); + + it('filter role', async function(){ + teamHelper.filters().clearText(); + let total = await teamHelper.team().count(); + let firstRole = await teamHelper.team().firstRole(); + let roleName = await firstRole.getText(); + teamHelper.filters().filterByRole(roleName); + let newTotal = await teamHelper.team().count(); + expect(newTotal).to.be.below(total); + expect(newTotal).to.be.least(1); + await utils.common.takeScreenshot("team", "filtering-by-role"); + }); +}) diff --git a/e2e/helpers/team-helper.js b/e2e/helpers/team-helper.js new file mode 100644 index 00000000..3517cf7e --- /dev/null +++ b/e2e/helpers/team-helper.js @@ -0,0 +1,55 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.team = function() { + let el = $('.team'); + + let obj = { + el: el, + firstRole: function() { + return el.$$('section[tg-team-members] .avatar span').first(); + }, + + firstMember: function() { + return el.$$('section[tg-team-members] a.name').first(); + }, + + count: function() { + return el.$$('section[tg-team-members] .row.member').count(); + }, + + leave: function() { + el.$(".hero .username a").click(); + } + }; + + return obj; +}; + +helper.filters = function() { + let el = $('.team-filters-inner'); + + let obj = { + el: el, + filterByRole: function(roleName) { + let roles = el.$$("ul li a"); + roles.filter(function(role) { + return role.getText().then(function(text) { + return text.toLowerCase() === roleName.toLowerCase(); + }); + }).click(); + + }, + + clearText: function(text) { + el.$('input[ng-model="filtersQ"]').clear(); + }, + + searchText: function(text) { + el.$('input[ng-model="filtersQ"]').sendKeys(text); + } + }; + + return obj; +}; From 3b086087ae0412b74d6afe179f19ebe715cd0e50 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 23 Jul 2015 11:28:02 +0200 Subject: [PATCH 127/403] Adding wiki tests --- e2e/full/team.e2e.js | 4 +- e2e/full/wiki.e2e.js | 88 +++++++++++++++++++++++++++++++++++++ e2e/helpers/index.js | 1 + e2e/helpers/wiki-helper.js | 89 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 2 deletions(-) create mode 100644 e2e/full/wiki.e2e.js create mode 100644 e2e/helpers/wiki-helper.js diff --git a/e2e/full/team.e2e.js b/e2e/full/team.e2e.js index 85b50f23..2394f3d2 100644 --- a/e2e/full/team.e2e.js +++ b/e2e/full/team.e2e.js @@ -18,7 +18,7 @@ describe('leaving project', function(){ await utils.lightbox.confirm.ok(); await utils.common.takeScreenshot("team", "after-leaving"); }); -}) +}); describe('team', function() { before(async function(){ @@ -54,4 +54,4 @@ describe('team', function() { expect(newTotal).to.be.least(1); await utils.common.takeScreenshot("team", "filtering-by-role"); }); -}) +}); diff --git a/e2e/full/wiki.e2e.js b/e2e/full/wiki.e2e.js new file mode 100644 index 00000000..72f9d5ae --- /dev/null +++ b/e2e/full/wiki.e2e.js @@ -0,0 +1,88 @@ +var utils = require('../utils'); +var wikiHelper = require('../helpers').wiki; + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('wiki', function() { + before(async function(){ + browser.get('http://localhost:9001/project/project-0/wiki/home'); + await utils.common.waitLoader(); + }); + + it('screenshot', async function() { + await utils.common.takeScreenshot("wiki", "empty"); + }); + + it('add link, follow it, edit and remove everything', async function(){ + // creation + let timestamp = new Date().getTime(); + let linkText = "Test link" + timestamp; + let slug = "test-link" + timestamp; + let newLink = await wikiHelper.links().addLink(linkText); + + //Following + newLink.click(); + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/project/project-0/wiki/' + slug); + await utils.common.waitLoader(); + await utils.common.takeScreenshot("wiki", "new-link-created-with-empty-wiki-page"); + + //Removing link + wikiHelper.links().deleteLink(newLink); + await utils.common.takeScreenshot("wiki", "deleting-the-created-link"); + + // Edition + let timesEdited = wikiHelper.editor().getTimesEdited(); + let lastEditionDatetime = wikiHelper.editor().getLastEditionDateTime(); + wikiHelper.editor().enabledEditionMode(); + let settingText = "This is the new text" + new Date().getTime() + wikiHelper.editor().setText(settingText); + + // Checking preview + wikiHelper.editor().preview(); + await utils.common.takeScreenshot("wiki", "home-edition-preview"); + + // Saving + wikiHelper.editor().save(); + let newHtml = await wikiHelper.editor().getInnerHtml(); + let newTimesEdited = wikiHelper.editor().getTimesEdited(); + let newLastEditionDatetime = wikiHelper.editor().getLastEditionDateTime(); + expect(newHtml).to.be.equal("

" + settingText + "

"); + expect(newTimesEdited).to.be.eventually.equal(timesEdited+1); + expect(newLastEditionDatetime).to.be.not.equal(lastEditionDatetime); + await utils.common.takeScreenshot("wiki", "home-edition"); + + // Delete + await wikiHelper.editor().delete(); + expect(browser.getCurrentUrl()).to.be.eventually.equal('http://localhost:9001/project/project-0/wiki/home'); + }) + + it('Custom keyboard actions', async function(){ + wikiHelper.editor().enabledEditionMode(); + + wikiHelper.editor().setText("- aa"); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + let text = await wikiHelper.editor().getText(); + expect(text).to.be.equal("- aa\n- "); + + wikiHelper.editor().setText("- "); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + text = await wikiHelper.editor().getText(); + expect(text).to.be.equal("\n"); + + wikiHelper.editor().setText("- bbcc"); + browser.actions().sendKeys(protractor.Key.ARROW_LEFT).sendKeys(protractor.Key.ARROW_LEFT).sendKeys(protractor.Key.ENTER).perform(); + text = await wikiHelper.editor().getText(); + expect(text).to.be.equal("- bb\n- cc"); + + wikiHelper.editor().setText("- aa"); + browser.actions().sendKeys(protractor.Key.HOME).sendKeys(protractor.Key.ENTER).perform(); + text = await wikiHelper.editor().getText(); + expect(text).to.be.equal("\n- aa"); + }); + + //TODO attachments +}); diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index 0acefa66..02f9e949 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -1,3 +1,4 @@ module.exports.backlog = require("./backlog-helper"); module.exports.taskboard = require("./taskboard-helper"); module.exports.team = require("./team-helper"); +module.exports.wiki = require("./wiki-helper"); diff --git a/e2e/helpers/wiki-helper.js b/e2e/helpers/wiki-helper.js new file mode 100644 index 00000000..1824501e --- /dev/null +++ b/e2e/helpers/wiki-helper.js @@ -0,0 +1,89 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.links = function() { + let el = $('section[tg-wiki-nav]'); + + let obj = { + el: el, + + addLink: async function(pageTitle){ + el.$(".add-button").click(); + el.$(".new input").sendKeys(pageTitle); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + await browser.waitForAngular(); + let newLink = await el.$$(".wiki-link a").last(); + return newLink; + }, + + deleteLink: async function(link){ + link.$(".icon-delete").click(); + await utils.lightbox.confirm.ok(); + await browser.waitForAngular(); + } + + }; + + return obj; +}; + +helper.editor = function(){ + let el = $('.main.wiki'); + + let obj = { + el: el, + + enabledEditionMode: async function(){ + await el.$("section[tg-editable-wiki-content]").click(); + }, + + getTimesEdited: async function(){ + let total = await el.$(".wiki-times-edited .number").getText(); + return total; + }, + + getLastEditionDateTime: async function(){ + let date = await el.$(".wiki-last-modified .number").getText(); + return date; + }, + + getLastEditor: async function(){ + let editor = await el.$(".wiki-user-modification .username").getText(); + return editor; + }, + + getInnerHtml: async function(text){ + let wikiText = await el.$(".content").getInnerHtml(); + return wikiText; + }, + + getText: async function(text){ + let wikiText = await el.$("textarea").getAttribute('value'); + return wikiText; + }, + + setText: async function(text){ + await el.$("textarea").clear().sendKeys(text); + }, + + preview: async function(){ + await el.$(".preview-icon a").click(); + await browser.waitForAngular(); + }, + + save: async function(){ + await el.$(".save").click(); + await browser.waitForAngular(); + }, + + delete: async function(){ + await el.$('.remove').click(); + await utils.lightbox.confirm.ok(); + await browser.waitForAngular(); + } + + }; + + return obj; +}; From 6ff4bf69e1bf448934c84a457ab783a0a3d1cab9 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Wed, 22 Jul 2015 14:22:10 +0200 Subject: [PATCH 128/403] add taskboard-helpers --- e2e/full/taskboard.e2e.js | 106 ++++++++++++++++++++++++++++++++ e2e/helpers/taskboard-helper.js | 61 ++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 38e09603..6deabc43 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -42,9 +42,21 @@ describe('taskboard', function() { let date = Date.now(); formFields.subject = 'test subject' + date; formFields.description = 'test description' + date; + formFields.blockedNote = 'blocked note'; createTaskLightbox.subject().sendKeys(formFields.subject); createTaskLightbox.description().sendKeys(formFields.description); + + createTaskLightbox.tags().sendKeys('aaa'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createTaskLightbox.tags().sendKeys('bbb'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createTaskLightbox.blocked().click(); + createTaskLightbox.blockedNote().sendKeys(formFields.blockedNote); + + utils.common.takeScreenshot('taskboard', 'create-task-filled'); }); it('send form', async function() { @@ -58,4 +70,98 @@ describe('taskboard', function() { expect(taskSubject).to.be.eventually.equal(formFields.subject); }); }); + + describe('bulk create', function() { + let bulkCreateTaskLightbox; + + before(async function() { + taskboardHelper.openBulkTaskLb(0); + + bulkCreateTaskLightbox = taskboardHelper.getBulkCreateTask(); + + await bulkCreateTaskLightbox.waitOpen(); + }); + + it('fill form', function() { + bulkCreateTaskLightbox.textarea().sendKeys('aaa'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + bulkCreateTaskLightbox.textarea().sendKeys('bbb'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + }); + + it('send form', async function() { + let taskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + + bulkCreateTaskLightbox.submit(); + + await utils.lightbox.close(bulkCreateTaskLightbox.el); + + let newTaskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + + expect(newTaskCount).to.be.equal(taskCount + 2); + }); + }); + + describe('folds', function() { + it('fold row', async function() { + taskboardHelper.foldRow(0); + + utils.common.takeScreenshot('taskboard', 'fold-row'); + + let rowsFold = await $$('.row-fold').count(); + + expect(rowsFold).to.be.equal(1); + }); + + it('unfold row', async function() { + taskboardHelper.unFoldRow(0); + + let rowsFold = await $$('.row-fold').count(); + + expect(rowsFold).to.be.equal(0); + }); + + it('fold column', async function() { + taskboardHelper.foldColumn(0); + + utils.common.takeScreenshot('taskboard', 'fold-column'); + + let columnFold = await $$('.column-fold').count(); + + expect(columnFold).to.be.above(1); + }); + + it('unfold column', async function() { + taskboardHelper.unFoldColumn(0); + + let columnFold = await $$('.column-fold').count(); + + expect(columnFold).to.be.equal(0); + }); + + it('fold row and column', async function() { + taskboardHelper.foldRow(0); + taskboardHelper.foldColumn(0); + + utils.common.takeScreenshot('taskboard', 'fold-column-row'); + + let rowsFold = await $$('.row-fold').count(); + let columnFold = await $$('.column-fold').count(); + + expect(rowsFold).to.be.equal(1); + expect(columnFold).to.be.above(1); + }); + + it('unfold row and column', async function() { + taskboardHelper.unFoldRow(0); + taskboardHelper.unFoldColumn(0); + + let rowsFold = await $$('.row-fold').count(); + let columnFold = await $$('.column-fold').count(); + + expect(rowsFold).to.be.equal(0); + expect(columnFold).to.be.equal(0); + }); + }); }); diff --git a/e2e/helpers/taskboard-helper.js b/e2e/helpers/taskboard-helper.js index 02eed900..07fdb815 100644 --- a/e2e/helpers/taskboard-helper.js +++ b/e2e/helpers/taskboard-helper.js @@ -22,6 +22,36 @@ helper.openNewTaskLb = function(row) { us.$('.icon-plus').click(); }; +helper.openBulkTaskLb = function(row) { + let us = helper.usertories().get(row); + + us.$('.icon-bulk').click(); +}; + +helper.foldRow = function(row) { + let icon = $$('.icon-vfold.vfold').get(row); + + icon.click(); +}; + +helper.unFoldRow = function(row) { + let icon = $$('.icon-vunfold.vunfold').get(row); + + icon.click(); +}; + +helper.foldColumn = function(row) { + let icon = $$('.icon-vfold.hfold').get(row); + + icon.click(); +}; + +helper.unFoldColumn = function(row) { + let icon = $$('.icon-vunfold.hunfold').get(row); + + icon.click(); +}; + helper.getCreateTask = function() { let el = $('div[tg-lb-create-edit-task]'); @@ -36,6 +66,37 @@ helper.getCreateTask = function() { description: function() { return el.element(by.model('task.description')); }, + tags: function() { + return el.$('.tag-input'); + }, + iocaine: function() { + return el.$('.iocaine'); + }, + blocked: function() { + return el.$('.blocked'); + }, + blockedNote: function() { + return el.$('textarea[name="blocked_note"]'); + }, + submit: function() { + el.$('button[type="submit"]').click(); + } + }; + + return obj; +}; + +helper.getBulkCreateTask = function() { + let el = $('div[tg-lb-create-bulk-tasks]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + textarea: function() { + return el.element(by.model('form.data')); + }, submit: function() { el.$('button[type="submit"]').click(); } From 3ddd84d1b25cbd4fd984fac6941af4e6e49c3712 Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 23 Jul 2015 12:55:45 +0200 Subject: [PATCH 129/403] taskboard e2e tests --- e2e/full/taskboard.e2e.js | 127 ++++++++++++++++++++++++++++++-- e2e/helpers/taskboard-helper.js | 8 ++ 2 files changed, 128 insertions(+), 7 deletions(-) diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 6deabc43..ded536f3 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -8,14 +8,13 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe('taskboard', function() { +describe.only('taskboard', function() { before(async function() { browser.get('http://localhost:9001/project/project-0/backlog'); + await utils.common.waitLoader(); - let sprint = backlogHelper.sprints().get(0); - - sprint.$('.button-gray').click(); + backlogHelper.sprints().first().$('.button-gray').click(); await utils.common.waitLoader(); @@ -64,10 +63,56 @@ describe('taskboard', function() { await utils.lightbox.close(createTaskLightbox.el); - let task = taskboardHelper.getBoxTasks(0, 0).last(); - let taskSubject = task.$('.task-name').getText(); + let tasks = taskboardHelper.getBoxTasks(0, 0); - expect(taskSubject).to.be.eventually.equal(formFields.subject); + let tasksSubject = await $$('.task-name').getText(); + + let findSubject = tasksSubject.indexOf(formFields.subject) !== 1; + + expect(findSubject).to.be.true; + }); + }); + + describe('edit task', function() { + let createTaskLightbox = null; + let formFields = {}; + + before(async function() { + taskboardHelper.editTask(0, 0, 0); + + createTaskLightbox = taskboardHelper.getCreateTask(); + + await createTaskLightbox.waitOpen(); + }); + + it('capture screen', function() { + utils.common.takeScreenshot('taskboard', 'edit-task'); + }); + + it('fill form', async function() { + let date = Date.now(); + formFields.subject = 'test subject' + date; + formFields.description = 'test description' + date; + formFields.blockedNote = 'blocked note'; + + createTaskLightbox.subject().sendKeys(formFields.subject); + createTaskLightbox.description().sendKeys(formFields.description); + + utils.common.takeScreenshot('taskboard', 'edit-task-filled'); + }); + + it('send form', async function() { + createTaskLightbox.submit(); + + await utils.lightbox.close(createTaskLightbox.el); + + let tasks = taskboardHelper.getBoxTasks(0, 0); + + let tasksSubject = await $$('.task-name').getText(); + + let findSubject = tasksSubject.indexOf(formFields.subject) !== 1; + + expect(findSubject).to.be.true; }); }); @@ -164,4 +209,72 @@ describe('taskboard', function() { expect(columnFold).to.be.equal(0); }); }); + + describe('move tasks', function() { + it('move task between statuses', async function() { + let initOriginTaskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + let initDestinationTaskCount = await taskboardHelper.getBoxTasks(0, 1).count(); + + let taskOrigin = taskboardHelper.getBoxTasks(0, 0).first(); + let destination = taskboardHelper.getBox(0, 1); + + await utils.common.drag(taskOrigin, destination); + + browser.waitForAngular(); + + let originTaskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + let destinationTaskCount = await taskboardHelper.getBoxTasks(0, 1).count(); + + expect(originTaskCount).to.be.equal(initOriginTaskCount - 1); + expect(destinationTaskCount).to.be.equal(initDestinationTaskCount + 1); + }); + + // jquery ui drag bug + it.skip('move task between US\s', async function() { + let initOriginTaskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + let initDestinationTaskCount = await taskboardHelper.getBoxTasks(1, 1).count(); + + let taskOrigin = taskboardHelper.getBoxTasks(0, 0).first(); + let destination = taskboardHelper.getBox(1, 0); + + await utils.common.drag(taskOrigin, destination); + + browser.waitForAngular(); + + let originTaskCount = await taskboardHelper.getBoxTasks(0, 0).count(); + let destinationTaskCount = await taskboardHelper.getBoxTasks(1, 1).count(); + + expect(originTaskCount).to.be.equal(initOriginTaskCount - 1); + expect(destinationTaskCount).to.be.equal(initDestinationTaskCount + 1); + }); + }); + + + it.skip('Change task assigned to', function(){}); + + describe('Graph', function(){ + let graph = $('.graphics-container'); + + it('open', async function() { + taskboardHelper.toggleGraph(); + + await utils.common.waitTransitionTime(graph); + + utils.common.takeScreenshot('taskboard', 'grap-open'); + + let open = await utils.common.hasClass(graph, 'open'); + + expect(open).to.be.true; + }); + + it('close', async function() { + taskboardHelper.toggleGraph(); + + await utils.common.waitTransitionTime(graph); + + let open = await utils.common.hasClass(graph, 'open'); + + expect(open).to.be.false; + }); + }); }); diff --git a/e2e/helpers/taskboard-helper.js b/e2e/helpers/taskboard-helper.js index 07fdb815..5f033141 100644 --- a/e2e/helpers/taskboard-helper.js +++ b/e2e/helpers/taskboard-helper.js @@ -52,6 +52,14 @@ helper.unFoldColumn = function(row) { icon.click(); }; +helper.editTask = function(row, column, task) { + helper.getBoxTasks(row, column).get(task).$('.icon-edit').click(); +}; + +helper.toggleGraph = function() { + $('.large-summary svg').click(); +}; + helper.getCreateTask = function() { let el = $('div[tg-lb-create-edit-task]'); From 2ae506421d4d700216992abe4f6de591c1cd7a1c Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 23 Jul 2015 14:57:08 +0200 Subject: [PATCH 130/403] Adding assigned to details test --- e2e/full/issues/issue-detail.e2e.js | 24 ++++++++++ e2e/full/taskboard.e2e.js | 2 +- e2e/full/tasks/task-detail.e2e.js | 24 ++++++++++ .../user-stories/user-story-detail.e2e.js | 24 ++++++++++ e2e/helpers/detail-assigned-to-helper.js | 47 +++++++++++++++++++ e2e/helpers/index.js | 1 + e2e/utils/detail-assigned-to.js | 23 +++++++++ e2e/utils/index.js | 1 + 8 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 e2e/full/issues/issue-detail.e2e.js create mode 100644 e2e/full/tasks/task-detail.e2e.js create mode 100644 e2e/full/user-stories/user-story-detail.e2e.js create mode 100644 e2e/helpers/detail-assigned-to-helper.js create mode 100644 e2e/utils/detail-assigned-to.js diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js new file mode 100644 index 00000000..a2debbc5 --- /dev/null +++ b/e2e/full/issues/issue-detail.e2e.js @@ -0,0 +1,24 @@ +var utils = require('../../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('Issue detail', function(){ + before(async function(){ + browser.get('http://localhost:9001/project/project-2/issue/95'); + await utils.common.waitLoader(); + }); + + it('screenshot', async function() { + await utils.common.takeScreenshot("issues", "detail"); + }); + + it('assigned to', utils.detailAssignedTo.assignedToTesting); + + it('screenshot', async function() { + await utils.common.takeScreenshot("issues", "detail updated"); + }); +}) diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index ded536f3..48ff2077 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -8,7 +8,7 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe.only('taskboard', function() { +describe('taskboard', function() { before(async function() { browser.get('http://localhost:9001/project/project-0/backlog'); diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js new file mode 100644 index 00000000..1f8b5331 --- /dev/null +++ b/e2e/full/tasks/task-detail.e2e.js @@ -0,0 +1,24 @@ +var utils = require('../../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('Task detail', function(){ + before(async function(){ + browser.get('http://localhost:9001/project/project-2/task/4'); + await utils.common.waitLoader(); + }); + + it('screenshot', async function() { + await utils.common.takeScreenshot("tasks", "detail"); + }); + + it('assigned to', utils.detailAssignedTo.assignedToTesting); + + it('screenshot', async function() { + await utils.common.takeScreenshot("tasks", "detail updated"); + }); +}) diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js new file mode 100644 index 00000000..16bc5221 --- /dev/null +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -0,0 +1,24 @@ +var utils = require('../../utils'); + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('USer story detail', function(){ + before(async function(){ + browser.get('http://localhost:9001/project/project-2/us/65'); + await utils.common.waitLoader(); + }); + + it('screenshot', async function() { + await utils.common.takeScreenshot("user-stories", "detail"); + }); + + it('assigned to', utils.detailAssignedTo.assignedToTesting); + + it('screenshot', async function() { + await utils.common.takeScreenshot("user-stories", "detail updated"); + }); +}) diff --git a/e2e/helpers/detail-assigned-to-helper.js b/e2e/helpers/detail-assigned-to-helper.js new file mode 100644 index 00000000..bc44a8f6 --- /dev/null +++ b/e2e/helpers/detail-assigned-to-helper.js @@ -0,0 +1,47 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.assignedTo = function() { + let el = $('.assigned-to'); + + let obj = { + el: el, + clear: async function() { + el.$('.icon-delete').click(); + await utils.lightbox.confirm.ok(); + await browser.waitForAngular(); + }, + + assign: function() { + el.$('.user-assigned').click(); + }, + + getUserName: function() { + return el.$('.user-assigned').getText(); + } + + }; + + return obj; +}; + +helper.assignToLightbox = function() { + let el = $('div[tg-lb-assignedto]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + waitClose: function() { + return utils.lightbox.close(el); + }, + selectFirst: function() { + el.$$('div[data-user-id]').first().click(); + } + + }; + + return obj; +}; diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index 02f9e949..86b60939 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -2,3 +2,4 @@ module.exports.backlog = require("./backlog-helper"); module.exports.taskboard = require("./taskboard-helper"); module.exports.team = require("./team-helper"); module.exports.wiki = require("./wiki-helper"); +module.exports.detailAssignedTo = require("./detail-assigned-to-helper"); diff --git a/e2e/utils/detail-assigned-to.js b/e2e/utils/detail-assigned-to.js new file mode 100644 index 00000000..e5e4ec59 --- /dev/null +++ b/e2e/utils/detail-assigned-to.js @@ -0,0 +1,23 @@ +var detailAssignedToHelper = require('../helpers').detailAssignedTo; + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +var helper = module.exports; + +helper.assignedToTesting = async function() { + let assignedTo = detailAssignedToHelper.assignedTo(); + let assignToLightbox = detailAssignedToHelper.assignToLightbox(); + + let userName = detailAssignedToHelper.assignedTo().getUserName(); + await assignedTo.clear(); + assignedTo.assign(); + assignToLightbox.waitOpen(); + assignToLightbox.selectFirst(); + assignToLightbox.waitClose(); + let newUserName = assignedTo.getUserName(); + expect(newUserName).to.be.not.equal(userName); +} diff --git a/e2e/utils/index.js b/e2e/utils/index.js index 7a8ba243..75f490a0 100644 --- a/e2e/utils/index.js +++ b/e2e/utils/index.js @@ -2,3 +2,4 @@ module.exports.common = require("./common"); module.exports.notifications = require("./notifications"); module.exports.lightbox = require("./lightbox"); module.exports.popover = require("./popover"); +module.exports.detailAssignedTo = require("./detail-assigned-to"); From 2ed7ac62f409d0396b00009caf8930081d0ae2b7 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 24 Jul 2015 07:48:50 +0200 Subject: [PATCH 131/403] Refactoring detail common tests --- e2e/full/issues/issue-detail.e2e.js | 2 +- e2e/full/tasks/task-detail.e2e.js | 2 +- e2e/full/user-stories/user-story-detail.e2e.js | 2 +- .../{detail-assigned-to-helper.js => detail-helper.js} | 0 e2e/helpers/index.js | 2 +- e2e/utils/{detail-assigned-to.js => detail.js} | 8 ++++---- e2e/utils/index.js | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) rename e2e/helpers/{detail-assigned-to-helper.js => detail-helper.js} (100%) rename e2e/utils/{detail-assigned-to.js => detail.js} (63%) diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js index a2debbc5..626e4166 100644 --- a/e2e/full/issues/issue-detail.e2e.js +++ b/e2e/full/issues/issue-detail.e2e.js @@ -16,7 +16,7 @@ describe('Issue detail', function(){ await utils.common.takeScreenshot("issues", "detail"); }); - it('assigned to', utils.detailAssignedTo.assignedToTesting); + it('assigned to', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("issues", "detail updated"); diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js index 1f8b5331..d225aea0 100644 --- a/e2e/full/tasks/task-detail.e2e.js +++ b/e2e/full/tasks/task-detail.e2e.js @@ -16,7 +16,7 @@ describe('Task detail', function(){ await utils.common.takeScreenshot("tasks", "detail"); }); - it('assigned to', utils.detailAssignedTo.assignedToTesting); + it('assigned to', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("tasks", "detail updated"); diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js index 16bc5221..2e344a4b 100644 --- a/e2e/full/user-stories/user-story-detail.e2e.js +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -16,7 +16,7 @@ describe('USer story detail', function(){ await utils.common.takeScreenshot("user-stories", "detail"); }); - it('assigned to', utils.detailAssignedTo.assignedToTesting); + it('assigned to', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("user-stories", "detail updated"); diff --git a/e2e/helpers/detail-assigned-to-helper.js b/e2e/helpers/detail-helper.js similarity index 100% rename from e2e/helpers/detail-assigned-to-helper.js rename to e2e/helpers/detail-helper.js diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index 86b60939..dfdb1cfc 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -2,4 +2,4 @@ module.exports.backlog = require("./backlog-helper"); module.exports.taskboard = require("./taskboard-helper"); module.exports.team = require("./team-helper"); module.exports.wiki = require("./wiki-helper"); -module.exports.detailAssignedTo = require("./detail-assigned-to-helper"); +module.exports.detail = require("./detail-helper"); diff --git a/e2e/utils/detail-assigned-to.js b/e2e/utils/detail.js similarity index 63% rename from e2e/utils/detail-assigned-to.js rename to e2e/utils/detail.js index e5e4ec59..1ed058f6 100644 --- a/e2e/utils/detail-assigned-to.js +++ b/e2e/utils/detail.js @@ -1,4 +1,4 @@ -var detailAssignedToHelper = require('../helpers').detailAssignedTo; +var detailHelper = require('../helpers').detail; var chai = require('chai'); var chaiAsPromised = require('chai-as-promised'); @@ -9,10 +9,10 @@ var expect = chai.expect; var helper = module.exports; helper.assignedToTesting = async function() { - let assignedTo = detailAssignedToHelper.assignedTo(); - let assignToLightbox = detailAssignedToHelper.assignToLightbox(); + let assignedTo = detailHelper.assignedTo(); + let assignToLightbox = detailHelper.assignToLightbox(); - let userName = detailAssignedToHelper.assignedTo().getUserName(); + let userName = detailHelper.assignedTo().getUserName(); await assignedTo.clear(); assignedTo.assign(); assignToLightbox.waitOpen(); diff --git a/e2e/utils/index.js b/e2e/utils/index.js index 75f490a0..c2810a06 100644 --- a/e2e/utils/index.js +++ b/e2e/utils/index.js @@ -2,4 +2,4 @@ module.exports.common = require("./common"); module.exports.notifications = require("./notifications"); module.exports.lightbox = require("./lightbox"); module.exports.popover = require("./popover"); -module.exports.detailAssignedTo = require("./detail-assigned-to"); +module.exports.detail = require("./detail"); From eea81738fe1d714a355a86be68ca5754e17807f0 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 24 Jul 2015 09:28:41 +0200 Subject: [PATCH 132/403] Adding common detail testing for title, tags and description --- e2e/full/issues/issue-detail.e2e.js | 8 +- e2e/full/tasks/task-detail.e2e.js | 8 +- .../user-stories/user-story-detail.e2e.js | 8 +- e2e/helpers/detail-helper.js | 119 +++++++++++++++--- e2e/utils/detail.js | 33 +++++ 5 files changed, 157 insertions(+), 19 deletions(-) diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js index 626e4166..012d6670 100644 --- a/e2e/full/issues/issue-detail.e2e.js +++ b/e2e/full/issues/issue-detail.e2e.js @@ -16,7 +16,13 @@ describe('Issue detail', function(){ await utils.common.takeScreenshot("issues", "detail"); }); - it('assigned to', utils.detail.assignedToTesting); + it('title edition', utils.detail.titleTesting); + + it('tags edition', utils.detail.tagsTesting); + + it('description edition', utils.detail.descriptionTesting); + + it('assigned to edition', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("issues", "detail updated"); diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js index d225aea0..4afbde21 100644 --- a/e2e/full/tasks/task-detail.e2e.js +++ b/e2e/full/tasks/task-detail.e2e.js @@ -16,7 +16,13 @@ describe('Task detail', function(){ await utils.common.takeScreenshot("tasks", "detail"); }); - it('assigned to', utils.detail.assignedToTesting); + it('title edition', utils.detail.titleTesting); + + it('tags edition', utils.detail.tagsTesting); + + it('description edition', utils.detail.descriptionTesting); + + it('assigned to edition', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("tasks", "detail updated"); diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js index 2e344a4b..4002b12f 100644 --- a/e2e/full/user-stories/user-story-detail.e2e.js +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -16,7 +16,13 @@ describe('USer story detail', function(){ await utils.common.takeScreenshot("user-stories", "detail"); }); - it('assigned to', utils.detail.assignedToTesting); + it('title edition', utils.detail.titleTesting); + + it('tags edition', utils.detail.tagsTesting); + + it('description edition', utils.detail.descriptionTesting); + + it('assigned to edition', utils.detail.assignedToTesting); it('screenshot', async function() { await utils.common.takeScreenshot("user-stories", "detail updated"); diff --git a/e2e/helpers/detail-helper.js b/e2e/helpers/detail-helper.js index bc44a8f6..ee425d6a 100644 --- a/e2e/helpers/detail-helper.js +++ b/e2e/helpers/detail-helper.js @@ -2,28 +2,115 @@ var utils = require('../utils'); var helper = module.exports; +helper.title = function() { + let el = $('span[tg-editable-subject]'); + + let obj = { + el: el, + + getTitle: function() { + return el.$('.view-subject').getText(); + }, + + setTitle: function(title) { + el.$('.view-subject').click(); + el.$('.edit-subject input').clear().sendKeys(title); + } + }; + + return obj; +} + +helper.description = function(){ + let el = $('section[tg-editable-description]'); + + let obj = { + el: el, + + enabledEditionMode: async function(){ + await el.$(".view-description").click(); + }, + + getInnerHtml: async function(text){ + let html = await el.$(".wysiwyg.editable").getInnerHtml(); + return html; + }, + + setText: async function(text){ + await el.$("textarea").clear().sendKeys(text); + }, + + save: async function(){ + await el.$(".save").click(); + await browser.waitForAngular(); + } + }; + + return obj; +}; + + +helper.tags = function() { + let el = $('div[tg-tag-line]'); + + let obj = { + el:el, + + clearTags: async function() { + let tags = await el.$$('.icon-delete'); + let totalTags = tags.length + while (totalTags > 0) { + el.$$('.icon-delete').first().click(); + await browser.waitForAngular(); + totalTags --; + } + }, + + getTagsText: async function() { + let tags = await el.$$('.tag-name'); + let text = ""; + for (let tag of tags) { + let tagText = await tag.getText(); + text += tagText; + } + return text; + }, + + addTags: async function(tags) { + el.$('.add-tag').click(); + for (let tag of tags){ + el.$('.tag-input').sendKeys(tag); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + } + } + } + + return obj; +} + helper.assignedTo = function() { - let el = $('.assigned-to'); + let el = $('.assigned-to'); - let obj = { - el: el, - clear: async function() { - el.$('.icon-delete').click(); - await utils.lightbox.confirm.ok(); - await browser.waitForAngular(); - }, + let obj = { + el: el, - assign: function() { - el.$('.user-assigned').click(); - }, + clear: async function() { + el.$('.icon-delete').click(); + await utils.lightbox.confirm.ok(); + await browser.waitForAngular(); + }, - getUserName: function() { - return el.$('.user-assigned').getText(); - } + assign: function() { + el.$('.user-assigned').click(); + }, - }; + getUserName: function() { + return el.$('.user-assigned').getText(); + } - return obj; + }; + + return obj; }; helper.assignToLightbox = function() { diff --git a/e2e/utils/detail.js b/e2e/utils/detail.js index 1ed058f6..fba4c656 100644 --- a/e2e/utils/detail.js +++ b/e2e/utils/detail.js @@ -8,6 +8,39 @@ var expect = chai.expect; var helper = module.exports; +helper.titleTesting = async function() { + let titleHelper = detailHelper.title(); + let title = await titleHelper.getTitle(); + let date = Date.now() + titleHelper.setTitle("New title " + date); + let newTitle = await titleHelper.getTitle(); + expect(newTitle).to.be.not.equal(title); +} + +helper.tagsTesting = async function() { + let tagsHelper = detailHelper.tags(); + let tagsText = await tagsHelper.getTagsText(); + await tagsHelper.clearTags(); + let date = Date.now(); + let tags = [1, 2, 3, 4, 5].map(function(i){ return date + "-" + i}) + tagsHelper.addTags(tags); + await browser.waitForAngular(); + let newtagsText = await tagsHelper.getTagsText(); + expect(newtagsText).to.be.not.equal(tagsText); +} + +helper.descriptionTesting = async function() { + let descriptionHelper = detailHelper.description(); + let description = await descriptionHelper.getInnerHtml(); + let date = Date.now() + descriptionHelper.enabledEditionMode(); + descriptionHelper.setText("New description " + date) + descriptionHelper.save(); + let newDescription = await descriptionHelper.getInnerHtml(); + expect(newDescription).to.be.not.equal(description); +} + + helper.assignedToTesting = async function() { let assignedTo = detailHelper.assignedTo(); let assignToLightbox = detailHelper.assignToLightbox(); From e575f23d063fb97e0e3ebc89f3d2f1eea794e65f Mon Sep 17 00:00:00 2001 From: Juanfran Date: Thu, 23 Jul 2015 15:19:27 +0200 Subject: [PATCH 133/403] kanban e2e --- e2e/full/kanband.e2e.js | 275 +++++++++++++++++++++++++++++++++++ e2e/full/taskboard.e2e.js | 2 +- e2e/helpers/index.js | 1 + e2e/helpers/kanban-helper.js | 51 +++++++ 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 e2e/full/kanband.e2e.js create mode 100644 e2e/helpers/kanban-helper.js diff --git a/e2e/full/kanband.e2e.js b/e2e/full/kanband.e2e.js new file mode 100644 index 00000000..01e9d84d --- /dev/null +++ b/e2e/full/kanband.e2e.js @@ -0,0 +1,275 @@ +var utils = require('../utils'); +var kanbanHelper = require('../helpers').kanban; +var backlogHelper = require('../helpers').backlog; + +var chai = require('chai'); +var chaiAsPromised = require('chai-as-promised'); + +chai.use(chaiAsPromised); +var expect = chai.expect; + +describe('kanban', function() { + before(async function() { + browser.get('http://localhost:9001/project/project-0/kanban'); + + await utils.common.waitLoader(); + + utils.common.takeScreenshot('kanban', 'kanban'); + }); + + describe('create us', function() { + let createUSLightbox = null; + let formFields = {}; + + before(async function() { + kanbanHelper.openNewUsLb(0); + + createUSLightbox = backlogHelper.getCreateEditUsLightbox(); + + await createUSLightbox.waitOpen(); + }); + + it('capture screen', function() { + utils.common.takeScreenshot('kanban', 'create-us'); + }); + + it('fill form', async function() { + let date = Date.now(); + + formFields.subject = 'test subject' + date; + formFields.description = 'test description' + date; + + // subject + createUSLightbox.subject().sendKeys(formFields.subject); + + // roles + createUSLightbox.setRole(1, 3); + createUSLightbox.setRole(2, 3); + createUSLightbox.setRole(3, 3); + createUSLightbox.setRole(4, 3); + + let totalPoints = await createUSLightbox.getRolePoints(); + + expect(totalPoints).to.be.equal('4'); + + // tags + createUSLightbox.tags().sendKeys('www'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createUSLightbox.tags().sendKeys('xxx'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + // description + createUSLightbox.description().sendKeys(formFields.description); + + //settings + createUSLightbox.settings(1).click(); + }); + + it('send form', async function() { + createUSLightbox.submit(); + + await utils.lightbox.close(createUSLightbox.el); + + let ussTitles = await kanbanHelper.getColumnUssTitles(0); + + let findSubject = ussTitles.indexOf(formFields.subject) !== 1; + + expect(findSubject).to.be.true; + }); + }); + + + describe('edit us', function() { + let createUSLightbox = null; + let formFields = {}; + + before(async function() { + kanbanHelper.editUs(0, 0); + + createUSLightbox = backlogHelper.getCreateEditUsLightbox(); + + await createUSLightbox.waitOpen(); + }); + + it('capture screen', function() { + utils.common.takeScreenshot('kanban', 'edit-us'); + }); + + it('fill form', async function() { + let date = Date.now(); + + formFields.subject = 'test subject' + date; + formFields.description = 'test description' + date; + + // subject + let subject = createUSLightbox.subject(); + utils.common.clear(subject); + subject.sendKeys(formFields.subject); + + // roles + createUSLightbox.setRole(1, 3); + createUSLightbox.setRole(2, 3); + createUSLightbox.setRole(3, 3); + createUSLightbox.setRole(4, 3); + + let totalPoints = await createUSLightbox.getRolePoints(); + + expect(totalPoints).to.be.equal('4'); + + // tags + createUSLightbox.tags().sendKeys('www'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createUSLightbox.tags().sendKeys('xxx'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + // description + createUSLightbox.description().sendKeys(formFields.description); + + //settings + createUSLightbox.settings(1).click(); + }); + + it('send form', async function() { + createUSLightbox.submit(); + + await utils.lightbox.close(createUSLightbox.el); + + let ussTitles = await kanbanHelper.getColumnUssTitles(0); + + let findSubject = ussTitles.indexOf(formFields.subject) !== -1; + + expect(findSubject).to.be.true; + }); + }); + + describe('bulk create', function() { + let createUSLightbox; + + before(async function() { + kanbanHelper.openBulkUsLb(0); + + createUSLightbox = backlogHelper.getBulkCreateLightbox(); + + await createUSLightbox.waitOpen(); + }); + + it('fill form', function() { + createUSLightbox.textarea().sendKeys('aaa'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + + createUSLightbox.textarea().sendKeys('bbb'); + browser.actions().sendKeys(protractor.Key.ENTER).perform(); + }); + + it('send form', async function() { + let ussCount = await kanbanHelper.getBoxUss(0).count(); + + createUSLightbox.submit(); + + await utils.lightbox.close(createUSLightbox.el); + + let newUssCount = await kanbanHelper.getBoxUss(0).count(); + + expect(newUssCount).to.be.equal(ussCount + 2); + }); + }); + + describe('folds', function() { + it('fold column', async function() { + kanbanHelper.foldColumn(0); + + utils.common.takeScreenshot('kanban', 'fold-column'); + + let foldedColumns = await $$('.vfold.task-column').count(); + + expect(foldedColumns).to.be.equal(1); + }); + + it('unfold column', async function() { + kanbanHelper.unFoldColumn(0); + + let foldedColumns = await $$('.vfold.task-column').count(); + + expect(foldedColumns).to.be.equal(0); + }); + + it('fold cars', async function() { + kanbanHelper.foldCards(0); + + utils.common.takeScreenshot('kanban', 'fold-cards'); + + let minimized = await $$('.kanban-task-minimized').count(); + + expect(minimized).to.be.above(1); + }); + + it('unfold cars', async function() { + kanbanHelper.unFoldCards(0); + + let minimized = await $$('.kanban-task-minimized').count(); + + expect(minimized).to.be.equal(0); + }); + }); + + it('move us between columns', async function() { + let initOriginUsCount = await kanbanHelper.getBoxUss(0).count(); + let initDestinationUsCount = await kanbanHelper.getBoxUss(1).count(); + + let usOrigin = kanbanHelper.getBoxUss(0).first(); + let destination = kanbanHelper.getColumns().get(1); + + await utils.common.drag(usOrigin, destination); + + browser.waitForAngular(); + + let originUsCount = await kanbanHelper.getBoxUss(0).count(); + let destinationUsCount = await kanbanHelper.getBoxUss(1).count(); + + expect(originUsCount).to.be.equal(initOriginUsCount - 1); + expect(destinationUsCount).to.be.equal(initDestinationUsCount + 1); + }); + + describe('archive', function() { + it('move to archive', async function() { + let initOriginUsCount = await kanbanHelper.getBoxUss(3).count(); + + let usOrigin = kanbanHelper.getBoxUss(3).first(); + let destination = kanbanHelper.getColumns().last(); + + await kanbanHelper.scrollRight(); + + await utils.common.drag(usOrigin, destination); + + browser.waitForAngular(); + + let originUsCount = await kanbanHelper.getBoxUss(3).count(); + + utils.common.takeScreenshot('kanban', 'archive'); + + expect(originUsCount).to.be.equal(initOriginUsCount - 1); + }); + + it('show archive', async function() { + $('.icon-open-eye').click(); + + utils.common.takeScreenshot('kanban', 'archive-open'); + + let usCount = await kanbanHelper.getBoxUss(5).count(); + + expect(usCount).to.be.above(0); + }); + + it('close archive', async function() { + $('.icon-closed-eye').click(); + + let usCount = await kanbanHelper.getBoxUss(5).count(); + + expect(usCount).to.be.equal(0); + }); + }); + + it.skip('edit assigned to', function() {}); +}); diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 48ff2077..8cb9144a 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -67,7 +67,7 @@ describe('taskboard', function() { let tasksSubject = await $$('.task-name').getText(); - let findSubject = tasksSubject.indexOf(formFields.subject) !== 1; + let findSubject = tasksSubject.indexOf(formFields.subject) !== -1; expect(findSubject).to.be.true; }); diff --git a/e2e/helpers/index.js b/e2e/helpers/index.js index dfdb1cfc..f5c57163 100644 --- a/e2e/helpers/index.js +++ b/e2e/helpers/index.js @@ -1,5 +1,6 @@ module.exports.backlog = require("./backlog-helper"); module.exports.taskboard = require("./taskboard-helper"); +module.exports.kanban = require("./kanban-helper"); module.exports.team = require("./team-helper"); module.exports.wiki = require("./wiki-helper"); module.exports.detail = require("./detail-helper"); diff --git a/e2e/helpers/kanban-helper.js b/e2e/helpers/kanban-helper.js new file mode 100644 index 00000000..3033fa50 --- /dev/null +++ b/e2e/helpers/kanban-helper.js @@ -0,0 +1,51 @@ +var utils = require('../utils'); + +var helper = module.exports; + +helper.getHeaderColumns = function() { + return $$('.task-colum-name'); +}; + +helper.openNewUsLb = function(column) { + helper.getHeaderColumns().get(column).$('.icon-plus').click(); +}; + +helper.getColumns = function() { + return $$('.task-column'); +}; + +helper.getColumnUssTitles = function(column) { + return helper.getColumns().$$('.task-name').getText(); +}; + +helper.getBoxUss = function(column) { + return helper.getColumns().get(column).$$('.kanban-task'); +}; + +helper.editUs = function(column, us) { + helper.getColumns().get(column).$$('.icon-edit').get(us).click(); +}; + +helper.openBulkUsLb = function(column) { + $$('.icon-bulk').get(column).click(); +}; + +helper.foldColumn = function(column) { + $$('.hfold').get(column).click(); +}; + +helper.unFoldColumn = function(column) { + $$('.hunfold').get(column).click(); +}; + +helper.foldCards = function(column) { + $$('.icon-vfold').get(column).click(); +}; + +helper.unFoldCards = function(column) { + $$('.icon-vunfold').get(column).click(); +}; + +helper.scrollRight = function() { + return browser.executeScript('$(".kanban-table-body:last").scrollLeft(10000);'); +}; From 1f0b7d510efb6d65e96636ab4f80d09add1f5222 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 24 Jul 2015 10:52:27 +0200 Subject: [PATCH 134/403] Adding common utils for accessing first project, backlog, taskboard, task, issue and userstory --- e2e/full/issues/issue-detail.e2e.js | 17 ++++++-- e2e/full/tasks/task-detail.e2e.js | 16 +++++++- .../user-stories/user-story-detail.e2e.js | 17 ++++++-- e2e/helpers/detail-helper.js | 14 +++++++ e2e/utils/common.js | 41 +++++++++++++++++++ e2e/utils/detail.js | 6 ++- 6 files changed, 102 insertions(+), 9 deletions(-) diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js index 012d6670..b4ba4054 100644 --- a/e2e/full/issues/issue-detail.e2e.js +++ b/e2e/full/issues/issue-detail.e2e.js @@ -6,10 +6,14 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe('Issue detail', function(){ +describe('Issue detail', async function(){ + let issuesUrl = ""; before(async function(){ - browser.get('http://localhost:9001/project/project-2/issue/95'); - await utils.common.waitLoader(); + utils.common.goHome(); + utils.common.goToFirstProject(); + utils.common.goToIssues(); + issuesUrl = await browser.getCurrentUrl(); + utils.common.goToFirstIssue(); }); it('screenshot', async function() { @@ -27,4 +31,11 @@ describe('Issue detail', function(){ it('screenshot', async function() { await utils.common.takeScreenshot("issues", "detail updated"); }); + + it('delete', utils.detail.deleteTesting); + + it('redirected', async function (){ + let url = await browser.getCurrentUrl(); + expect(url.endsWith(issuesUrl)).to.be.true; + }); }) diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js index 4afbde21..7bcaeda3 100644 --- a/e2e/full/tasks/task-detail.e2e.js +++ b/e2e/full/tasks/task-detail.e2e.js @@ -7,9 +7,14 @@ chai.use(chaiAsPromised); var expect = chai.expect; describe('Task detail', function(){ + let sprintUrl = ""; before(async function(){ - browser.get('http://localhost:9001/project/project-2/task/4'); - await utils.common.waitLoader(); + utils.common.goHome(); + utils.common.goToFirstProject(); + utils.common.goToBacklog(); + utils.common.goToFirstSprint(); + sprintUrl = await browser.getCurrentUrl(); + utils.common.goToFirstTask(); }); it('screenshot', async function() { @@ -27,4 +32,11 @@ describe('Task detail', function(){ it('screenshot', async function() { await utils.common.takeScreenshot("tasks", "detail updated"); }); + + it('delete', utils.detail.deleteTesting); + + it('redirected', async function (){ + let url = await browser.getCurrentUrl(); + expect(url.endsWith(sprintUrl)).to.be.true; + }); }) diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js index 4002b12f..60c73e43 100644 --- a/e2e/full/user-stories/user-story-detail.e2e.js +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -6,10 +6,14 @@ var chaiAsPromised = require('chai-as-promised'); chai.use(chaiAsPromised); var expect = chai.expect; -describe('USer story detail', function(){ +describe('User story detail', function(){ + let backlogUrl = ""; before(async function(){ - browser.get('http://localhost:9001/project/project-2/us/65'); - await utils.common.waitLoader(); + utils.common.goHome(); + utils.common.goToFirstProject(); + utils.common.goToBacklog(); + backlogUrl = await browser.getCurrentUrl(); + utils.common.goToFirstUserStory(); }); it('screenshot', async function() { @@ -27,4 +31,11 @@ describe('USer story detail', function(){ it('screenshot', async function() { await utils.common.takeScreenshot("user-stories", "detail updated"); }); + + it('delete', utils.detail.deleteTesting); + + it('redirected', async function (){ + let url = await browser.getCurrentUrl(); + expect(url.endsWith(backlogUrl+"?no-milestone=1")).to.be.true; + }); }) diff --git a/e2e/helpers/detail-helper.js b/e2e/helpers/detail-helper.js index ee425d6a..0a54c31e 100644 --- a/e2e/helpers/detail-helper.js +++ b/e2e/helpers/detail-helper.js @@ -132,3 +132,17 @@ helper.assignToLightbox = function() { return obj; }; + +helper.delete = function() { + let el = $('tg-delete-button'); + + let obj = { + el:el, + delete: async function(){ + el.$('.button-red').click(); + await utils.lightbox.confirm.ok(); + } + } + + return obj; +} diff --git a/e2e/utils/common.js b/e2e/utils/common.js index aca15b79..838e1e24 100644 --- a/e2e/utils/common.js +++ b/e2e/utils/common.js @@ -197,3 +197,44 @@ common.clear = function(elem, length) { return elem.sendKeys(backspaceSeries); }; + +common.goHome = async function() { + browser.get('http://localhost:9001'); + await utils.common.waitLoader(); +}; + +common.goToFirstProject = async function() { + browser.actions().mouseMove($('div[tg-dropdown-project-list]')).perform(); + $$('div[tg-dropdown-project-list] li a').first().click(); + await utils.common.waitLoader(); +}; + +common.goToIssues = async function() { + $('#nav-issues').click(); + await utils.common.waitLoader(); +}; + +common.goToFirstIssue = async function() { + $$('section.issues-table .row.table-main .subject a').first().click(); + await utils.common.waitLoader(); +}; + +common.goToBacklog = async function() { + $('#nav-backlog').click(); + await utils.common.waitLoader(); +} + +common.goToFirstUserStory = async function() { + $$('.user-story-name>a').first().click(); + await utils.common.waitLoader(); +} + +common.goToFirstSprint = async function() { + $$('div[tg-backlog-sprint] a.button-gray').first().click(); + await utils.common.waitLoader(); +} + +common.goToFirstTask = async function() { + $$('div[tg-taskboard-task] a.task-name').first().click(); + await utils.common.waitLoader(); +} diff --git a/e2e/utils/detail.js b/e2e/utils/detail.js index fba4c656..bffe6775 100644 --- a/e2e/utils/detail.js +++ b/e2e/utils/detail.js @@ -44,7 +44,6 @@ helper.descriptionTesting = async function() { helper.assignedToTesting = async function() { let assignedTo = detailHelper.assignedTo(); let assignToLightbox = detailHelper.assignToLightbox(); - let userName = detailHelper.assignedTo().getUserName(); await assignedTo.clear(); assignedTo.assign(); @@ -54,3 +53,8 @@ helper.assignedToTesting = async function() { let newUserName = assignedTo.getUserName(); expect(newUserName).to.be.not.equal(userName); } + +helper.deleteTesting = async function() { + let deleteHelper = detailHelper.delete(); + await deleteHelper.delete(); +} From 4f01ceb2f23cebe999f89f0aca70946b753a2c2d Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 24 Jul 2015 12:45:35 +0200 Subject: [PATCH 135/403] Adding tests for history tabs --- e2e/full/issues/issue-detail.e2e.js | 3 + e2e/full/tasks/task-detail.e2e.js | 2 + .../user-stories/user-story-detail.e2e.js | 2 + e2e/helpers/detail-helper.js | 67 +++++++++++++++++++ e2e/utils/detail.js | 29 ++++++++ 5 files changed, 103 insertions(+) diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js index b4ba4054..1ddd2b5b 100644 --- a/e2e/full/issues/issue-detail.e2e.js +++ b/e2e/full/issues/issue-detail.e2e.js @@ -28,6 +28,8 @@ describe('Issue detail', async function(){ it('assigned to edition', utils.detail.assignedToTesting); + it('history', utils.detail.historyTesting); + it('screenshot', async function() { await utils.common.takeScreenshot("issues", "detail updated"); }); @@ -38,4 +40,5 @@ describe('Issue detail', async function(){ let url = await browser.getCurrentUrl(); expect(url.endsWith(issuesUrl)).to.be.true; }); + }) diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js index 7bcaeda3..5df24b11 100644 --- a/e2e/full/tasks/task-detail.e2e.js +++ b/e2e/full/tasks/task-detail.e2e.js @@ -29,6 +29,8 @@ describe('Task detail', function(){ it('assigned to edition', utils.detail.assignedToTesting); + it('history', utils.detail.historyTesting); + it('screenshot', async function() { await utils.common.takeScreenshot("tasks", "detail updated"); }); diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js index 60c73e43..b1ff45a6 100644 --- a/e2e/full/user-stories/user-story-detail.e2e.js +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -28,6 +28,8 @@ describe('User story detail', function(){ it('assigned to edition', utils.detail.assignedToTesting); + it('history', utils.detail.historyTesting); + it('screenshot', async function() { await utils.common.takeScreenshot("user-stories", "detail updated"); }); diff --git a/e2e/helpers/detail-helper.js b/e2e/helpers/detail-helper.js index 0a54c31e..c63b829d 100644 --- a/e2e/helpers/detail-helper.js +++ b/e2e/helpers/detail-helper.js @@ -133,6 +133,73 @@ helper.assignToLightbox = function() { return obj; }; +helper.history = function() { + let el = $('section.history'); + let obj = { + el:el, + + selectCommentsTab: function() { + el.$$('.history-tabs li a').first().click(); + }, + + selectActivityTab: function() { + el.$$('.history-tabs li a').last().click(); + }, + + addComment: async function(comment) { + el.$('textarea[tg-markitup]').sendKeys(comment); + el.$('input.save-comment').click(); + await browser.waitForAngular(); + }, + + countComments: async function() { + let moreComments = el.$('.comments-list .show-more-comments') + let moreCommentsIsPresent = await moreComments.isPresent(); + if (moreCommentsIsPresent){ + moreComments.click(); + } + await browser.waitForAngular(); + let comments = await el.$$(".activity-single.comment"); + return comments.length; + }, + + countActivities: async function() { + let moreActivities = el.$('.changes-list .show-more-comments') + let selectActivityTabIsPresent = await moreActivities.isPresent(); + if (selectActivityTabIsPresent){ + moreActivities.click(); + } + await browser.waitForAngular(); + let activities = await el.$$(".activity-single.activity"); + return activities.length; + }, + + countDeletedComments: async function() { + let moreComments = el.$('.comments-list .show-more-comments') + let moreCommentsIsPresent = await moreComments.isPresent(); + if (moreCommentsIsPresent){ + moreComments.click(); + } + await browser.waitForAngular(); + let comments = await el.$$(".activity-single.comment.deleted-comment"); + return comments.length; + }, + + deleteLastComment: async function() { + el.$$(".activity-single.comment .comment-delete").last().click(); + await browser.waitForAngular(); + }, + + restoreLastComment: async function() { + el.$$(".activity-single.comment.deleted-comment .comment-restore").last().click(); + await browser.waitForAngular(); + } + } + + return obj; + +} + helper.delete = function() { let el = $('tg-delete-button'); diff --git a/e2e/utils/detail.js b/e2e/utils/detail.js index bffe6775..8cc4e4fe 100644 --- a/e2e/utils/detail.js +++ b/e2e/utils/detail.js @@ -54,6 +54,35 @@ helper.assignedToTesting = async function() { expect(newUserName).to.be.not.equal(userName); } +helper.historyTesting = async function() { + let historyHelper = detailHelper.history(); + + //Adding a comment + historyHelper.selectCommentsTab(); + let commentsCounter = await historyHelper.countComments(); + let date = Date.now() + await historyHelper.addComment("New comment " + date); + let newCommentsCounter = await historyHelper.countComments(); + expect(newCommentsCounter).to.be.equal(commentsCounter+1); + + //Deleting last comment + let deletedCommentsCounter = await historyHelper.countDeletedComments(); + await historyHelper.deleteLastComment(); + let newDeletedCommentsCounter = await historyHelper.countDeletedComments(); + expect(newDeletedCommentsCounter).to.be.equal(deletedCommentsCounter+1); + + //Restore last coment + deletedCommentsCounter = await historyHelper.countDeletedComments(); + await historyHelper.restoreLastComment(); + newDeletedCommentsCounter = await historyHelper.countDeletedComments(); + expect(newDeletedCommentsCounter).to.be.equal(deletedCommentsCounter-1); + + //Check activity + historyHelper.selectActivityTab(); + let activitiesCounter = await historyHelper.countActivities(); + expect(activitiesCounter).to.be.least(newCommentsCounter); +} + helper.deleteTesting = async function() { let deleteHelper = detailHelper.delete(); await deleteHelper.delete(); From bc172f6d80d3985076ba45cf84c21a279d88e757 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 27 Jul 2015 09:12:17 +0200 Subject: [PATCH 136/403] Adding block testing --- e2e/full/issues/issue-detail.e2e.js | 3 +- e2e/full/tasks/task-detail.e2e.js | 4 +- .../user-stories/user-story-detail.e2e.js | 4 +- e2e/helpers/detail-helper.js | 41 +++++++++++++++++++ e2e/utils/detail.js | 14 +++++++ 5 files changed, 63 insertions(+), 3 deletions(-) diff --git a/e2e/full/issues/issue-detail.e2e.js b/e2e/full/issues/issue-detail.e2e.js index 1ddd2b5b..789c7125 100644 --- a/e2e/full/issues/issue-detail.e2e.js +++ b/e2e/full/issues/issue-detail.e2e.js @@ -34,11 +34,12 @@ describe('Issue detail', async function(){ await utils.common.takeScreenshot("issues", "detail updated"); }); + it('block', utils.detail.blockTesting); + it('delete', utils.detail.deleteTesting); it('redirected', async function (){ let url = await browser.getCurrentUrl(); expect(url.endsWith(issuesUrl)).to.be.true; }); - }) diff --git a/e2e/full/tasks/task-detail.e2e.js b/e2e/full/tasks/task-detail.e2e.js index 5df24b11..d5cde251 100644 --- a/e2e/full/tasks/task-detail.e2e.js +++ b/e2e/full/tasks/task-detail.e2e.js @@ -30,11 +30,13 @@ describe('Task detail', function(){ it('assigned to edition', utils.detail.assignedToTesting); it('history', utils.detail.historyTesting); - + it('screenshot', async function() { await utils.common.takeScreenshot("tasks", "detail updated"); }); + it('block', utils.detail.blockTesting); + it('delete', utils.detail.deleteTesting); it('redirected', async function (){ diff --git a/e2e/full/user-stories/user-story-detail.e2e.js b/e2e/full/user-stories/user-story-detail.e2e.js index b1ff45a6..95c4ec74 100644 --- a/e2e/full/user-stories/user-story-detail.e2e.js +++ b/e2e/full/user-stories/user-story-detail.e2e.js @@ -29,11 +29,13 @@ describe('User story detail', function(){ it('assigned to edition', utils.detail.assignedToTesting); it('history', utils.detail.historyTesting); - + it('screenshot', async function() { await utils.common.takeScreenshot("user-stories", "detail updated"); }); + it('block', utils.detail.blockTesting); + it('delete', utils.detail.deleteTesting); it('redirected', async function (){ diff --git a/e2e/helpers/detail-helper.js b/e2e/helpers/detail-helper.js index c63b829d..ec9b58cb 100644 --- a/e2e/helpers/detail-helper.js +++ b/e2e/helpers/detail-helper.js @@ -200,6 +200,47 @@ helper.history = function() { } +helper.block = function() { + let el = $('tg-block-button'); + + let obj = { + el:el, + block: function() { + el.$('.item-block').click(); + }, + + unblock: async function() { + el.$('.item-unblock').click(); + await browser.waitForAngular(); + } + } + + return obj; +} + +helper.blockLightbox = function() { + let el = $('div[tg-lb-block]'); + + let obj = { + el: el, + waitOpen: function() { + return utils.lightbox.open(el); + }, + waitClose: function() { + return utils.lightbox.close(el); + }, + fill: function(text) { + el.$('textarea').sendKeys(text); + }, + submit: async function() { + el.$('a.button-green').click(); + await browser.waitForAngular(); + } + }; + + return obj; +}; + helper.delete = function() { let el = $('tg-delete-button'); diff --git a/e2e/utils/detail.js b/e2e/utils/detail.js index 8cc4e4fe..727428e9 100644 --- a/e2e/utils/detail.js +++ b/e2e/utils/detail.js @@ -83,6 +83,20 @@ helper.historyTesting = async function() { expect(activitiesCounter).to.be.least(newCommentsCounter); } +helper.blockTesting = function() { + let blockHelper = detailHelper.block(); + let blockLightboxHelper = detailHelper.blockLightbox(); + blockHelper.block(); + blockLightboxHelper.waitOpen(); + blockLightboxHelper.fill('This is a testing block reason'); + blockLightboxHelper.submit(); + blockLightboxHelper.waitClose(); + expect($('.block-description').getText()).to.be.eventually.equal('This is a testing block reason'); + expect($('.block-description').isDisplayed()).to.be.eventually.true; + blockHelper.unblock(); + expect($('.block-description').isDisplayed()).to.be.eventually.false; +} + helper.deleteTesting = async function() { let deleteHelper = detailHelper.delete(); await deleteHelper.delete(); From 1d56fe6fdc4ce47afb7641c15fddf01cd393541a Mon Sep 17 00:00:00 2001 From: Juanfran Date: Mon, 27 Jul 2015 11:26:58 +0200 Subject: [PATCH 137/403] e2e screenshots gallery --- e2e/full/taskboard.e2e.js | 12 ++-- e2e/gallery/gallery-front.js | 106 ++++++++++++++++++++++++++++++++ e2e/gallery/gallery.css | 36 +++++++++++ e2e/gallery/gallery.jade | 52 ++++++++++++++++ e2e/gallery/index.js | 46 ++++++++++++++ e2e/helpers/taskboard-helper.js | 8 +++ e2e/utils/common.js | 5 +- package.json | 8 ++- 8 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 e2e/gallery/gallery-front.js create mode 100644 e2e/gallery/gallery.css create mode 100644 e2e/gallery/gallery.jade create mode 100644 e2e/gallery/index.js diff --git a/e2e/full/taskboard.e2e.js b/e2e/full/taskboard.e2e.js index 8cb9144a..5f5e8ce9 100644 --- a/e2e/full/taskboard.e2e.js +++ b/e2e/full/taskboard.e2e.js @@ -53,7 +53,7 @@ describe('taskboard', function() { browser.actions().sendKeys(protractor.Key.ENTER).perform(); createTaskLightbox.blocked().click(); - createTaskLightbox.blockedNote().sendKeys(formFields.blockedNote); + await createTaskLightbox.blockedNote().sendKeys(formFields.blockedNote); utils.common.takeScreenshot('taskboard', 'create-task-filled'); }); @@ -96,7 +96,7 @@ describe('taskboard', function() { formFields.blockedNote = 'blocked note'; createTaskLightbox.subject().sendKeys(formFields.subject); - createTaskLightbox.description().sendKeys(formFields.description); + await createTaskLightbox.description().sendKeys(formFields.description); utils.common.takeScreenshot('taskboard', 'edit-task-filled'); }); @@ -150,7 +150,7 @@ describe('taskboard', function() { describe('folds', function() { it('fold row', async function() { - taskboardHelper.foldRow(0); + await taskboardHelper.foldRow(0); utils.common.takeScreenshot('taskboard', 'fold-row'); @@ -168,7 +168,7 @@ describe('taskboard', function() { }); it('fold column', async function() { - taskboardHelper.foldColumn(0); + await taskboardHelper.foldColumn(0); utils.common.takeScreenshot('taskboard', 'fold-column'); @@ -186,8 +186,8 @@ describe('taskboard', function() { }); it('fold row and column', async function() { - taskboardHelper.foldRow(0); - taskboardHelper.foldColumn(0); + await taskboardHelper.foldRow(0); + await taskboardHelper.foldColumn(0); utils.common.takeScreenshot('taskboard', 'fold-column-row'); diff --git a/e2e/gallery/gallery-front.js b/e2e/gallery/gallery-front.js new file mode 100644 index 00000000..b36fbf9b --- /dev/null +++ b/e2e/gallery/gallery-front.js @@ -0,0 +1,106 @@ +var serverData; + +function alphabetical(a, b) { + var A = a.toLowerCase(); + var B = b.toLowerCase(); + + if (A < B){ + return -1; + }else if (A > B){ + return 1; + }else{ + return 0; + } +} + +$.get('get').then(function(data) { + serverData = data; + + printSections(serverData); +}); + +$('.browsers .browser').click(function() { + $(this).toggleClass('active'); +}); + +$('.browsers .search').click(function() { + var data = serverData; + + // filter by browser + var activeBrowsers = []; + + $('.browsers .active').each(function() { + activeBrowsers.push($(this).data('browser')); + }); + + data = data.filter(function(item) { + return activeBrowsers.indexOf(item.browser) !== -1; + }); + + // filter by section + var section = $('.browsers select').val(); + + if (section !== 'all') { + data = data.filter(function(item) { + return item.section === section; + }); + } + + if(!data.length) { + alert('no images found'); + return; + } + + data.sort(function(a, b) { + return alphabetical(a.title, b.title); + }); + + initGallery(data); +}); + +function printSections(images) { + var sections = []; + + var select = $('.browsers select'); + var options = []; + + var imagesSections = images.reduce(function(sections, image) { + if (sections.indexOf(image.section) === -1) { + sections.push(image.section); + } + + return sections; + }, []); + + imagesSections.forEach(function(section) { + var option = $('