diff --git a/app/assets/javascripts/custom-fields.js b/app/assets/javascripts/custom-fields.js
index 9cb07500c7..5c13acb2f4 100644
--- a/app/assets/javascripts/custom-fields.js
+++ b/app/assets/javascripts/custom-fields.js
@@ -44,7 +44,8 @@
possibleValues = $('#custom_field_possible_values_attributes'),
defaultValueFields = $('#custom_field_default_value_attributes'),
spanDefaultText = $('#default_value_text'),
- spanDefaultBool = $('#default_value_bool');
+ spanDefaultBool = $('#default_value_bool'),
+ textOrientationField = $('#custom_field_text_orientation');
var deactivate = function(element) {
element.hide().find('input, textarea').not('.destroy_flag,.-cf-ignore-disabled').attr('disabled', true);
@@ -65,7 +66,7 @@
unsearchable = function() { searchable.attr('checked', false).hide(); };
// defaults (reset these fields before doing anything else)
- $.each([spanDefaultBool, spanDefaultText, multiSelect], function(idx, element) {
+ $.each([spanDefaultBool, spanDefaultText, multiSelect, textOrientationField], function(idx, element) {
deactivate(element);
});
show(defaultValueFields);
@@ -107,6 +108,11 @@
hide(lengthField, regexpField, defaultValueFields);
unsearchable();
break;
+ case 'text':
+ show(lengthField, regexpField, searchable, textOrientationField);
+ deactivate(possibleValues);
+ activate(textOrientationField);
+ break;
default:
show(lengthField, regexpField, searchable);
deactivate(possibleValues);
diff --git a/app/assets/stylesheets/openproject/_generic.sass b/app/assets/stylesheets/openproject/_generic.sass
index 5582932d30..6ff3713a65 100644
--- a/app/assets/stylesheets/openproject/_generic.sass
+++ b/app/assets/stylesheets/openproject/_generic.sass
@@ -86,6 +86,10 @@
font-style: italic
.-small-font
font-size: 12px
+.-rtl
+ direction: rtl
+ .-placeholder &
+ direction: ltr
.drop-zone.-dragged-over
background-color: #eaeaea60
diff --git a/app/contracts/work_packages/base_contract.rb b/app/contracts/work_packages/base_contract.rb
index 7b1c5fc9df..75016b0958 100644
--- a/app/contracts/work_packages/base_contract.rb
+++ b/app/contracts/work_packages/base_contract.rb
@@ -103,7 +103,9 @@ module WorkPackages
message: :greater_than_or_equal_to_start_date,
allow_blank: true },
unless: Proc.new { |wp| wp.start_date.blank? }
+
validate :validate_enabled_type
+ validate :validate_type_exists
validate :validate_milestone_constraint
validate :validate_parent_not_milestone
@@ -112,13 +114,17 @@ module WorkPackages
validate :validate_parent_in_same_project
validate :validate_parent_not_subtask
+ validate :validate_status_exists
validate :validate_status_transition
validate :validate_active_priority
+ validate :validate_priority_exists
validate :validate_category
validate :validate_estimated_hours
+ validate :validate_assigned_to_exists
+
def initialize(work_package, user, options: {})
super
@@ -149,11 +155,19 @@ module WorkPackages
def validate_enabled_type
# Checks that the issue can not be added/moved to a disabled type
- if model.project && (model.type_id_changed? || model.project_id_changed?)
+ if type_context_changed?
errors.add :type_id, :inclusion unless model.project.types.include?(model.type)
end
end
+ def validate_assigned_to_exists
+ errors.add :assigned_to, :does_not_exist if model.assigned_to&.is_a?(User::InexistentUser)
+ end
+
+ def validate_type_exists
+ errors.add :type, :does_not_exist if type_inexistent?
+ end
+
def validate_milestone_constraint
if model.is_milestone? && model.due_date && model.start_date && model.start_date != model.due_date
errors.add :due_date, :not_start_date
@@ -186,6 +200,10 @@ module WorkPackages
end
end
+ def validate_status_exists
+ errors.add :status, :does_not_exist if model.status&.is_a?(Status::InexistentStatus)
+ end
+
def validate_status_transition
if status_changed? && status_exists? && !(model.type_id_changed? || status_transition_exists?)
errors.add :status_id, :status_transition_invalid
@@ -198,6 +216,10 @@ module WorkPackages
end
end
+ def validate_priority_exists
+ errors.add :priority, :does_not_exist if model.priority&.is_a?(Priority::InexistentPriority)
+ end
+
def validate_category
if inexistent_category?
errors.add :category, :does_not_exist
@@ -287,5 +309,13 @@ module WorkPackages
query
end
end
+
+ def type_context_changed?
+ model.project && !type_inexistent? && (model.type_id_changed? || model.project_id_changed?)
+ end
+
+ def type_inexistent?
+ model.type.is_a?(Type::InexistentType)
+ end
end
end
diff --git a/app/contracts/work_packages/create_contract.rb b/app/contracts/work_packages/create_contract.rb
index 2ac6bfa863..f191c54769 100644
--- a/app/contracts/work_packages/create_contract.rb
+++ b/app/contracts/work_packages/create_contract.rb
@@ -32,8 +32,6 @@ require 'work_packages/base_contract'
module WorkPackages
class CreateContract < BaseContract
- # TODO: Think about whether this can be removed
- # as it is unwriteable. So why bother checking for the correct author
attribute :author_id,
writeable: false do
errors.add :author_id, :invalid if model.author != user
diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb
index d32e6abb51..b25500f4dd 100644
--- a/app/models/permitted_params.rb
+++ b/app/models/permitted_params.rb
@@ -480,6 +480,7 @@ class PermittedParams
:default_value,
:possible_values,
:multi_value,
+ :content_right_to_left,
{ custom_options_attributes: %i(id value default_value position) },
type_ids: []
],
diff --git a/app/models/priority/inexistent_priority.rb b/app/models/priority/inexistent_priority.rb
new file mode 100644
index 0000000000..12a721167a
--- /dev/null
+++ b/app/models/priority/inexistent_priority.rb
@@ -0,0 +1,31 @@
+#-- encoding: UTF-8
+
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2017 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See docs/COPYRIGHT.rdoc for more details.
+#++
+
+class Priority::InexistentPriority < IssuePriority; end
diff --git a/app/models/status/inexistent_status.rb b/app/models/status/inexistent_status.rb
new file mode 100644
index 0000000000..a7cb10fa7f
--- /dev/null
+++ b/app/models/status/inexistent_status.rb
@@ -0,0 +1,31 @@
+#-- encoding: UTF-8
+
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2017 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See docs/COPYRIGHT.rdoc for more details.
+#++
+
+class Status::InexistentStatus < Status; end
diff --git a/app/models/type/inexistent_type.rb b/app/models/type/inexistent_type.rb
new file mode 100644
index 0000000000..2a0af5c851
--- /dev/null
+++ b/app/models/type/inexistent_type.rb
@@ -0,0 +1,32 @@
+#-- encoding: UTF-8
+
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2017 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See docs/COPYRIGHT.rdoc for more details.
+#++
+
+class Type::InexistentType < Type
+end
diff --git a/app/models/user/inexistent_user.rb b/app/models/user/inexistent_user.rb
new file mode 100644
index 0000000000..6fd662b8b5
--- /dev/null
+++ b/app/models/user/inexistent_user.rb
@@ -0,0 +1,31 @@
+#-- encoding: UTF-8
+
+#-- copyright
+# OpenProject is a project management system.
+# Copyright (C) 2012-2018 the OpenProject Foundation (OPF)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2017 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See docs/COPYRIGHT.rdoc for more details.
+#++
+
+class User::InexistentUser < User; end
diff --git a/app/services/work_packages/create_service.rb b/app/services/work_packages/create_service.rb
index c8e35756bc..ca4b695121 100644
--- a/app/services/work_packages/create_service.rb
+++ b/app/services/work_packages/create_service.rb
@@ -74,7 +74,7 @@ class WorkPackages::CreateService
end
def set_attributes(attributes, wp)
- WorkPackages::SetAttributesService
+ attributes_service_class
.new(user: user,
model: wp,
contract_class: contract_class)
@@ -96,4 +96,8 @@ class WorkPackages::CreateService
result
end
+
+ def attributes_service_class
+ ::WorkPackages::SetAttributesService
+ end
end
diff --git a/app/services/work_packages/set_attributes_service.rb b/app/services/work_packages/set_attributes_service.rb
index 2b9990cfa1..6a874320e7 100644
--- a/app/services/work_packages/set_attributes_service.rb
+++ b/app/services/work_packages/set_attributes_service.rb
@@ -177,7 +177,7 @@ class WorkPackages::SetAttributesService < ::BaseServices::SetAttributes
end
def reassign_status(available_statuses)
- return if available_statuses.include? work_package.status
+ return if available_statuses.include?(work_package.status) || work_package.status.is_a?(Status::InexistentStatus)
new_status = available_statuses.detect(&:is_default) || available_statuses.first
work_package.status = new_status if new_status.present?
diff --git a/app/views/custom_fields/_form.html.erb b/app/views/custom_fields/_form.html.erb
index fa2bf08d37..18f59d2afa 100644
--- a/app/views/custom_fields/_form.html.erb
+++ b/app/views/custom_fields/_form.html.erb
@@ -107,6 +107,7 @@ See docs/COPYRIGHT.rdoc for more details.
<%= f.check_box :is_for_all %>
<%= f.check_box :is_filter %>
<%= f.check_box :searchable %>
+ <%= f.check_box :content_right_to_left %>
<% when "UserCustomField" %>
<%= f.check_box :is_required %>
<%= f.check_box :visible %>
diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml
index 37dcccbc17..129411c09d 100644
--- a/config/locales/crowdin/cs.yml
+++ b/config/locales/crowdin/cs.yml
@@ -30,33 +30,33 @@ cs:
custom_styles:
custom_colors: "Vlastní barvy"
customize: "Přizpůsobte si svou OpenProject instalaci vlastním logem. Poznámka: Logo bude veřejně přístupné."
- enterprise_notice: "As a special 'Thank you!' for their financial contribution to develop OpenProject, this tiny feature is only available for Enterprise Edition support subscribers."
- manage_colors: "Edit color select options"
+ enterprise_notice: "Jako zvláštní 'Děkujeme!' za jejich finanční příspěvky na vývoj OpenProjektu, je tato malá funkce dostupná pouze pro podporu Enterprise Edition."
+ manage_colors: "Upravit možnosti výběru barvy"
instructions:
- alternative_color: "Strong accent color, typically used for most the important button on a screen."
+ alternative_color: "Silný odstín, obvykle používaný pro nejdůležitější tlačítko na obrazovce."
content_link_color: "Barva písma většiny odkazů."
primary_color: "Hlavní barva."
- primary_color_dark: "Typically a darker version of the main color used for hover effects."
+ primary_color_dark: "Obvykle tmavší verze hlavní barvy použité pro efekt vznášení."
header_bg_color: "Barva pozadí záhlaví."
header_item_bg_hover_color: "Barva pozadí klikacích položek záhlaví při najetí myší."
header_item_font_color: "Barva pozadí klikacích položek záhlaví."
- header_item_font_hover_color: "Font color of clickable header items when hovered with the mouse."
- header_border_bottom_color: "Thin line under the header. Leave this field empty if you don't want any line."
- main_menu_bg_color: "Left side menu's background color."
+ header_item_font_hover_color: "Barva pozadí klikacích položek záhlaví při najetí myší."
+ header_border_bottom_color: "Tenký řádek pod záhlavím. Ponechte toto pole prázdné, pokud nechcete žádný řádek."
+ main_menu_bg_color: "Barva pozadí levého menu."
enterprise:
- upgrade_to_ee: "Upgrade to Enterprise Edition"
- add_token: "Upload an Enterprise Edition support token"
- replace_token: "Replace your current support token"
- order: "Order Enterprise Edition"
- paste: "Paste your Enterprise Edition support token"
- required_for_feature: "This feature is only available with an active Enterprise Edition support token."
- enterprise_link: "For more information, click here."
+ upgrade_to_ee: "Upgradovat na Enterprise Edition"
+ add_token: "Nahrát podpůrný token Enterprise Edition"
+ replace_token: "Nahradit aktuální podpůrný token"
+ order: "Objednávka Enterprise edice"
+ paste: "Vložte svůj podpůrný token Enterprise Edition"
+ required_for_feature: "Tato funkce je dostupná pouze s aktivním podpůrným tokenem pro Enterprise Edition."
+ enterprise_link: "Pro více informací klikněte zde."
announcements:
show_until: Ukázat až do
is_active: aktuálně zobrazené
is_inactive: v současné době nejsou zobrazeny
attribute_help_texts:
- text_overview: 'In this view, you can create custom help texts for attributes view. When defined, these texts can be shown by clicking the help icon next to its belonging attribute.'
+ text_overview: 'V tomto zobrazení můžete vytvořit vlastní nápovědné texty pro zobrazení atributů. Pokud je definováno, mohou být tyto texty zobrazeny klepnutím na ikonu nápovědy vedle jejího atributu.'
label_plural: 'Texty nápovědy atributu'
show_preview: 'Náhled textu'
add_new: 'Přidat text nápovědy'
@@ -66,16 +66,16 @@ cs:
no_results_content_title: Nyní neexistují žádné ověřovací režimy.
no_results_content_text: Vytvořit nový režim ověřování
ldap_auth_sources:
- connection_encryption: 'Connection encryption'
+ connection_encryption: 'Šifrování připojení'
tls_mode:
plain: 'žádný'
- simple_tls: 'simple_tls'
- start_tls: 'start_tls'
- plain_description: "Plain unencrypted connection, no TLS negotiation."
- simple_tls_description: "Implicit TLS encryption, but no certificate validation. Use with caution and implicit trust of the LDAP connection."
- start_tls_description: "Explicit TLS encryption with full validation. Use for LDAP over TLS/SSL."
+ simple_tls: 'jednoduché_tls'
+ start_tls: 'začátek_tls'
+ plain_description: "Prosté nešifrované připojení, žádné jednání TLS."
+ simple_tls_description: "Implicitní TLS šifrování, ale bez ověření certifikátu. Používejte s opatrností a implicitní důvěru k LDAP připojení."
+ start_tls_description: "Explicitní TLS šifrování s úplnou validací. Použijte pro LDAP nad TLS/SSL."
section_more_info_link_html: >
- This section concerns the connection security of this LDAP authentication source. For more information, visit the Net::LDAP documentation.
+ Tato sekce se týká zabezpečení připojení tohoto LDAP autentifikačního zdroje. Pro více informací navštivte síť:LDAP dokumentaci.
forums:
show:
no_results_title_text: There are currently no posts for the forum.
@@ -89,7 +89,7 @@ cs:
name: 'Akce'
add: 'Přidat akci'
assigned_to:
- executing_user_value: '(Assign to executing user)'
+ executing_user_value: '(Přiřaďte k vykonání uživatele)'
conditions: 'Podmínky'
plural: 'Vlastní akce'
new: 'Nová vlastní akce'
@@ -100,11 +100,11 @@ cs:
description: 'Vlastní akce zjednodušuje každodenní práci tím, že kombinuje několik kroků do jednoho tlačítka.'
custom_fields:
text_add_new_custom_field: >
- To add new custom fields to a project you first need to create them before you can add them to this project.
+ Chcete-li přidat nová vlastní pole do projektu, musíte je nejprve vytvořit, než je budete moci přidat do tohoto projektu.
is_enabled_globally: 'Globálně povoleno'
enabled_in_project: 'Povoleno v projektu'
- contained_in_type: 'Contained in type'
- confirm_destroy_option: "Deleting an option will delete all of its occurrences (e.g. in work packages). Are you sure you want to delete it?"
+ contained_in_type: 'Obsahuje typ'
+ confirm_destroy_option: "Smazáním možnosti smažete všechny výskyty (např. v pracovních balíčcích). Opravdu ji chcete odstranit?"
tab:
no_results_title_text: V současné době nejsou žádná vlastní pole.
no_results_content_text: Vytvořit nové vlastní pole
@@ -1115,14 +1115,14 @@ cs:
community: "OpenProject komunita"
upsale:
become_hero: "Staň se hrdinou!"
- title: "Upgrade to Enterprise Edition"
+ title: "Upgradovat na Enterprise Edition"
description: "What are the benefits?"
more_info: "Více informací"
additional_features: "Additional powerful premium features"
professional_support: "Professional support from the OpenProject experts"
you_contribute: "Developers need to pay their bills, too. With Enterprise Edition you substantially contribute to this Open-Source community effort."
links:
- upgrade_enterprise_edition: "Upgrade to Enterprise Edition"
+ upgrade_enterprise_edition: "Upgradovat na Enterprise Edition"
postgres_migration: "Migrating your installation to PostgreSQL"
user_guides: "Uživatelské příručky"
faq: "FAQ - často kladené dotazy"
diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml
index 5f21d1df43..f97e781765 100644
--- a/config/locales/crowdin/fr.yml
+++ b/config/locales/crowdin/fr.yml
@@ -445,8 +445,8 @@ fr:
confirmation: "ne correspond pas à %{attribute}."
could_not_be_copied: "n'a pas pu être copié (entièrement)."
does_not_exist: "n'existe pas."
- error_unauthorized: "may not be accessed."
- error_readonly: "is not writable."
+ error_unauthorized: "est interdit d'accès."
+ error_readonly: "est en lecture seule."
empty: "ne peut pas être vide."
even: "doit être pair."
exclusion: "est réservé."
diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml
index 927f7e59aa..ce2912b308 100644
--- a/config/locales/crowdin/js-cs.yml
+++ b/config/locales/crowdin/js-cs.yml
@@ -43,7 +43,7 @@ cs:
button_close: "Zavřít"
button_change_project: "Change project"
button_check_all: "Zaškrtnout vše"
- button_configure-form: "Configure form"
+ button_configure-form: "Nastavení formuláře"
button_confirm: "Potvrdit"
button_continue: "Pokračovat"
button_copy: "Kopírovat"
@@ -54,13 +54,13 @@ cs:
button_duplicate: "Kopie"
button_edit: "Upravit"
button_filter: "Filtr"
- button_advanced_filter: "Advanced filter"
+ button_advanced_filter: "Pokročilý filtr"
button_list_view: "Zobrazit jako seznam"
button_show_view: "Celá obrazovka"
button_log_time: "Čas protokolu"
button_more: "Více"
- button_open_details: "Open details view"
- button_close_details: "Close details view"
+ button_open_details: "Otevřít zobrazení podrobností"
+ button_close_details: "Zavřít zobrazení podrobností"
button_open_fullscreen: "Otevřít celoobrazovkový pohled"
button_show_cards: "Show card view"
button_show_list: "Show list view"
@@ -106,16 +106,16 @@ cs:
description_selected_columns: "Vybrané sloupce"
description_subwork_package: "Potomek pracovního balíčku #%{id}"
editor:
- preview: 'Toggle preview mode'
- source_code: 'Toggle Markdown source mode'
- error_saving_failed: 'Saving the document failed with the following error: %{error}'
+ preview: 'Přepnout režim náhledu'
+ source_code: 'Přepnout zdrojový mód Markdown'
+ error_saving_failed: 'Uložení dokumentu se nezdařilo s následující chybou: %{error}'
error_initialization_failed: 'Nepodařilo se inicializovat CKEditor!'
mode:
manual: 'Přepněte do Markdown zdroje'
- wysiwyg: 'Switch to WYSIWYG editor'
+ wysiwyg: 'Přepnout na WYSIWYG Editor'
macro:
child_pages:
- button: 'Links to child pages'
+ button: 'Odkazy na podřízené stránky'
include_parent: 'Include parent'
text: '[Placeholder] Links to child pages of'
page: 'Stránka wiki'
@@ -419,7 +419,7 @@ cs:
reset_title: "Reset form configuration"
confirm_reset: >
Warning: Are you sure you want to reset the form configuration? This will reset the attributes to their default group and disable ALL custom fields.
- upgrade_to_ee: "Upgrade to Enterprise Edition"
+ upgrade_to_ee: "Upgradovat na Enterprise Edition"
upgrade_to_ee_text: "Wow! If you need this feature you are a super pro! Would you mind supporting us OpenSource developers by becoming an Enterprise Edition client?"
more_information: "Více informací"
nevermind: "Nevermind"
diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml
index 1bbee319a5..c6816e26cc 100644
--- a/config/locales/crowdin/tr.yml
+++ b/config/locales/crowdin/tr.yml
@@ -2576,7 +2576,7 @@ tr:
redirect_uri_html: >
İzin verilen URL'ler yetkili kullanıcılar adresine yönlendirilebilir. Her satıra bir giriş.
Bir masaüstü uygulamasına kaydoluyorsanız, aşağıdaki URL'yi kullanın.
confidential: "Uygulamanın, müşteri sırrının gizli tutulabileceği yerlerde kullanılıp kullanılmayacağını kontrol edin. Yerel mobil uygulamalar ve Tek Sayfa Uygulamaları gizli değildir."
- scopes: "Check the scopes you want the application to grant access to. If no scope is checked, api_v3 is assumed."
+ scopes: "Uygulamanın erişmesine izin vermek istediğiniz kapsamları kontrol edin. Kapsam işaretli değilse, api_v3 olduğu kabul edilir."
client_credential_user_id: "İstemciler bu uygulamayı kullandıklarında kimliğe bürünmek için isteğe bağlı kullanıcı kimliği. Yalnızca genel erişime izin vermek için boş bırakın"
register_intro: "OpenProject için bir OAuth API istemci uygulaması geliştiriyorsanız, tüm kullanıcıların kullanması için bu formu kullanarak kayıt olabilirsiniz."
default_scopes: ""
@@ -2591,8 +2591,8 @@ tr:
wants_to_access_html: >
Bu uygulama OpenProject hesabınıza erişim istiyor.
Aşağıdaki izinleri istedi:
scopes:
- api_v3: "Full API v3 access"
- api_v3_text: "Application will receive full read & write access to the OpenProject API v3 to perform actions on your behalf."
+ api_v3: "Tam API v3 erişimi"
+ api_v3_text: "Uygulama, sizin adınıza işlem yapmak için OpenProject API v3'e tam okuma ve yazma erişimi alacaktır."
grants:
created_date: "Tarihinde onaylandı"
scopes: "İzinler"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 4ea70c7863..12d6a8a1ef 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -497,7 +497,7 @@ en:
could_not_be_copied: "could not be (fully) copied."
does_not_exist: "does not exist."
error_unauthorized: "may not be accessed."
- error_readonly: "is not writable."
+ error_readonly: "was attempted to be written but is not writable."
empty: "can't be empty."
even: "must be even."
exclusion: "is reserved."
@@ -2652,7 +2652,6 @@ en:
estimated_hours: "Estimated hours cannot be set on parent work packages."
invalid_user_assigned_to_work_package: "The chosen user is not allowed to be '%{property}' for this work package."
start_date: "Start date cannot be set on parent work packages."
- writing_read_only_attributes: "You must not write a read-only attribute."
resources:
schema: 'Schema'
diff --git a/db/migrate/20191115141154_add_content_orientation_to_custom_fields.rb b/db/migrate/20191115141154_add_content_orientation_to_custom_fields.rb
new file mode 100644
index 0000000000..7fbfb7b5fd
--- /dev/null
+++ b/db/migrate/20191115141154_add_content_orientation_to_custom_fields.rb
@@ -0,0 +1,5 @@
+class AddContentOrientationToCustomFields < ActiveRecord::Migration[6.0]
+ def change
+ add_column :custom_fields, :content_right_to_left, :boolean, default: false
+ end
+end
diff --git a/frontend/src/app/components/wp-card-view/event-handler/click-handler.ts b/frontend/src/app/components/wp-card-view/event-handler/click-handler.ts
index c7825ddf14..c5e1a5cfc5 100644
--- a/frontend/src/app/components/wp-card-view/event-handler/click-handler.ts
+++ b/frontend/src/app/components/wp-card-view/event-handler/click-handler.ts
@@ -3,12 +3,15 @@ import {CardEventHandler} from "core-components/wp-card-view/event-handler/card-
import {WorkPackageCardViewComponent} from "core-components/wp-card-view/wp-card-view.component";
import {WorkPackageViewSelectionService} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-selection.service";
import {WorkPackageViewFocusService} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-focus.service";
-
import {WorkPackageCardViewService} from "core-components/wp-card-view/services/wp-card-view.service";
+import {StateService} from "@uirouter/core";
+import {DeviceService} from "core-app/modules/common/browser/device.service";
export class CardClickHandler implements CardEventHandler {
// Injections
+ public deviceService:DeviceService = this.injector.get(DeviceService);
+ public $state:StateService = this.injector.get(StateService);
public wpTableSelection:WorkPackageViewSelectionService = this.injector.get(WorkPackageViewSelectionService);
public wpTableFocus:WorkPackageViewFocusService = this.injector.get(WorkPackageViewFocusService);
public wpCardView:WorkPackageCardViewService = this.injector.get(WorkPackageCardViewService);
@@ -67,7 +70,15 @@ export class CardClickHandler implements CardEventHandler {
// not matter what other card are (de-)selected below.
// Thus save that card for the details view button.
this.wpTableFocus.updateFocus(wpId);
+
+ // open work package on mobile after first click
+ if (this.deviceService.isMobile) {
+ this.$state.go(
+ 'work-packages.show',
+ {workPackageId: wpId}
+ );
+ }
+
return false;
}
}
-
diff --git a/frontend/src/app/components/wp-card-view/wp-card-view.component.ts b/frontend/src/app/components/wp-card-view/wp-card-view.component.ts
index a49233eaa3..f5ab59471b 100644
--- a/frontend/src/app/components/wp-card-view/wp-card-view.component.ts
+++ b/frontend/src/app/components/wp-card-view/wp-card-view.component.ts
@@ -33,6 +33,7 @@ import {CardViewHandlerRegistry} from "core-components/wp-card-view/event-handle
import {WorkPackageCardViewService} from "core-components/wp-card-view/services/wp-card-view.service";
import {WorkPackageCardDragAndDropService} from "core-components/wp-card-view/services/wp-card-drag-and-drop.service";
import {WorkPackageNotificationService} from "core-app/modules/work_packages/notifications/work-package-notification.service";
+import {DeviceService} from "core-app/modules/common/browser/device.service";
export type CardViewOrientation = 'horizontal'|'vertical';
@@ -100,7 +101,8 @@ export class WorkPackageCardViewComponent implements OnInit, AfterViewInit {
readonly wpTableSelection:WorkPackageViewSelectionService,
readonly wpViewOrder:WorkPackageViewOrderService,
readonly cardView:WorkPackageCardViewService,
- readonly cardDragDrop:WorkPackageCardDragAndDropService) {
+ readonly cardDragDrop:WorkPackageCardDragAndDropService,
+ readonly deviceService:DeviceService) {
}
ngOnInit() {
@@ -140,9 +142,12 @@ export class WorkPackageCardViewComponent implements OnInit, AfterViewInit {
}
ngAfterViewInit() {
- // Register Drag & Drop
this.cardDragDrop.init(this);
- this.cardDragDrop.registerDragAndDrop();
+
+ // Register Drag & Drop only on desktop
+ if (!this.deviceService.isMobile) {
+ this.cardDragDrop.registerDragAndDrop();
+ }
// Register event handlers for the cards
new CardViewHandlerRegistry(this.injector).attachTo(this);
diff --git a/frontend/src/app/components/wp-card-view/wp-single-card/wp-single-card.component.html b/frontend/src/app/components/wp-card-view/wp-single-card/wp-single-card.component.html
index a68dc90346..202ffe10cb 100644
--- a/frontend/src/app/components/wp-card-view/wp-single-card/wp-single-card.component.html
+++ b/frontend/src/app/components/wp-card-view/wp-single-card/wp-single-card.component.html
@@ -5,7 +5,7 @@
[ngClass]="cardHighlightingClass(workPackage)">
-