diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 07c1674cb336..de098ef7b263 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -315,7 +315,7 @@ jobs: needs: [setup, build, merge] permissions: contents: none - if: ${{ github.repository == 'opf/openproject' && inputs.tag != '' }} + if: ${{ github.repository == 'opf/openproject' }} runs-on: ubuntu-latest steps: - name: Trigger Helm charts release diff --git a/.github/workflows/email-notification.yml b/.github/workflows/email-notification.yml index 9e9799ad1ff6..10f8a3cf0222 100644 --- a/.github/workflows/email-notification.yml +++ b/.github/workflows/email-notification.yml @@ -25,7 +25,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Send mail - uses: dawidd6/action-send-mail@v3 + uses: dawidd6/action-send-mail@v4 with: subject: ${{ inputs.subject }} body: ${{ inputs.body }} diff --git a/Gemfile b/Gemfile index 6b2200ffa589..f8e962882816 100644 --- a/Gemfile +++ b/Gemfile @@ -36,7 +36,7 @@ ruby File.read(File.expand_path(".ruby-version", __dir__)).strip gem "actionpack-xml_parser", "~> 2.0.0" gem "activemodel-serializers-xml", "~> 1.0.1" -gem "activerecord-import", "~> 1.7.0" +gem "activerecord-import", "~> 1.8.0" gem "activerecord-session_store", "~> 2.1.0" gem "ox" gem "rails", "~> 7.1.3" @@ -46,7 +46,7 @@ gem "ffi", "~> 1.15" gem "rdoc", ">= 2.4.2" -gem "doorkeeper", "~> 5.7.0" +gem "doorkeeper", "~> 5.8.0" # Maintain our own omniauth due to relative URL root issues # see upstream PR: https://github.com/omniauth/omniauth/pull/903 gem "omniauth", git: "https://github.com/opf/omniauth", ref: "fe862f986b2e846e291784d2caa3d90a658c67f0" @@ -61,7 +61,7 @@ gem "friendly_id", "~> 5.5.0" gem "acts_as_list", "~> 1.2.0" gem "acts_as_tree", "~> 2.9.0" -gem "awesome_nested_set", "~> 3.7.0" +gem "awesome_nested_set", "~> 3.8.0" gem "closure_tree", "~> 7.4.0" gem "rubytree", "~> 2.1.0" # Only used in down migrations now. @@ -93,7 +93,7 @@ gem "deckar01-task_list", "~> 2.3.1" # Requires escape-utils for faster escaping gem "escape_utils", "~> 1.3" # Syntax highlighting used in html-pipeline with rouge -gem "rouge", "~> 4.4.0" +gem "rouge", "~> 4.5.1" # HTML sanitization used for html-pipeline gem "sanitize", "~> 6.1.0" # HTML autolinking for mails and urls (replaces autolink) @@ -140,7 +140,7 @@ gem "rack-attack", "~> 6.7.0" gem "secure_headers", "~> 7.0.0" # Browser detection for incompatibility checks -gem "browser", "~> 6.0.0" +gem "browser", "~> 6.1.0" # Providing health checks gem "okcomputer", "~> 1.18.1" @@ -184,7 +184,7 @@ gem "rails-i18n", "~> 7.0.0" gem "sprockets", "~> 3.7.2" # lock sprockets below 4.0 gem "sprockets-rails", "~> 3.5.1" -gem "puma", "~> 6.4" +gem "puma", "~> 6.5" gem "puma-plugin-statsd", "~> 2.0" gem "rack-timeout", "~> 0.7.0", require: "rack/timeout/base" @@ -247,7 +247,7 @@ group :test do gem "rack_session_access" gem "rspec", "~> 3.13.0" # also add to development group, so 'spec' rake task gets loaded - gem "rspec-rails", "~> 7.0.0", group: :development + gem "rspec-rails", "~> 7.1.0", group: :development # Retry failures within the same environment gem "retriable", "~> 3.1.1" @@ -400,4 +400,4 @@ end gem "openproject-octicons", "~>19.19.0" gem "openproject-octicons_helper", "~>19.19.0" -gem "openproject-primer_view_components", "~>0.48.2" +gem "openproject-primer_view_components", "~>0.49.2" diff --git a/Gemfile.lock b/Gemfile.lock index a41d1fe15d76..f5bec99d3c56 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,6 @@ GIT remote: https://github.com/citizensadvice/capybara_accessible_selectors - revision: 347bbe06cb420416855e80bb4e3a3016b2d5872c + revision: aed2860e5b5df7f39284fdc35a5bf57bda7e1ad9 branch: main specs: capybara_accessible_selectors (0.11.0) @@ -206,7 +206,7 @@ PATH remote: modules/two_factor_authentication specs: openproject-two_factor_authentication (1.0.0) - aws-sdk-sns (~> 1.88.0) + aws-sdk-sns (~> 1.92.0) messagebird-rest (~> 1.4.2) rotp (~> 6.1) webauthn (~> 3.0) @@ -225,36 +225,36 @@ PATH GEM remote: https://rubygems.org/ specs: - Ascii85 (1.1.1) - actioncable (7.1.4.1) - actionpack (= 7.1.4.1) - activesupport (= 7.1.4.1) + Ascii85 (2.0.1) + actioncable (7.1.5) + actionpack (= 7.1.5) + activesupport (= 7.1.5) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.1.4.1) - actionpack (= 7.1.4.1) - activejob (= 7.1.4.1) - activerecord (= 7.1.4.1) - activestorage (= 7.1.4.1) - activesupport (= 7.1.4.1) + actionmailbox (7.1.5) + actionpack (= 7.1.5) + activejob (= 7.1.5) + activerecord (= 7.1.5) + activestorage (= 7.1.5) + activesupport (= 7.1.5) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.1.4.1) - actionpack (= 7.1.4.1) - actionview (= 7.1.4.1) - activejob (= 7.1.4.1) - activesupport (= 7.1.4.1) + actionmailer (7.1.5) + actionpack (= 7.1.5) + actionview (= 7.1.5) + activejob (= 7.1.5) + activesupport (= 7.1.5) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.2) - actionpack (7.1.4.1) - actionview (= 7.1.4.1) - activesupport (= 7.1.4.1) + actionpack (7.1.5) + actionview (= 7.1.5) + activesupport (= 7.1.5) nokogiri (>= 1.8.5) racc rack (>= 2.2.4) @@ -265,33 +265,33 @@ GEM actionpack-xml_parser (2.0.1) actionpack (>= 5.0) railties (>= 5.0) - actiontext (7.1.4.1) - actionpack (= 7.1.4.1) - activerecord (= 7.1.4.1) - activestorage (= 7.1.4.1) - activesupport (= 7.1.4.1) + actiontext (7.1.5) + actionpack (= 7.1.5) + activerecord (= 7.1.5) + activestorage (= 7.1.5) + activesupport (= 7.1.5) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.1.4.1) - activesupport (= 7.1.4.1) + actionview (7.1.5) + activesupport (= 7.1.5) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) - activejob (7.1.4.1) - activesupport (= 7.1.4.1) + activejob (7.1.5) + activesupport (= 7.1.5) globalid (>= 0.3.6) - activemodel (7.1.4.1) - activesupport (= 7.1.4.1) + activemodel (7.1.5) + activesupport (= 7.1.5) activemodel-serializers-xml (1.0.3) activemodel (>= 5.0.0.a) activesupport (>= 5.0.0.a) builder (~> 3.1) - activerecord (7.1.4.1) - activemodel (= 7.1.4.1) - activesupport (= 7.1.4.1) + activerecord (7.1.5) + activemodel (= 7.1.5) + activesupport (= 7.1.5) timeout (>= 0.4.0) - activerecord-import (1.7.0) + activerecord-import (1.8.1) activerecord (>= 4.2) activerecord-nulldb-adapter (1.0.1) activerecord (>= 5.2.0, < 7.2) @@ -302,23 +302,26 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 4) railties (>= 6.1) - activestorage (7.1.4.1) - actionpack (= 7.1.4.1) - activejob (= 7.1.4.1) - activerecord (= 7.1.4.1) - activesupport (= 7.1.4.1) + activestorage (7.1.5) + actionpack (= 7.1.5) + activejob (= 7.1.5) + activerecord (= 7.1.5) + activesupport (= 7.1.5) marcel (~> 1.0) - activesupport (7.1.4.1) + activesupport (7.1.5) base64 + benchmark (>= 0.3) bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) connection_pool (>= 2.2.5) drb i18n (>= 1.6, < 2) + logger (>= 1.4.2) minitest (>= 5.1) mutex_m + securerandom (>= 0.3) tzinfo (~> 2.0) - acts_as_list (1.2.3) + acts_as_list (1.2.4) activerecord (>= 6.1) activesupport (>= 6.1) acts_as_tree (2.9.1) @@ -338,34 +341,33 @@ GEM attr_required (1.0.2) auto_strip_attributes (2.6.0) activerecord (>= 4.0) - awesome_nested_set (3.7.0) - activerecord (>= 4.0.0, < 8.0) - awrence (1.2.1) + awesome_nested_set (3.8.0) + activerecord (>= 4.0.0, < 8.1) aws-eventstream (1.3.0) - aws-partitions (1.1001.0) - aws-sdk-core (3.211.0) + aws-partitions (1.1015.0) + aws-sdk-core (3.214.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.992.0) aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.95.0) + aws-sdk-kms (1.96.0) aws-sdk-core (~> 3, >= 3.210.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.170.0) + aws-sdk-s3 (1.175.0) aws-sdk-core (~> 3, >= 3.210.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sdk-sns (1.88.0) - aws-sdk-core (~> 3, >= 3.207.0) + aws-sdk-sns (1.92.0) + aws-sdk-core (~> 3, >= 3.210.0) aws-sigv4 (~> 1.5) aws-sigv4 (1.10.1) aws-eventstream (~> 1, >= 1.0.2) - axe-core-api (4.10.1) + axe-core-api (4.10.2) dumb_delegator ostruct virtus - axe-core-rspec (4.10.1) - axe-core-api (= 4.10.1) + axe-core-rspec (4.10.2) + axe-core-api (= 4.10.2) dumb_delegator ostruct virtus @@ -375,6 +377,7 @@ GEM thread_safe (~> 0.3, >= 0.3.1) base64 (0.2.0) bcrypt (3.1.20) + benchmark (0.4.0) better_html (2.1.1) actionview (>= 6.0) activesupport (>= 6.0) @@ -388,7 +391,7 @@ GEM msgpack (~> 1.2) brakeman (6.2.2) racc - browser (6.0.0) + browser (6.1.0) builder (3.3.0) byebug (11.1.3) capybara (3.40.0) @@ -446,7 +449,7 @@ GEM ferrum (~> 0.15.0) daemons (1.4.1) dalli (3.2.8) - date (3.3.4) + date (3.4.1) date_validator (0.12.0) activemodel (>= 3) activesupport (>= 3) @@ -462,7 +465,7 @@ GEM disposable (0.6.3) declarative (>= 0.0.9, < 1.0.0) representable (>= 3.1.1, < 4) - doorkeeper (5.7.1) + doorkeeper (5.8.0) railties (>= 5) dotenv (3.1.4) dotenv-rails (3.1.4) @@ -477,8 +480,9 @@ GEM zeitwerk (~> 2.6) dry-container (0.11.0) concurrent-ruby (~> 1.0) - dry-core (1.0.1) + dry-core (1.0.2) concurrent-ruby (~> 1.0) + logger zeitwerk (~> 2.6) dry-inflector (1.1.0) dry-initializer (3.1.1) @@ -541,20 +545,20 @@ GEM tzinfo eventmachine (1.2.7) eventmachine_httpserver (0.2.1) - excon (1.0.0) + excon (1.2.2) factory_bot (6.5.0) activesupport (>= 5.0.0) factory_bot_rails (6.4.4) factory_bot (~> 6.5) railties (>= 5.0.0) - faraday (2.12.0) - faraday-net_http (>= 2.0, < 3.4) + faraday (2.12.1) + faraday-net_http (>= 2.0, < 3.5) json logger faraday-follow_redirects (0.3.0) faraday (>= 1, < 3) - faraday-net_http (3.3.0) - net-http + faraday-net_http (3.4.0) + net-http (>= 0.5.0) fastimage (2.3.1) ferrum (0.15) addressable (~> 2.5) @@ -634,7 +638,7 @@ GEM rack gravatar_image_tag (1.2.0) hana (1.3.7) - hashdiff (1.1.1) + hashdiff (1.1.2) hashery (2.1.2) hashie (3.6.0) highline (3.1.1) @@ -645,10 +649,10 @@ GEM htmlbeautifier (1.4.3) htmldiff (0.0.1) htmlentities (4.3.4) - http-2 (1.0.1) + http-2 (1.0.2) http_parser.rb (0.6.0) httpclient (2.8.3) - httpx (1.3.1) + httpx (1.3.4) http-2 (>= 1.0.0) i18n (1.14.6) concurrent-ruby (~> 1.0) @@ -677,7 +681,7 @@ GEM reline (>= 0.4.2) iso8601 (0.13.0) jmespath (1.6.2) - json (2.7.4) + json (2.8.2) json-jwt (1.16.7) activesupport (>= 4.2) aes_key_wrap @@ -703,7 +707,7 @@ GEM launchy (3.0.1) addressable (~> 2.8) childprocess (~> 5.0) - lefthook (1.8.2) + lefthook (1.8.5) letter_opener (1.10.0) launchy (>= 2.2, < 4) letter_opener_web (3.0.0) @@ -718,13 +722,13 @@ GEM omniauth (~> 1.1) omniauth-openid-connect (>= 0.2.1) rails (>= 3.2.21) - logger (1.6.1) + logger (1.6.2) lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.22.0) + loofah (2.23.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) lookbook (2.3.4) @@ -754,21 +758,21 @@ GEM mime-types (3.6.0) logger mime-types-data (~> 3.2015) - mime-types-data (3.2024.1001) + mime-types-data (3.2024.1105) mini_magick (5.0.1) mini_mime (1.1.5) - mini_portile2 (2.8.7) - minitest (5.25.1) - msgpack (1.7.3) + mini_portile2 (2.8.8) + minitest (5.25.2) + msgpack (1.7.5) multi_json (1.15.0) mustermann (3.0.3) ruby2_keywords (~> 0.0.1) mustermann-grape (1.1.0) mustermann (>= 1.0.0) - mutex_m (0.2.0) - net-http (0.4.1) + mutex_m (0.3.0) + net-http (0.6.0) uri - net-imap (0.4.17) + net-imap (0.5.1) date net-protocol net-ldap (0.19.0) @@ -778,11 +782,11 @@ GEM timeout net-smtp (0.5.0) net-protocol - nio4r (2.7.3) - nokogiri (1.16.7) + nio4r (2.7.4) + nokogiri (1.16.8) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.6) + oj (3.16.7) bigdecimal (>= 3.0) ostruct (>= 0.2) okcomputer (1.18.5) @@ -808,7 +812,7 @@ GEM actionview openproject-octicons (= 19.19.0) railties - openproject-primer_view_components (0.48.2) + openproject-primer_view_components (0.49.2) actionview (>= 5.0.0) activesupport (>= 5.0.0) openproject-octicons (>= 19.17.0) @@ -818,9 +822,9 @@ GEM openssl (3.2.0) openssl-signature_algorithm (1.3.0) openssl (> 2.0) - optimist (3.1.0) + optimist (3.2.0) os (1.1.4) - ostruct (0.6.0) + ostruct (0.6.1) ox (2.14.18) paper_trail (15.2.0) activerecord (>= 6.1) @@ -828,14 +832,14 @@ GEM parallel (1.26.3) parallel_tests (4.7.2) parallel - parser (3.3.5.0) + parser (3.3.6.0) ast (~> 2.4.1) racc pdf-core (0.9.0) pdf-inspector (1.3.0) pdf-reader (>= 1.0, < 3.0.a) - pdf-reader (2.12.0) - Ascii85 (~> 1.0) + pdf-reader (2.13.0) + Ascii85 (>= 1.0, < 3.0, != 2.0.0) afm (~> 0.2.1) hashery (~> 2.0) ruby-rc4 @@ -864,7 +868,8 @@ GEM pry-rescue (1.6.0) interception (>= 0.5) pry (>= 0.12.0) - psych (5.1.2) + psych (5.2.1) + date stringio public_suffix (6.0.1) puffing-billy (4.0.0) @@ -875,7 +880,7 @@ GEM eventmachine_httpserver http_parser.rb (~> 0.6.0) multi_json - puma (6.4.3) + puma (6.5.0) nio4r (~> 2.0) puma-plugin-statsd (2.6.0) puma (>= 5.0, < 7) @@ -906,23 +911,23 @@ GEM rack_session_access (0.2.0) builder (>= 2.0.0) rack (>= 1.0.0) - rackup (1.0.0) + rackup (1.0.1) rack (< 3) webrick - rails (7.1.4.1) - actioncable (= 7.1.4.1) - actionmailbox (= 7.1.4.1) - actionmailer (= 7.1.4.1) - actionpack (= 7.1.4.1) - actiontext (= 7.1.4.1) - actionview (= 7.1.4.1) - activejob (= 7.1.4.1) - activemodel (= 7.1.4.1) - activerecord (= 7.1.4.1) - activestorage (= 7.1.4.1) - activesupport (= 7.1.4.1) + rails (7.1.5) + actioncable (= 7.1.5) + actionmailbox (= 7.1.5) + actionmailer (= 7.1.5) + actionpack (= 7.1.5) + actiontext (= 7.1.5) + actionview (= 7.1.5) + activejob (= 7.1.5) + activemodel (= 7.1.5) + activerecord (= 7.1.5) + activestorage (= 7.1.5) + activesupport (= 7.1.5) bundler (>= 1.15.0) - railties (= 7.1.4.1) + railties (= 7.1.5) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -931,15 +936,15 @@ GEM activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.6.0) + rails-html-sanitizer (1.6.1) loofah (~> 2.21) - nokogiri (~> 1.14) - rails-i18n (7.0.9) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + rails-i18n (7.0.10) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 8) - railties (7.1.4.1) - actionpack (= 7.1.4.1) - activesupport (= 7.1.4.1) + railties (7.1.5) + actionpack (= 7.1.5) + activesupport (= 7.1.5) irb rackup (>= 1.0.0) rake (>= 12.2) @@ -950,22 +955,22 @@ GEM rb-fsevent (0.11.2) rb-inotify (0.11.1) ffi (~> 1.0) - rb_sys (0.9.102) + rb_sys (0.9.103) rbtrace (0.5.1) ffi (>= 1.0.6) msgpack (>= 0.4.3) optimist (>= 3.0.0) rbtree3 (0.7.1) - rdoc (6.7.0) + rdoc (6.8.1) psych (>= 4.0.0) - recaptcha (5.17.0) + recaptcha (5.17.1) redcarpet (3.6.0) redis (5.3.0) redis-client (>= 0.22.0) redis-client (0.22.2) connection_pool - regexp_parser (2.9.2) - reline (0.5.10) + regexp_parser (2.9.3) + reline (0.5.12) io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) @@ -982,7 +987,7 @@ GEM roar (1.2.0) representable (~> 3.1) rotp (6.3.0) - rouge (4.4.0) + rouge (4.5.1) rspec (3.13.0) rspec-core (~> 3.13.0) rspec-expectations (~> 3.13.0) @@ -995,7 +1000,7 @@ GEM rspec-mocks (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) - rspec-rails (7.0.1) + rspec-rails (7.1.0) actionpack (>= 7.0) activesupport (>= 7.0) railties (>= 7.0) @@ -1008,17 +1013,17 @@ GEM rspec-support (3.13.1) rspec-wait (1.0.1) rspec (>= 3.4) - rubocop (1.67.0) + rubocop (1.69.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.2, < 2.0) + rubocop-ast (>= 1.36.1, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.3) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.36.2) parser (>= 3.3.1.0) rubocop-capybara (2.21.0) rubocop (~> 1.41) @@ -1026,7 +1031,7 @@ GEM rubocop (~> 1.61) rubocop-openproject (0.2.0) rubocop - rubocop-performance (1.22.1) + rubocop-performance (1.23.0) rubocop (>= 1.48.1, < 2.0) rubocop-ast (>= 1.31.1, < 2.0) rubocop-rails (2.27.0) @@ -1060,9 +1065,10 @@ GEM crass (~> 1.0.2) nokogiri (>= 1.12.0) secure_headers (7.0.0) - selenium-devtools (0.129.0) + securerandom (0.4.0) + selenium-devtools (0.131.0) selenium-webdriver (~> 4.2) - selenium-webdriver (4.26.0) + selenium-webdriver (4.27.0) base64 (~> 0.2) logger (~> 1.4) rexml (~> 3.2, >= 3.2.5) @@ -1079,7 +1085,7 @@ GEM multi_json (~> 1.10) simpleidn (0.2.3) smart_properties (1.17.0) - spreadsheet (1.3.1) + spreadsheet (1.3.3) bigdecimal ruby-ole spring (4.2.1) @@ -1100,7 +1106,7 @@ GEM store_attribute (1.3.1) activerecord (>= 6.1) stringex (2.8.6) - stringio (3.1.1) + stringio (3.1.2) structured_warnings (0.4.0) svg-graph (2.2.2) swd (2.0.3) @@ -1118,7 +1124,7 @@ GEM thor (1.3.2) thread_safe (0.3.6) timecop (0.9.10) - timeout (0.4.1) + timeout (0.4.2) tpm-key_attestation (0.12.1) bindata (~> 2.4) openssl (> 2.0) @@ -1138,7 +1144,7 @@ GEM tzinfo (>= 1.0.0) uber (0.1.0) unicode-display_width (2.6.0) - uri (0.13.1) + uri (1.0.2) validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) @@ -1147,7 +1153,7 @@ GEM public_suffix vcr (6.3.1) base64 - vernier (1.3.1) + vernier (1.4.0) view_component (3.20.0) activesupport (>= 5.2.0, < 8.1) concurrent-ruby (~> 1.0) @@ -1160,9 +1166,8 @@ GEM rack (>= 2.0.9) warden-basic_auth (0.2.1) warden (~> 1.2) - webauthn (3.1.0) + webauthn (3.2.2) android_key_attestation (~> 0.3.0) - awrence (~> 1.1) bindata (~> 2.4) cbor (~> 0.5.9) cose (~> 1.1) @@ -1177,7 +1182,7 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webrick (1.8.2) + webrick (1.9.1) websocket (1.2.11) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) @@ -1189,7 +1194,7 @@ GEM xpath (3.2.0) nokogiri (~> 1.8) yard (0.9.37) - zeitwerk (2.7.0) + zeitwerk (2.7.1) PLATFORMS ruby @@ -1197,7 +1202,7 @@ PLATFORMS DEPENDENCIES actionpack-xml_parser (~> 2.0.0) activemodel-serializers-xml (~> 1.0.1) - activerecord-import (~> 1.7.0) + activerecord-import (~> 1.8.0) activerecord-nulldb-adapter (~> 1.0.0) activerecord-session_store (~> 2.1.0) acts_as_list (~> 1.2.0) @@ -1206,14 +1211,14 @@ DEPENDENCIES airbrake (~> 13.0.0) appsignal (~> 3.10.0) auto_strip_attributes (~> 2.5) - awesome_nested_set (~> 3.7.0) + awesome_nested_set (~> 3.8.0) aws-sdk-core (~> 3.107) aws-sdk-s3 (~> 1.91) axe-core-rspec bcrypt (~> 3.1.6) bootsnap (~> 1.18.0) brakeman (~> 6.2.0) - browser (~> 6.0.0) + browser (~> 6.1.0) budgets! capybara (~> 3.40.0) capybara-screenshot (~> 1.0.17) @@ -1235,7 +1240,7 @@ DEPENDENCIES debug deckar01-task_list (~> 2.3.1) disposable (~> 0.6.2) - doorkeeper (~> 5.7.0) + doorkeeper (~> 5.8.0) dotenv-rails dry-auto_inject dry-container @@ -1308,7 +1313,7 @@ DEPENDENCIES openproject-octicons (~> 19.19.0) openproject-octicons_helper (~> 19.19.0) openproject-openid_connect! - openproject-primer_view_components (~> 0.48.2) + openproject-primer_view_components (~> 0.49.2) openproject-recaptcha! openproject-reporting! openproject-storages! @@ -1330,7 +1335,7 @@ DEPENDENCIES pry-rails (~> 0.3.6) pry-rescue (~> 1.6.0) puffing-billy (~> 4.0.0) - puma (~> 6.4) + puma (~> 6.5) puma-plugin-statsd (~> 2.0) rack-attack (~> 6.7.0) rack-cors (~> 2.0.2) @@ -1350,9 +1355,9 @@ DEPENDENCIES retriable (~> 3.1.1) rinku (~> 2.0.4) roar (~> 1.2.0) - rouge (~> 4.4.0) + rouge (~> 4.5.1) rspec (~> 3.13.0) - rspec-rails (~> 7.0.0) + rspec-rails (~> 7.1.0) rspec-retry (~> 0.6.1) rspec-wait rubocop diff --git a/app/components/_index.sass b/app/components/_index.sass index a14f1dce5db6..45a89e33bc3f 100644 --- a/app/components/_index.sass +++ b/app/components/_index.sass @@ -17,3 +17,4 @@ @import "projects/row_component" @import "op_primer/border_box_table_component" @import "work_packages/exports/modal_dialog_component" +@import "work_package_relations_tab/index_component" diff --git a/app/components/admin/custom_fields/custom_field_projects/new_custom_field_projects_form_modal_component.html.erb b/app/components/admin/custom_fields/custom_field_projects/new_custom_field_projects_form_modal_component.html.erb index a7596230ea1c..3950d4e83b5b 100644 --- a/app/components/admin/custom_fields/custom_field_projects/new_custom_field_projects_form_modal_component.html.erb +++ b/app/components/admin/custom_fields/custom_field_projects/new_custom_field_projects_form_modal_component.html.erb @@ -37,7 +37,7 @@ See COPYRIGHT and LICENSE files for more details. ) do |form| concat(render(Primer::Alpha::Dialog::Body.new( id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title }, - style: "min-height: 300px" + classes: "Overlay-body_autocomplete_height" )) do render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_mapping: @custom_field_project_mapping)) end) diff --git a/app/components/op_primer/border_box_row_component.html.erb b/app/components/op_primer/border_box_row_component.html.erb index f2ffcf6ad838..0b350142c64f 100644 --- a/app/components/op_primer/border_box_row_component.html.erb +++ b/app/components/op_primer/border_box_row_component.html.erb @@ -34,11 +34,17 @@ See COPYRIGHT and LICENSE files for more details. classes: "#{table.grid_class} #{row_css_class}", ) do %> <% columns.each do |column| %> - <%= render(Primer::BaseComponent.new(tag: :div, classes: column_css_class(column), **column_args(column))) { column_value(column) } %> + <%= render(Primer::BaseComponent.new(tag: :div, classes: grid_column_classes(column), **column_args(column))) do %> + <% label = mobile_label(column) %> + <% if label.present? %> + <%= render(Primer::Beta::Text.new(classes: "op-border-box-grid--row-label")) { "#{label}: " } %> + <% end %> + <%= column_value(column) %> + <% end %> <% end %> <% if table.has_actions? %> - <%= flex_layout(align_items: :center, justify_content: :flex_end) do |flex| %> + <%= flex_layout(classes: "op-border-box-grid--row-action") do |flex| %> <% button_links.each_with_index do |link, i| %> <% args = i == (button_links.count - 1) ? {} : { mr: 1 } %> <% flex.with_column(**args) { link } %> diff --git a/app/components/op_primer/border_box_row_component.rb b/app/components/op_primer/border_box_row_component.rb index 5c3b21120158..4da530abcc46 100644 --- a/app/components/op_primer/border_box_row_component.rb +++ b/app/components/op_primer/border_box_row_component.rb @@ -32,6 +32,26 @@ module OpPrimer class BorderBoxRowComponent < RowComponent # rubocop:disable OpenProject/AddPreviewForViewComponent include ComponentHelpers + def mobile_label(column) + return unless table.mobile_labels.include?(column) + + table.column_title(column) + end + + def visible_on_mobile?(column) + table.mobile_columns.include?(column) + end + + def grid_column_classes(column) + classes = ["op-border-box-grid--row-item"] + classes << column_css_class(column) + classes << "op-border-box-grid--main-column" if table.main_column?(column) + classes << "ellipsis" unless table.main_column?(column) + classes << "op-border-box-grid--no-mobile" unless visible_on_mobile?(column) + + classes.compact.join(" ") + end + def column_args(_column) {} end diff --git a/app/components/op_primer/border_box_table_component.html.erb b/app/components/op_primer/border_box_table_component.html.erb index 2e150ac4870e..4c96232aa95f 100644 --- a/app/components/op_primer/border_box_table_component.html.erb +++ b/app/components/op_primer/border_box_table_component.html.erb @@ -35,12 +35,17 @@ See COPYRIGHT and LICENSE files for more details. )) do |component| component.with_header(classes: grid_class, color: :muted) do headers.each do |name, args| - caption = args.delete(:caption) - concat render(Primer::Beta::Text.new(font_weight: :semibold, **header_args(name))) { caption } + concat render(Primer::Beta::Text.new(classes: header_classes(name), + font_weight: :semibold, + **header_args(name))) { args[:caption] } end + concat render(Primer::Beta::Text.new(classes: "op-border-box-grid--mobile-heading", + font_weight: :semibold)) { mobile_title } + if has_actions? - concat render(Primer::BaseComponent.new(tag: :div)) + concat render(Primer::BaseComponent.new(classes: heading_class, + tag: :div)) end end diff --git a/app/components/op_primer/border_box_table_component.rb b/app/components/op_primer/border_box_table_component.rb index b1cb1b9463e8..b005fe4be6d0 100644 --- a/app/components/op_primer/border_box_table_component.rb +++ b/app/components/op_primer/border_box_table_component.rb @@ -32,10 +32,71 @@ module OpPrimer class BorderBoxTableComponent < TableComponent include ComponentHelpers + class << self + # Declares columns to be shown in the mobile table + # + # Use it in subclasses like so: + # + # columns :name, :description + # + # mobile_columns :name + # + # This results in the description columns to be hidden on mobile + def mobile_columns(*names) + return @mobile_columns || columns if names.empty? + + @mobile_columns = names.map(&:to_sym) + end + + # Declares which columns to be rendered with a label + # + # mobile_labels :name + # + # This results in the description columns to be hidden on mobile + def mobile_labels(*names) + return @mobile_labels if names.empty? + + @mobile_labels = names.map(&:to_sym) + end + + # Declare main columns, that will result in a grid column span of 2 and not truncate text + # + # column_grid_span :title + # + def main_column(*names) + return Array(@main_columns) if names.empty? + + @main_columns = names.map(&:to_sym) + end + end + + delegate :mobile_columns, :mobile_labels, + to: :class + + def main_column?(column) + self.class.main_column.include?(column) + end + def header_args(_column) {} end + def column_title(name) + header = headers.find { |h| h[0] == name } + header ? header[1][:caption] : nil + end + + def header_classes(column) + classes = [heading_class] + classes << "op-border-box-grid--main-column" if main_column?(column) + + classes.join(" ") + end + + def heading_class + "op-border-box-grid--heading" + end + # Default grid class with equal weights def grid_class "op-border-box-grid" @@ -57,6 +118,10 @@ def render_blank_slate end end + def mobile_title + raise ArgumentError, "Need to provide a mobile table title" + end + def blank_title I18n.t(:label_nothing_display) end diff --git a/app/components/op_primer/border_box_table_component.sass b/app/components/op_primer/border_box_table_component.sass index 254c212dffc7..34902845700b 100644 --- a/app/components/op_primer/border_box_table_component.sass +++ b/app/components/op_primer/border_box_table_component.sass @@ -1,7 +1,47 @@ +@import "helpers" + .op-border-box-grid display: grid - justify-content: flex-start - align-items: center - // Distribute columns evenly by default - grid-auto-columns: minmax(0, 1fr) - grid-auto-flow: column + + &--row-action + align-items: center + justify-content: flex-end + +@media screen and (min-width: $breakpoint-md) + .op-border-box-grid + // Distribute columns evenly on desktop + grid-auto-columns: minmax(0, 1fr) + grid-auto-flow: column + justify-content: flex-start + align-items: center + + &--heading, + &--row-item + &:not(:first-child) + padding-left: 6px + + &:not(:last-child) + padding-right: 6px + + &--mobile-heading, + &--row-label + display: none + + &--main-column + grid-column: span 2 + +@media screen and (max-width: $breakpoint-md) + .op-border-box-grid + grid-template-columns: 1fr auto + grid-auto-flow: row + + &--heading, + &--no-mobile + display: none + + &--row-item + grid-column: 1 + + &--row-action + grid-column: 2 + grid-row: 1 diff --git a/app/components/work_package_relations_tab/add_work_package_child_dialog_component.html.erb b/app/components/work_package_relations_tab/add_work_package_child_dialog_component.html.erb new file mode 100644 index 000000000000..d068472fdcff --- /dev/null +++ b/app/components/work_package_relations_tab/add_work_package_child_dialog_component.html.erb @@ -0,0 +1,30 @@ +<%= + render(Primer::Alpha::Dialog.new(title: dialog_title, + size: :large, + id: DIALOG_ID)) do |d| + d.with_header(variant: :large) + d.with_body(classes: "Overlay-body_autocomplete_height") do + render(WorkPackageRelationsTab::AddWorkPackageChildFormComponent.new( + work_package: @work_package + )) + end + d.with_footer do + component_collection do |buttons| + buttons.with_component(Primer::ButtonComponent.new( + data: { + 'close-dialog-id': DIALOG_ID + } + )) do + t("button_cancel") + end + buttons.with_component(Primer::ButtonComponent.new( + scheme: :primary, + form: FORM_ID, + data: { turbo: true }, + type: :submit)) do + t("button_save") + end + end + end + end +%> diff --git a/app/components/work_package_relations_tab/add_work_package_child_dialog_component.rb b/app/components/work_package_relations_tab/add_work_package_child_dialog_component.rb new file mode 100644 index 000000000000..8f3ae85e92d2 --- /dev/null +++ b/app/components/work_package_relations_tab/add_work_package_child_dialog_component.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsTab::AddWorkPackageChildDialogComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + I18N_NAMESPACE = "work_package_relations_tab" + DIALOG_ID = "add-work-package-child-dialog" + FORM_ID = "add-work-package-child-form" + + attr_reader :work_package + + def initialize(work_package:) + super() + + @work_package = work_package + end + + private + + def dialog_title + child_label = t("#{I18N_NAMESPACE}.relations.label_child_singular") + t("#{I18N_NAMESPACE}.label_add_x", x: child_label) + end +end diff --git a/app/components/work_package_relations_tab/add_work_package_child_form_component.html.erb b/app/components/work_package_relations_tab/add_work_package_child_form_component.html.erb new file mode 100644 index 000000000000..17142756557b --- /dev/null +++ b/app/components/work_package_relations_tab/add_work_package_child_form_component.html.erb @@ -0,0 +1,38 @@ +<%= component_wrapper do %> + <%= primer_form_with( + id: FORM_ID, + model: WorkPackage.new, + **submit_url_options, + data: { + turbo: true, + update_work_package: true + } + ) do |f| %> + <%# Form fields section %> + <%= flex_layout(my: 3) do |flex| + flex.with_row do + if @base_errors&.any? + render(Primer::Alpha::Banner.new(mb: 3, icon: :stop, scheme: :danger)) { @base_errors.join("\n") } + end + end + flex.with_row do + render_inline_form(f) do |my_form| + my_form.work_package_autocompleter( + name: :id, + label: WorkPackage.model_name.human, + visually_hide_label: false, + autocomplete_options: { + resource: 'work_packages', + searchKey: 'subjectOrId', + openDirectly: false, + focusDirectly: true, + dropdownPosition: 'bottom', + appendTo: "##{DIALOG_ID}", + data: { test_selector: ID_FIELD_TEST_SELECTOR } + } + ) + end + end + end %> + <% end %> +<% end %> diff --git a/app/components/work_package_relations_tab/add_work_package_child_form_component.rb b/app/components/work_package_relations_tab/add_work_package_child_form_component.rb new file mode 100644 index 000000000000..f9f4d6863b11 --- /dev/null +++ b/app/components/work_package_relations_tab/add_work_package_child_form_component.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsTab::AddWorkPackageChildFormComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + DIALOG_ID = "add-work-package-child-dialog" + FORM_ID = "add-work-package-child-form" + ID_FIELD_TEST_SELECTOR = "work-package-child-form-id" + I18N_NAMESPACE = "work_package_relations_tab" + + def initialize(work_package:, base_errors: nil) + super() + + @work_package = work_package + @base_errors = base_errors + end + + def submit_url_options + { method: :post, + url: work_package_children_path(@work_package) } + end +end diff --git a/app/components/work_package_relations_tab/index_component.html.erb b/app/components/work_package_relations_tab/index_component.html.erb new file mode 100644 index 000000000000..e78e21510bbf --- /dev/null +++ b/app/components/work_package_relations_tab/index_component.html.erb @@ -0,0 +1,103 @@ +<%= component_wrapper(tag: "turbo-frame") do %> + <%= + if should_render_create_button? + flex_layout(justify_content: :space_between, align_items: :center, mb: 4) do |action_bar| + action_bar.with_column(pr: 1) do + render(Primer::Beta::Text.new(color: :muted)) do + t("#{I18N_NAMESPACE}.index.action_bar_title") + end + end + + # Prevent the menu from overflowing on Safari + action_bar.with_column(flex_shrink: 0, ml: 2) do + render(Primer::Alpha::ActionMenu.new(test_selector: NEW_RELATION_ACTION_MENU, + menu_id: NEW_RELATION_ACTION_MENU)) do |menu| + menu.with_show_button do |button| + button.with_leading_visual_icon(icon: :"plus") + button.with_trailing_action_icon(icon: :"triangle-down") + t(:label_relation) + end + + if should_render_add_relations? + Relation::TYPES.each do |relation_type, type_configuration_hash| + label_key = "#{I18N_NAMESPACE}.relations.#{type_configuration_hash[:name]}_singular" + menu.with_item( + label: t(label_key).capitalize, + href: new_relation_path(relation_type:), + test_selector: new_button_test_selector(relation_type:), + content_arguments: { + data: { turbo_stream: true } + } + ) do |item| + item.with_description.with_content(t("#{I18N_NAMESPACE}.relations.#{relation_type}_description")) + end + end + end + + if should_render_add_child? + menu.with_item( + label: t("#{I18N_NAMESPACE}.relations.label_child_singular").capitalize, + href: new_work_package_child_path(@work_package), + test_selector: new_button_test_selector(relation_type: :child), + content_arguments: { + data: { turbo_stream: true } + } + ) do |item| + item.with_description.with_content(t("#{I18N_NAMESPACE}.relations.child_description")) + end + end + end + end + end + end + %> + + <%= + flex_layout(mb: 3) do |flex| + if any_relations? + key_namespace = "#{I18N_NAMESPACE}.relations" + + # Relations + directionally_aware_grouped_relations.each do |relation_type, relations_of_type| + base_key = "#{key_namespace}.label_#{relation_type}" + + flex.with_row(mb: 4) do + render_relation_group( + title: t("#{base_key}_plural").capitalize, + relation_type:, + items: relations_of_type + ) do |relation| + render(WorkPackageRelationsTab::RelationComponent.new(work_package:, + relation:)) + end + end + end + + # Children + if children.any? + base_key = "#{key_namespace}.label_child" + + flex.with_row do + render_relation_group( + title: t("#{base_key}_plural").capitalize, + relation_type: :children, + items: children + ) do |child| + render(WorkPackageRelationsTab::RelationComponent.new(work_package:, + relation: nil, + child:)) + end + end + end + else + flex.with_row do + render Primer::Beta::Blankslate.new(border: true) do |component| + component.with_visual_icon(icon: "package-dependents") + component.with_heading(tag: :h4).with_content(t("#{I18N_NAMESPACE}.index.blankslate_heading")) + component.with_description { t("#{I18N_NAMESPACE}.index.blankslate_description") } + end + end + end + end + %> +<% end %> diff --git a/app/components/work_package_relations_tab/index_component.rb b/app/components/work_package_relations_tab/index_component.rb new file mode 100644 index 000000000000..083455043601 --- /dev/null +++ b/app/components/work_package_relations_tab/index_component.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +class WorkPackageRelationsTab::IndexComponent < ApplicationComponent + FRAME_ID = "work-package-relations-tab-content" + NEW_RELATION_ACTION_MENU = "new-relation-action-menu" + I18N_NAMESPACE = "work_package_relations_tab" + include ApplicationHelper + include OpPrimer::ComponentHelpers + include Turbo::FramesHelper + include OpTurbo::Streamable + + attr_reader :work_package, :relations, :children, :directionally_aware_grouped_relations + + def initialize(work_package:, relations:, children:) + super() + + @work_package = work_package + @relations = relations + @children = children + @directionally_aware_grouped_relations = group_relations_by_directional_context + end + + def self.wrapper_key + FRAME_ID + end + + private + + def should_render_add_child? + helpers.current_user.allowed_in_project?(:manage_subtasks, @work_package.project) + end + + def should_render_add_relations? + helpers.current_user.allowed_in_project?(:manage_work_package_relations, @work_package.project) + end + + def should_render_create_button? + should_render_add_child? || should_render_add_relations? + end + + def group_relations_by_directional_context + relations.group_by do |relation| + relation.relation_type_for(work_package) + end + end + + def any_relations? = relations.any? || children.any? + + def render_relation_group(title:, relation_type:, items:, &_block) + render(border_box_container(padding: :condensed, + data: { test_selector: "op-relation-group-#{relation_type}" })) do |border_box| + border_box.with_header(py: 3) do + flex_layout(align_items: :center) do |flex| + flex.with_column(mr: 2) do + render(Primer::Beta::Text.new(font_size: :normal, font_weight: :bold)) { title } + end + flex.with_column do + render(Primer::Beta::Counter.new(count: items.size, round: true, scheme: :primary)) + end + end + end + + items.each do |item| + border_box.with_row(test_selector: row_test_selector(item)) do + yield(item) + end + end + end + end + + def new_relation_path(relation_type:) + raise ArgumentError, "Invalid relation type: #{relation_type}" unless Relation::TYPES.key?(relation_type) + + if relation_type == Relation::TYPE_CHILD + raise NotImplementedError, "Child relations are not supported yet" + else + new_work_package_relation_path(work_package, relation_type:) + end + end + + def new_button_test_selector(relation_type:) + "op-new-relation-button-#{relation_type}" + end + + def row_test_selector(item) + if item.is_a?(Relation) + target = item.to == work_package ? item.from : item.to + "op-relation-row-#{target.id}" + else # Work Package object + "op-relation-row-#{item.id}" + end + end +end diff --git a/app/components/work_package_relations_tab/index_component.sass b/app/components/work_package_relations_tab/index_component.sass new file mode 100644 index 000000000000..32a1e670cced --- /dev/null +++ b/app/components/work_package_relations_tab/index_component.sass @@ -0,0 +1,5 @@ +// We reference an ID as one is required to be specified for the action menu list. +// It can't be nested inside the BEM model as it's placed as a #top-layer element. +#new-relation-action-menu-list + max-height: 450px + max-width: 280px diff --git a/app/components/work_package_relations_tab/relation_component.html.erb b/app/components/work_package_relations_tab/relation_component.html.erb new file mode 100644 index 000000000000..b4cdd78822b4 --- /dev/null +++ b/app/components/work_package_relations_tab/relation_component.html.erb @@ -0,0 +1,104 @@ +<%= +flex_layout do |flex| + flex.with_row(flex_layout: true, justify_content: :space_between, align_items: :center) do |row| + row.with_column do + render(WorkPackages::InfoLineComponent.new(work_package: related_work_package)) + end + + if should_render_action_menu? + row.with_column do + render(Primer::Alpha::ActionMenu.new(test_selector: action_menu_test_selector)) do |menu| + menu.with_show_button(icon: "kebab-horizontal", + "aria-label": I18n.t(:label_relation_actions), + scheme: :invisible, + ml: 2) + + if should_render_edit_option? + menu.with_item(label: "Edit relation", + href: edit_path, + test_selector: edit_button_test_selector, + content_arguments: { + data: { turbo_stream: true } + }) do |item| + item.with_leading_visual_icon(icon: :pencil) + end + end + + menu.with_item(label: "Delete relation", + scheme: :danger, + href: destroy_path, + form_arguments: { + method: :delete, + data: { + confirm: t("text_are_you_sure"), + turbo_stream: true, + update_work_package: true + } + }, + test_selector: delete_button_test_selector) do |item| + item.with_leading_visual_icon(icon: :trash) + end + end + end + end + end + + flex.with_row(mb: 2) do + render(Primer::Beta::Link.new(href: work_package_path(related_work_package), + color: :default, + underline: false, + font_size: :normal, + font_weight: :bold, + target: "_blank")) { related_work_package.subject } + end + + if should_display_description? + flex.with_row(mb: 2) do + render(Primer::Beta::Text.new(font_size: :small, color: :muted)) { format_text(relation, :description) } + end + end + + if should_display_dates_row? + flex.with_row(flex_layout: true, align_items: :center, color: :muted, mb: 2) do |dates_row| + if precedes? && lag_present? + dates_row.with_column(mr: 1) do + render(Primer::Beta::Octicon.new(icon: "arrow-both")) + end + dates_row.with_column(mr: 3) do + render(Primer::Beta::Text.new) do + lag_as_text(relation.lag) + end + end + end + + if related_work_package.start_date.present? || related_work_package.due_date.present? + dates_row.with_column(mr: 1) do + icon = if follows? + :calendar + elsif precedes? + :pin + end + + render(Primer::Beta::Octicon.new(icon:)) + end + dates_row.with_column do + render(Primer::Beta::Text.new) do + "#{format_date(related_work_package.start_date)} - #{format_date(related_work_package.due_date)}" + end + end + end + + if follows? && lag_present? + dates_row.with_column(ml: 3, mr: 1) do + render(Primer::Beta::Octicon.new(icon: "arrow-both")) + end + dates_row.with_column(mr: 1) do + render(Primer::Beta::Text.new) do + lag_as_text(relation.lag) + end + end + end + end + end +end +%> diff --git a/app/components/work_package_relations_tab/relation_component.rb b/app/components/work_package_relations_tab/relation_component.rb new file mode 100644 index 000000000000..08e1452e02c5 --- /dev/null +++ b/app/components/work_package_relations_tab/relation_component.rb @@ -0,0 +1,113 @@ +class WorkPackageRelationsTab::RelationComponent < ApplicationComponent + include ApplicationHelper + include OpPrimer::ComponentHelpers + + attr_reader :work_package, :relation, :child + + def initialize(work_package:, + relation:, + child: nil) + super() + + @work_package = work_package + @relation = relation + @child = child + end + + def related_work_package + @related_work_package ||= if parent_child_relationship? + @child + else + relation.from == work_package ? relation.to : relation.from + end + end + + private + + def parent_child_relationship? = @child.present? + + def should_render_edit_option? + # Children have nothing to edit as it's not a relation. + !parent_child_relationship? && allowed_to_manage_relations? + end + + def should_render_action_menu? + if parent_child_relationship? + allowed_to_manage_subtasks? + else + allowed_to_manage_relations? + end + end + + def allowed_to_manage_subtasks? + helpers.current_user.allowed_in_project?(:manage_subtasks, @work_package.project) + end + + def allowed_to_manage_relations? + helpers.current_user.allowed_in_project?(:manage_work_package_relations, @work_package.project) + end + + def underlying_resource_id + @underlying_resource_id ||= if parent_child_relationship? + @child.id + else + @relation.other_work_package(work_package).id + end + end + + def should_display_description? + return false if parent_child_relationship? + + relation.description.present? + end + + def lag_present? + relation.lag.present? && relation.lag != 0 + end + + def should_display_dates_row? + return false if parent_child_relationship? + + relation.follows? || relation.precedes? + end + + def follows? + relation.relation_type_for(work_package) == Relation::TYPE_FOLLOWS + end + + def precedes? + relation.relation_type_for(work_package) == Relation::TYPE_PRECEDES + end + + def edit_path + if parent_child_relationship? + raise NotImplementedError, "Children relationships are not editable" + else + edit_work_package_relation_path(@work_package, @relation) + end + end + + def destroy_path + if parent_child_relationship? + work_package_child_path(@work_package, @child) + else + work_package_relation_path(@work_package, @relation) + end + end + + def lag_as_text(lag) + "#{I18n.t('work_package_relations_tab.lag.subject')}: #{I18n.t('datetime.distance_in_words.x_days', count: lag)}" + end + + def action_menu_test_selector + "op-relation-row-#{underlying_resource_id}-action-menu" + end + + def edit_button_test_selector + "op-relation-row-#{underlying_resource_id}-edit-button" + end + + def delete_button_test_selector + "op-relation-row-#{underlying_resource_id}-delete-button" + end +end diff --git a/app/components/work_package_relations_tab/work_package_relation_dialog_component.html.erb b/app/components/work_package_relations_tab/work_package_relation_dialog_component.html.erb new file mode 100644 index 000000000000..d9cf73a50d36 --- /dev/null +++ b/app/components/work_package_relations_tab/work_package_relation_dialog_component.html.erb @@ -0,0 +1,29 @@ +<%= + render(Primer::Alpha::Dialog.new(title: dialog_title, + size: :large, + id: DIALOG_ID)) do |d| + d.with_header(variant: :large) + d.with_body(classes: "Overlay-body_autocomplete_height") do + render(WorkPackageRelationsTab::WorkPackageRelationFormComponent.new( + work_package: @work_package, + relation: @relation + )) + end + d.with_footer do + component_collection do |buttons| + buttons.with_component(Primer::ButtonComponent.new( + data: { 'close-dialog-id': DIALOG_ID } + )) do + t(:button_cancel) + end + buttons.with_component(Primer::ButtonComponent.new( + scheme: :primary, + form: FORM_ID, + data: { turbo: true }, + type: :submit)) do + t(:button_save) + end + end + end + end +%> diff --git a/app/components/work_package_relations_tab/work_package_relation_dialog_component.rb b/app/components/work_package_relations_tab/work_package_relation_dialog_component.rb new file mode 100644 index 000000000000..c56edcd2ba98 --- /dev/null +++ b/app/components/work_package_relations_tab/work_package_relation_dialog_component.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsTab::WorkPackageRelationDialogComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + I18N_NAMESPACE = "work_package_relations_tab" + DIALOG_ID = "work-package-relation-dialog" + FORM_ID = "work-package-relation-form" + + attr_reader :relation, :work_package + + def initialize(work_package:, relation:) + super() + + @relation = relation + @work_package = work_package + end + + private + + def dialog_title + relative_label = relation.label_for(work_package) + relation_label = t("#{I18N_NAMESPACE}.relations.#{relative_label}_singular") + + if relation.persisted? + t("#{I18N_NAMESPACE}.label_edit_x", x: relation_label) + else + t("#{I18N_NAMESPACE}.label_add_x", x: relation_label) + end + end +end diff --git a/app/components/work_package_relations_tab/work_package_relation_form_component.html.erb b/app/components/work_package_relations_tab/work_package_relation_form_component.html.erb new file mode 100644 index 000000000000..83879e8a97c6 --- /dev/null +++ b/app/components/work_package_relations_tab/work_package_relation_form_component.html.erb @@ -0,0 +1,77 @@ +<%= component_wrapper do %> + <%= primer_form_with( + id: FORM_ID, + model: @relation, + **submit_url_options, + data: { + turbo: true, + update_work_package: true + } + ) do |f| %> + <%# Form fields section %> + <%= flex_layout(my: 2) do |flex| + flex.with_row do + if @base_errors&.any? + render(Primer::Alpha::Banner.new(mb: 3, icon: :stop, scheme: :danger)) { @base_errors.join("\n") } + end + end + flex.with_row do + # These are not available inside the render_inline_form block + # so we need to re-define them here. Figure out solution for this. + relation = @relation + lag_shown = show_lag? + to_id_field_value = relation.to.present? ? "#{related_work_package.type.name.upcase} ##{related_work_package.id} - #{related_work_package.subject}" : nil + url = ::API::V3::Utilities::PathHelper::ApiV3Path.work_package_available_relation_candidates(@work_package.id, type: relation.relation_type_for(@work_package)) + render_inline_form(f) do |my_form| + if relation.persisted? + my_form.text_field( + name: :to_id, + label: WorkPackage.model_name.human, + visually_hide_label: false, + value: to_id_field_value, + readonly: true + ) + else + my_form.hidden( + name: :relation_type, + value: relation.relation_type + ) + + my_form.autocompleter( + name: :to_id, + label: WorkPackage.model_name.human, + visually_hide_label: false, + autocomplete_options: { + resource: 'work_packages', + url:, + relations: true, # Activates relations fetch mode in the autocomplete + openDirectly: false, + focusDirectly: true, + dropdownPosition: 'bottom', + appendTo: "##{DIALOG_ID}", + data: { test_selector: TO_ID_FIELD_TEST_SELECTOR} + } + ) + end + + my_form.text_field( + name: :description, + label: Relation.human_attribute_name(:description), + autofocus: relation.persisted? + ) + + if lag_shown + my_form.text_field( + name: :lag, + type: :number, + min: 0, + label: I18n.t("work_package_relations_tab.lag.title"), + caption: I18n.t("work_package_relations_tab.lag.caption"), + input_width: :small, + ) + end + end + end + end %> + <% end %> +<% end %> diff --git a/app/components/work_package_relations_tab/work_package_relation_form_component.rb b/app/components/work_package_relations_tab/work_package_relation_form_component.rb new file mode 100644 index 000000000000..264d08770fab --- /dev/null +++ b/app/components/work_package_relations_tab/work_package_relation_form_component.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsTab::WorkPackageRelationFormComponent < ApplicationComponent + include ApplicationHelper + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + DIALOG_ID = "work-package-relation-dialog" + FORM_ID = "work-package-relation-form" + TO_ID_FIELD_TEST_SELECTOR = "work-package-relation-form-to-id" + I18N_NAMESPACE = "work_package_relations_tab" + + def initialize(work_package:, relation:, base_errors: nil) + super() + + @work_package = work_package + @relation = relation + @base_errors = base_errors + end + + def related_work_package + @related_work_package ||= begin + related = @relation.to + # We cannot rely on the related WorkPackage being the "to", + # depending on the relation it can also be "from" + related.id == @work_package.id ? @relation.from : related + end + end + + def submit_url_options + if @relation.persisted? + { method: :patch, + url: work_package_relation_path(@work_package, @relation) } + else + { method: :post, + url: work_package_relations_path(@work_package) } + end + end + + def show_lag? + @relation.relation_type == Relation::TYPE_PRECEDES || @relation.relation_type == Relation::TYPE_FOLLOWS + end +end diff --git a/app/components/work_packages/activities_tab/index_component.html.erb b/app/components/work_packages/activities_tab/index_component.html.erb index 6ff2baeee91c..6b4492a05afe 100644 --- a/app/components/work_packages/activities_tab/index_component.html.erb +++ b/app/components/work_packages/activities_tab/index_component.html.erb @@ -1,53 +1,59 @@ <%= - content_tag("turbo-frame", id: "work-package-activities-tab-content") do - flex_layout(classes: "work-packages-activities-tab-index-component", mb: [5, 5, 5, 5, 0]) do |activties_tab_wrapper_container| - activties_tab_wrapper_container.with_row(classes: "work-packages-activities-tab-index-component--errors") do - render( - WorkPackages::ActivitiesTab::ErrorStreamComponent.new - ) - end - activties_tab_wrapper_container.with_row do - component_wrapper(data: wrapper_data_attributes) do - flex_layout do |activties_tab_container| - activties_tab_container.with_row(mb: 2) do - render( - WorkPackages::ActivitiesTab::Journals::FilterAndSortingComponent.new( - work_package:, - filter: - ) - ) - end - activties_tab_container.with_row(flex_layout: true, mt: 3) do |journals_wrapper_container| - journals_wrapper_container.with_row( - classes: "work-packages-activities-tab-index-component--journals-container work-packages-activities-tab-index-component--journals-container_with-initial-input-compensation", - data: { "work-packages--activities-tab--index-target": "journalsContainer" } - ) do + unless deferred + content_tag("turbo-frame", id: "work-package-activities-tab-content") do + flex_layout(classes: "work-packages-activities-tab-index-component", mb: [5, 5, 5, 5, 0]) do |activties_tab_wrapper_container| + activties_tab_wrapper_container.with_row(classes: "work-packages-activities-tab-index-component--errors") do + render( + WorkPackages::ActivitiesTab::ErrorStreamComponent.new + ) + end + activties_tab_wrapper_container.with_row do + component_wrapper(data: wrapper_data_attributes) do + flex_layout do |activties_tab_container| + activties_tab_container.with_row(mb: 2) do render( - WorkPackages::ActivitiesTab::Journals::IndexComponent.new(work_package:, filter:) + WorkPackages::ActivitiesTab::Journals::FilterAndSortingComponent.new( + work_package:, + filter: + ) ) end - if adding_comment_allowed? + activties_tab_container.with_row(flex_layout: true, mt: 3) do |journals_wrapper_container| journals_wrapper_container.with_row( - classes: "work-packages-activities-tab-index-component--input-container work-packages-activities-tab-index-component--input-container_sort-#{journal_sorting}", - mt: 3, - mb: [3, nil, nil, nil, 0], - pt: 2, - pb: 2, - pl: 3, - pr: [3, nil, nil, nil, 2], - border: [nil, nil, nil, nil, :top], - border_radius: [2, nil, nil, nil, 0], - bg: :subtle + classes: "work-packages-activities-tab-index-component--journals-container work-packages-activities-tab-index-component--journals-container_with-initial-input-compensation", + data: { "work-packages--activities-tab--index-target": "journalsContainer" } ) do render( - WorkPackages::ActivitiesTab::Journals::NewComponent.new(work_package:) + WorkPackages::ActivitiesTab::Journals::IndexComponent.new(work_package:, filter:) ) end + if adding_comment_allowed? + journals_wrapper_container.with_row( + classes: "work-packages-activities-tab-index-component--input-container work-packages-activities-tab-index-component--input-container_sort-#{journal_sorting}", + mt: 3, + mb: [3, nil, nil, nil, 0], + pt: 2, + pb: 2, + pl: 3, + pr: [3, nil, nil, nil, 2], + border: [nil, nil, nil, nil, :top], + border_radius: [2, nil, nil, nil, 0], + bg: :subtle + ) do + render( + WorkPackages::ActivitiesTab::Journals::NewComponent.new(work_package:) + ) + end + end end end end end end end + else + render( + WorkPackages::ActivitiesTab::Journals::IndexComponent.new(work_package:, filter:, deferred:) + ) end %> diff --git a/app/components/work_packages/activities_tab/index_component.rb b/app/components/work_packages/activities_tab/index_component.rb index 65ed1463d37c..3be97f3d5cd0 100644 --- a/app/components/work_packages/activities_tab/index_component.rb +++ b/app/components/work_packages/activities_tab/index_component.rb @@ -36,17 +36,18 @@ class IndexComponent < ApplicationComponent include OpTurbo::Streamable include WorkPackages::ActivitiesTab::SharedHelpers - def initialize(work_package:, last_server_timestamp:, filter: :all) + def initialize(work_package:, last_server_timestamp:, filter: :all, deferred: false) super @work_package = work_package @filter = filter @last_server_timestamp = last_server_timestamp + @deferred = deferred end private - attr_reader :work_package, :filter, :last_server_timestamp + attr_reader :work_package, :filter, :last_server_timestamp, :deferred def wrapper_data_attributes stimulus_controller = "work-packages--activities-tab--index" @@ -77,7 +78,7 @@ def polling_interval end def adding_comment_allowed? - User.current.allowed_in_project?(:add_work_package_notes, @work_package.project) + User.current.allowed_in_work_package?(:add_work_package_notes, @work_package) end end end diff --git a/app/components/work_packages/activities_tab/journals/index_component.html.erb b/app/components/work_packages/activities_tab/journals/index_component.html.erb index aa761592d114..c541372a20a6 100644 --- a/app/components/work_packages/activities_tab/journals/index_component.html.erb +++ b/app/components/work_packages/activities_tab/journals/index_component.html.erb @@ -1,34 +1,61 @@ <%= - component_wrapper(class: "work-packages-activities-tab-journals-index-component") do - flex_layout(data: { test_selector: "op-wp-journals-#{filter}-#{journal_sorting}" }) do |journals_index_wrapper_container| - journals_index_wrapper_container.with_row( - classes: "work-packages-activities-tab-journals-index-component--journals-inner-container", - mb: inner_container_margin_bottom - ) do - flex_layout(id: insert_target_modifier_id, - data: { test_selector: "op-wp-journals-container" }) do |journals_index_container| - if empty_state? - journals_index_container.with_row(mt: 2, mb: 3) do - render( - WorkPackages::ActivitiesTab::Journals::EmptyComponent.new - ) + unless deferred + component_wrapper(class: "work-packages-activities-tab-journals-index-component") do + flex_layout(data: { test_selector: "op-wp-journals-#{filter}-#{journal_sorting}" }) do |journals_index_wrapper_container| + journals_index_wrapper_container.with_row( + classes: "work-packages-activities-tab-journals-index-component--journals-inner-container", + mb: inner_container_margin_bottom + ) do + flex_layout(id: insert_target_modifier_id, + data: { test_selector: "op-wp-journals-container" }) do |journals_index_container| + if empty_state? + journals_index_container.with_row(mt: 2, mb: 3) do + render( + WorkPackages::ActivitiesTab::Journals::EmptyComponent.new + ) + end + end + + if !journal_sorting_desc? && journals.count > MAX_RECENT_JOURNALS + journals_index_container.with_row do + helpers.turbo_frame_tag("work-package-activities-tab-content-older-journals", src: work_package_activities_path(work_package, filter:, deferred: true)) + end end - end - journals.each do |journal| - journals_index_container.with_row do - render(WorkPackages::ActivitiesTab::Journals::ItemComponent.new( - journal:, filter:, - grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[journal.id] - )) + recent_journals.each do |journal| + journals_index_container.with_row do + render(WorkPackages::ActivitiesTab::Journals::ItemComponent.new( + journal:, filter:, + grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[journal.id] + )) + end + end + + if journal_sorting_desc? && journals.count > MAX_RECENT_JOURNALS + journals_index_container.with_row do + helpers.turbo_frame_tag("work-package-activities-tab-content-older-journals", src: work_package_activities_path(work_package, filter:, deferred: true)) + end end end end - end - unless empty_state? || journal_sorting_desc? - journals_index_wrapper_container - .with_row(classes: "work-packages-activities-tab-journals-index-component--stem-connection") + unless empty_state? || journal_sorting_desc? + journals_index_wrapper_container + .with_row(classes: "work-packages-activities-tab-journals-index-component--stem-connection") + end + end + end + else + helpers.turbo_frame_tag("work-package-activities-tab-content-older-journals") do + flex_layout do |older_journals_container| + older_journals.each do |journal| + older_journals_container.with_row do + render(WorkPackages::ActivitiesTab::Journals::ItemComponent.new( + journal:, filter:, + grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[journal.id] + )) + end + end end end end diff --git a/app/components/work_packages/activities_tab/journals/index_component.rb b/app/components/work_packages/activities_tab/journals/index_component.rb index a2120884a006..469f0e3d4e11 100644 --- a/app/components/work_packages/activities_tab/journals/index_component.rb +++ b/app/components/work_packages/activities_tab/journals/index_component.rb @@ -32,21 +32,24 @@ module WorkPackages module ActivitiesTab module Journals class IndexComponent < ApplicationComponent + MAX_RECENT_JOURNALS = 30 + include ApplicationHelper include OpPrimer::ComponentHelpers include OpTurbo::Streamable include WorkPackages::ActivitiesTab::SharedHelpers - def initialize(work_package:, filter: :all) + def initialize(work_package:, filter: :all, deferred: false) super @work_package = work_package @filter = filter + @deferred = deferred end private - attr_reader :work_package, :filter + attr_reader :work_package, :filter, :deferred def insert_target_modified? true @@ -60,16 +63,48 @@ def journal_sorting_desc? journal_sorting == "desc" end - def journals + def base_journals work_package .journals - .includes(:user, :notifications) + .includes( + :user, + :customizable_journals, + :attachable_journals, + :storable_journals, + :notifications + ) .reorder(version: journal_sorting) .with_sequence_version end + def journals + API::V3::Activities::ActivityEagerLoadingWrapper.wrap(base_journals) + end + + def recent_journals + recent_ones = if journal_sorting_desc? + base_journals.first(MAX_RECENT_JOURNALS) + else + base_journals.last(MAX_RECENT_JOURNALS) + end + + API::V3::Activities::ActivityEagerLoadingWrapper.wrap(recent_ones) + end + + def older_journals + older_ones = if journal_sorting_desc? + base_journals.offset(MAX_RECENT_JOURNALS) + else + total = base_journals.count + limit = [total - MAX_RECENT_JOURNALS, 0].max + base_journals.limit(limit) + end + + API::V3::Activities::ActivityEagerLoadingWrapper.wrap(older_ones) + end + def journal_with_notes - journals.where.not(notes: "") + base_journals.where.not(notes: "") end def wp_journals_grouped_emoji_reactions diff --git a/app/components/work_packages/activities_tab/journals/item_component.html.erb b/app/components/work_packages/activities_tab/journals/item_component.html.erb index 46e88201e3c8..7ea180f1a7ae 100644 --- a/app/components/work_packages/activities_tab/journals/item_component.html.erb +++ b/app/components/work_packages/activities_tab/journals/item_component.html.erb @@ -30,6 +30,16 @@ classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis hidden-for-mobile") do truncated_user_name(journal.user) end + if journal.initial? + header_start_container.with_column( + mr: 1, + classes: "work-packages-activities-tab-journals-item-component-details--journal-type hidden-for-mobile" + ) do + render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mt: 1)) do + I18n.t("activities.work_packages.activity_tab.created_on") + end + end + end header_start_container.with_column(mr: 1, classes: "hidden-for-mobile") do render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mt: 1)) { format_time(journal.updated_at) } end diff --git a/app/components/work_packages/activities_tab/journals/item_component.rb b/app/components/work_packages/activities_tab/journals/item_component.rb index 0030013b1fdd..af733a7474c4 100644 --- a/app/components/work_packages/activities_tab/journals/item_component.rb +++ b/app/components/work_packages/activities_tab/journals/item_component.rb @@ -75,7 +75,7 @@ def updated? end def has_unread_notifications? - journal.notifications.where(read_ian: false, recipient_id: User.current.id).any? + journal.has_unread_notifications_for_user?(User.current) end def notification_on_details? diff --git a/app/components/work_packages/activities_tab/journals/item_component/details.html.erb b/app/components/work_packages/activities_tab/journals/item_component/details.html.erb index 1398253b079c..e2ca551782ed 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/details.html.erb +++ b/app/components/work_packages/activities_tab/journals/item_component/details.html.erb @@ -14,23 +14,20 @@ when :only_comments render_empty_line(details_container) unless journal.notes.blank? && !journal.noop? when :only_changes - if journal.details.any? + if has_details? render_details_header(details_container) render_details(details_container) end else - if journal.details.any? + if has_details? if journal.notes.present? render_details(details_container) else render_details_header(details_container) render_details(details_container) end - elsif journal.notes.present? - render_details(details_container) else - # empty row to render the flex layout with its minimal height - render_empty_line(details_container) + render_details(details_container) end end end diff --git a/app/components/work_packages/activities_tab/journals/item_component/details.rb b/app/components/work_packages/activities_tab/journals/item_component/details.rb index 59f0c5ed4fbf..529fbcd6ab95 100644 --- a/app/components/work_packages/activities_tab/journals/item_component/details.rb +++ b/app/components/work_packages/activities_tab/journals/item_component/details.rb @@ -53,6 +53,14 @@ def wrapper_uniq_by journal.id end + def journal_details + @journal_details ||= journal.details + end + + def has_details? + @has_details ||= journal_details.any? + end + def render_details_header(details_container) details_container.with_row( flex_layout: true, @@ -223,7 +231,7 @@ def skip_rendering_details? end def render_journal_details(details_container_inner) - journal.details.each do |detail| + journal_details.each do |detail| rendered_detail = journal.render_detail(detail) render_single_detail(details_container_inner, rendered_detail) if rendered_detail.present? end diff --git a/app/components/work_packages/exports/generate/modal_dialog_component.html.erb b/app/components/work_packages/exports/generate/modal_dialog_component.html.erb new file mode 100644 index 000000000000..2ca7ef37b7e4 --- /dev/null +++ b/app/components/work_packages/exports/generate/modal_dialog_component.html.erb @@ -0,0 +1,57 @@ +<%= render(Primer::Alpha::Dialog.new( + title: I18n.t("pdf_generator.dialog.title"), + id: MODAL_ID, + size: :large +)) do |dialog| + dialog.with_header(variant: :large) + dialog.with_body do + primer_form_with( + url: generate_pdf_work_package_path(work_package), + data: { turbo: false }, + id: GENERATE_PDF_FORM_ID + ) do |form| + flex_layout do |modal_body| + generate_selects.each_with_index do |entry, index| + modal_body.with_row(mt: index == 0 ? 0 : 3) do + render(Primer::Alpha::Select.new( + name: entry[:name], + label: entry[:label], + caption: entry[:caption], + size: :medium, + input_width: :small, + value: entry[:options].find { |e| e[:default] }[:value]) + ) do |component| + entry[:options].each do |entry| + component.option(label: entry[:label], value: entry[:value]) + end + end + end + end + modal_body.with_row(mt: 3) do + render Primer::Alpha::TextField.new( + name: :header_text_right, + label: I18n.t("pdf_generator.dialog.header_right.label"), + caption: I18n.t("pdf_generator.dialog.header_right.caption"), + visually_hide_label: false, + value: default_header_text_right + ) + end + modal_body.with_row(mt: 3) do + render Primer::Alpha::TextField.new( + name: :footer_text_center, + label: I18n.t("pdf_generator.dialog.footer_center.label"), + caption: I18n.t("pdf_generator.dialog.footer_center.caption"), + visually_hide_label: false, + value: default_footer_text_center + ) + end + end + end + end + dialog.with_footer do + render(Primer::ButtonComponent.new(data: { "close-dialog-id": MODAL_ID })) { I18n.t(:button_cancel) } + render(Primer::ButtonComponent.new( + scheme: :primary, type: :submit, form: GENERATE_PDF_FORM_ID, + data: { "close-dialog-id": MODAL_ID })) { I18n.t("pdf_generator.dialog.submit") } + end +end %> diff --git a/app/components/work_packages/exports/generate/modal_dialog_component.rb b/app/components/work_packages/exports/generate/modal_dialog_component.rb new file mode 100644 index 000000000000..bf64944cabb6 --- /dev/null +++ b/app/components/work_packages/exports/generate/modal_dialog_component.rb @@ -0,0 +1,128 @@ +# frozen_string_literal: true + +# -- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +# ++ +require "text/hyphen" + +module WorkPackages + module Exports + module Generate + class ModalDialogComponent < ApplicationComponent + MODAL_ID = "op-work-package-generate-pdf-dialog" + GENERATE_PDF_FORM_ID = "op-work-packages-generate-pdf-dialog-form" + include OpTurbo::Streamable + include OpPrimer::ComponentHelpers + + attr_reader :work_package, :params + + def initialize(work_package:, params:) + super + + @work_package = work_package + @params = params + end + + def default_header_text_right + "#{work_package.type} ##{work_package.id}" + end + + def default_footer_text_center + work_package.subject + end + + def generate_selects + [ + { + name: "hyphenation", + label: I18n.t("pdf_generator.dialog.hyphenation.label"), + caption: I18n.t("pdf_generator.dialog.hyphenation.caption"), + options: hyphenation_options + }, + { + name: "paper_size", + label: I18n.t("pdf_generator.dialog.paper_size.label"), + caption: I18n.t("pdf_generator.dialog.paper_size.caption"), + options: paper_size_options + } + ] + end + + def hyphenation_options + # This is a list of languages that are supported by the hyphenation library + # https://rubygems.org/gems/text-hyphen + # The labels are the language names in the language itself (NOT to be put I18n) + supported_languages = [ + { label: "Català", value: "ca" }, + { label: "Dansk", value: "da" }, + { label: "Deutsch", value: "de" }, + { label: "Eesti", value: "et" }, + { label: "English (UK)", value: "en_uk" }, + { label: "English (USA)", value: "en_us" }, + { label: "Español", value: "es" }, + { label: "Euskara", value: "eu" }, + { label: "Français", value: "fr" }, + { label: "Gaeilge", value: "ga" }, + { label: "Hrvatski", value: "hr" }, + { label: "Indonesia", value: "id" }, + { label: "Interlingua", value: "ia" }, + { label: "Italiano", value: "it" }, + { label: "Magyar", value: "hu" }, + { label: "Melayu", value: "ms" }, + { label: "Nederlands", value: "nl" }, + { label: "Norsk", value: "no" }, + { label: "Polski", value: "pl" }, + { label: "Português", value: "pt" }, + { label: "Slovenčina", value: "sk" }, + { label: "Suomi", value: "fi" }, + { label: "Svenska", value: "sv" }, + { label: "Ísland", value: "is" }, + { label: "Čeština", value: "cs" }, + { label: "Монгол", value: "mn" }, + { label: "Русский", value: "ru" } + ] + + [{ value: "", label: "Off", default: true }].concat(supported_languages) + end + + def paper_size_options + [ + { label: "A4", value: "A4", default: true }, + { label: "A3", value: "A3" }, + { label: "A2", value: "A2" }, + { label: "A1", value: "A1" }, + { label: "A0", value: "A0" }, + { label: "Executive", value: "EXECUTIVE" }, + { label: "Folio", value: "FOLIO" }, + { label: "Letter", value: "LETTER" }, + { label: "Tabloid", value: "TABLOID" } + ] + end + end + end + end +end diff --git a/app/components/work_packages/hover_card_component.html.erb b/app/components/work_packages/hover_card_component.html.erb index a9f99822eb9d..5b11c6009870 100644 --- a/app/components/work_packages/hover_card_component.html.erb +++ b/app/components/work_packages/hover_card_component.html.erb @@ -1,16 +1,8 @@ <%= if @work_package.present? grid_layout('op-wp-hover-card', tag: :div) do |grid| - grid.with_area(:type, tag: :div) do - render(WorkPackages::HighlightedTypeComponent.new(work_package: @work_package, font_size: :small)) - end - - grid.with_area(:status, tag: :div) do - render WorkPackages::StatusBadgeComponent.new(status: @work_package.status) - end - - grid.with_area(:id, tag: :div) do - render(Primer::Beta::Text.new(font_size: :small,color: :muted)) { "##{@work_package.id}" } + grid.with_area(:info, tag: :div) do + render(WorkPackages::InfoLineComponent.new(work_package: @work_package)) end grid.with_area(:project, tag: :div) do diff --git a/app/components/work_packages/hover_card_component.sass b/app/components/work_packages/hover_card_component.sass index c28d444389a0..c44bc23ce480 100644 --- a/app/components/work_packages/hover_card_component.sass +++ b/app/components/work_packages/hover_card_component.sass @@ -1,11 +1,11 @@ .op-wp-hover-card display: grid align-items: center - grid-template-columns: auto auto auto auto 1fr + grid-template-columns: auto auto 1fr grid-template-rows: max-content 1fr auto grid-row-gap: calc(var(--stack-gap-condensed) / 2) grid-column-gap: var(--stack-gap-condensed) - grid-template-areas: "type id status project project project" "subject subject subject subject subject subject" "assignee assignee assignee assignee dates dates" + grid-template-areas: "info project project project" "subject subject subject subject" "assignee assignee dates dates" overflow: hidden &--project diff --git a/app/components/work_packages/info_line_component.html.erb b/app/components/work_packages/info_line_component.html.erb new file mode 100644 index 000000000000..a62250927f19 --- /dev/null +++ b/app/components/work_packages/info_line_component.html.erb @@ -0,0 +1,19 @@ +<%= + flex_layout do |flex| + flex.with_column(mr: 2) do + render(WorkPackages::HighlightedTypeComponent.new(work_package: @work_package, font_size: :small)) + end + flex.with_column(mr: 2) do + render(Primer::Beta::Link.new( + href: url_for(controller: "/work_packages", action: "show", id: @work_package), + title: @work_package.subject, + target: :_blank, + font_size: @font_size, + color: :muted + )) { "##{@work_package.id}" } + end + flex.with_column do + render WorkPackages::StatusBadgeComponent.new(status: @work_package.status) + end + end +%> diff --git a/app/components/work_packages/info_line_component.rb b/app/components/work_packages/info_line_component.rb new file mode 100644 index 000000000000..e4ea984ad648 --- /dev/null +++ b/app/components/work_packages/info_line_component.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class WorkPackages::InfoLineComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + + def initialize(work_package:, font_size: :small) + super + + @work_package = work_package + @font_size = font_size + end +end diff --git a/app/controllers/work_package_children_controller.rb b/app/controllers/work_package_children_controller.rb new file mode 100644 index 000000000000..2c95e3cc8a39 --- /dev/null +++ b/app/controllers/work_package_children_controller.rb @@ -0,0 +1,105 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageChildrenController < ApplicationController + include OpTurbo::ComponentStream + include OpTurbo::DialogStreamHelper + + before_action :set_work_package + + before_action :authorize # Short-circuit early if not authorized + + before_action :set_child, except: %i[new create] + before_action :set_relations, except: %i[new create] + + def new + component = WorkPackageRelationsTab::AddWorkPackageChildDialogComponent + .new(work_package: @work_package) + respond_with_dialog(component) + end + + def create + target_work_package_id = params[:work_package][:id] + target_child_work_package = WorkPackage.find(target_work_package_id) + + target_child_work_package.parent = @work_package + + if target_child_work_package.save + @children = @work_package.children.visible + @relations = @work_package.relations.visible + + component = WorkPackageRelationsTab::IndexComponent.new( + work_package: @work_package, + relations: @relations, + children: @children + ) + replace_via_turbo_stream(component:) + update_flash_message_via_turbo_stream( + message: I18n.t(:notice_successful_update), scheme: :success + ) + respond_with_turbo_streams + end + end + + def destroy + @child.parent = nil + + if @child.save + @work_package.reload + @children = @work_package.children.visible + component = WorkPackageRelationsTab::IndexComponent.new( + work_package: @work_package, + relations: @relations, + children: @children + ) + replace_via_turbo_stream(component:) + update_flash_message_via_turbo_stream( + message: I18n.t(:notice_successful_update), scheme: :success + ) + + respond_with_turbo_streams + end + end + + private + + def set_work_package + @work_package = WorkPackage.find(params[:work_package_id]) + @project = @work_package.project + end + + def set_child + @child = WorkPackage.find(params[:id]) + end + + def set_relations + @relations = @work_package.relations.visible + end +end diff --git a/app/controllers/work_package_relations_controller.rb b/app/controllers/work_package_relations_controller.rb new file mode 100644 index 000000000000..38095515fae5 --- /dev/null +++ b/app/controllers/work_package_relations_controller.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsController < ApplicationController + include OpTurbo::ComponentStream + include OpTurbo::DialogStreamHelper + + before_action :set_work_package + before_action :set_relation, except: %i[new create] + before_action :authorize + + def new + @relation = @work_package.relations.build( + from: @work_package, + relation_type: params[:relation_type] + ) + + respond_with_dialog( + WorkPackageRelationsTab::WorkPackageRelationDialogComponent + .new(work_package: @work_package, relation: @relation) + ) + end + + def edit + respond_with_dialog( + WorkPackageRelationsTab::WorkPackageRelationDialogComponent + .new(work_package: @work_package, relation: @relation) + ) + end + + def create + service_result = Relations::CreateService.new(user: current_user) + .call(create_relation_params) + + if service_result.success? + @work_package.reload + component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package, + relations: @work_package.relations, + children: @work_package.children) + replace_via_turbo_stream(component:) + respond_with_turbo_streams + else + respond_with_turbo_streams(status: :unprocessable_entity) + end + end + + def update + service_result = Relations::UpdateService + .new(user: current_user, + model: @relation) + .call(update_relation_params) + + if service_result.success? + @work_package.reload + component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package, + relations: @work_package.relations, + children: @work_package.children) + replace_via_turbo_stream(component:) + respond_with_turbo_streams + else + respond_with_turbo_streams(status: :unprocessable_entity) + end + end + + def destroy + service_result = Relations::DeleteService.new(user: current_user, model: @relation).call + + if service_result.success? + @children = WorkPackage.where(parent_id: @work_package.id) + @relations = @work_package + .relations + .reload + .includes(:to, :from) + + component = WorkPackageRelationsTab::IndexComponent.new(work_package: @work_package, + relations: @relations, + children: @children) + replace_via_turbo_stream(component:) + respond_with_turbo_streams + else + respond_with_turbo_streams(status: :unprocessable_entity) + end + end + + private + + def set_work_package + @work_package = WorkPackage.find(params[:work_package_id]) + end + + def set_relation + @relation = @work_package.relations.find(params[:id]) + end + + def create_relation_params + params.require(:relation) + .permit(:relation_type, :to_id, :description, :lag) + .merge(from_id: @work_package.id) + end + + def update_relation_params + params.require(:relation) + .permit(:description, :lag) + end +end diff --git a/app/controllers/work_package_relations_tab_controller.rb b/app/controllers/work_package_relations_tab_controller.rb new file mode 100644 index 000000000000..c8d9ab9ad75b --- /dev/null +++ b/app/controllers/work_package_relations_tab_controller.rb @@ -0,0 +1,66 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackageRelationsTabController < ApplicationController + include OpTurbo::ComponentStream + + before_action :set_work_package + before_action :authorize_global + + def index + @children = WorkPackage.where(parent_id: @work_package.id) + @relations = @work_package + .relations + .includes(:to, :from) + + component = WorkPackageRelationsTab::IndexComponent.new( + work_package: @work_package, + relations: @relations, + children: @children + ) + + respond_to do |format| + format.html do + render(component, layout: false) + end + format.turbo_stream do + replace_via_turbo_stream(component:) + render turbo_stream: turbo_streams + end + end + end + + private + + def set_work_package + @work_package = WorkPackage.find(params[:work_package_id]) + @project = @work_package.project # required for authorization via before_action + rescue ActiveRecord::RecordNotFound + render_404 + end +end diff --git a/app/controllers/work_packages/activities_tab_controller.rb b/app/controllers/work_packages/activities_tab_controller.rb index cfe19ecc31c8..2b824dc6b5e6 100644 --- a/app/controllers/work_packages/activities_tab_controller.rb +++ b/app/controllers/work_packages/activities_tab_controller.rb @@ -43,7 +43,8 @@ def index WorkPackages::ActivitiesTab::IndexComponent.new( work_package: @work_package, filter: @filter, - last_server_timestamp: get_current_server_timestamp + last_server_timestamp: get_current_server_timestamp, + deferred: ActiveRecord::Type::Boolean.new.cast(params[:deferred]) ), layout: false ) @@ -106,28 +107,33 @@ def cancel_edit end def create - call = create_journal_service_call + begin + call = create_journal_service_call - if call.success? && call.result - set_last_server_timestamp_to_headers - handle_successful_create_call(call) - else - handle_failed_create_call(call) # errors should be rendered in the form - @turbo_status = :bad_request + if call.success? && call.result + set_last_server_timestamp_to_headers + handle_successful_create_call(call) + else + handle_failed_create_or_update_call(call) + end + rescue StandardError => e + handle_internal_server_error(e) end respond_with_turbo_streams end def update - call = Journals::UpdateService.new(model: @journal, user: User.current).call( - notes: journal_params[:notes] - ) + begin + call = update_journal_service_call - if call.success? && call.result - update_item_show_component(journal: call.result, grouped_emoji_reactions: grouped_emoji_reactions_for_journal) - else - handle_failed_update_call(call) + if call.success? && call.result + update_item_show_component(journal: call.result, grouped_emoji_reactions: grouped_emoji_reactions_for_journal) + else + handle_failed_create_or_update_call(call) + end + rescue StandardError => e + handle_internal_server_error(e) end respond_with_turbo_streams @@ -182,19 +188,11 @@ def respond_with_error(error_message) # turbo_stream requests (tab is already rendered and an error occured in subsequent requests) are handled below format.turbo_stream do @turbo_status = :not_found - render_error_banner_via_turbo_stream(error_message) + render_error_flash_message_via_turbo_stream(message: error_message) end end end - def render_error_banner_via_turbo_stream(error_message) - update_via_turbo_stream( - component: WorkPackages::ActivitiesTab::ErrorStreamComponent.new( - error_message: - ) - ) - end - def find_work_package @work_package = WorkPackage.find(params[:work_package_id]) rescue ActiveRecord::RecordNotFound @@ -259,22 +257,22 @@ def perform_update_streams_from_last_update_timestamp end end - def handle_failed_create_call(call) - update_via_turbo_stream( - component: WorkPackages::ActivitiesTab::Journals::NewComponent.new( - work_package: @work_package, - journal: call.result, - form_hidden_initially: false - ) - ) - end - - def handle_failed_update_call(call) + def handle_failed_create_or_update_call(call) @turbo_status = if call.errors&.first&.type == :error_unauthorized :forbidden else :bad_request end + render_error_flash_message_via_turbo_stream( + message: call.errors&.full_messages&.join(", ") + ) + end + + def handle_internal_server_error(error) + @turbo_status = :internal_server_error + render_error_flash_message_via_turbo_stream( + message: error.message + ) end def replace_whole_tab @@ -306,6 +304,12 @@ def create_journal_service_call ### end + def update_journal_service_call + Journals::UpdateService.new(model: @journal, user: User.current).call( + notes: journal_params[:notes] + ) + end + def generate_time_based_update_streams(last_update_timestamp) journals = @work_package .journals @@ -371,6 +375,7 @@ def rerender_journals_with_updated_notification(journals, last_update_timestamp, # alternative approach in order to bypass the notification join issue in relation with the sequence_version query Notification .where(journal_id: journals.pluck(:id)) + .where(recipient_id: User.current.id) .where("notifications.updated_at > ?", last_update_timestamp) .find_each do |notification| update_item_show_component( diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index c17fec995245..81e3613a662e 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -37,13 +37,13 @@ class WorkPackagesController < ApplicationController accept_key_auth :index, :show before_action :authorize_on_work_package, - :project, only: :show + :project, only: %i[show generate_pdf_dialog generate_pdf] before_action :load_and_authorize_in_optional_project, :check_allowed_export, :protect_from_unauthorized_export, only: %i[index export_dialog] before_action :authorize, only: :show_conflict_flash_message - authorization_checked! :index, :show, :export_dialog + authorization_checked! :index, :show, :export_dialog, :generate_pdf_dialog, :generate_pdf before_action :load_and_validate_query, only: :index, unless: -> { request.format.html? } before_action :load_work_packages, only: :index, if: -> { request.format.atom? } @@ -93,6 +93,19 @@ def export_dialog respond_with_dialog WorkPackages::Exports::ModalDialogComponent.new(query: @query, project: @project, title: params[:title]) end + def generate_pdf_dialog + respond_with_dialog WorkPackages::Exports::Generate::ModalDialogComponent.new(work_package: work_package, params: params) + end + + def generate_pdf + exporter = WorkPackage::PDFExport::DocumentGenerator.new(work_package, params) + export = exporter.export! + send_data(export.content, type: export.mime_type, filename: export.title) + rescue ::Exports::ExportError => e + flash[:error] = e.message + redirect_back(fallback_location: work_package_path(work_package)) + end + def show_conflict_flash_message scheme = params[:scheme]&.to_sym || :danger diff --git a/app/forms/custom_fields/details_form.rb b/app/forms/custom_fields/details_form.rb index 096d55ced7dd..a73381e8cd33 100644 --- a/app/forms/custom_fields/details_form.rb +++ b/app/forms/custom_fields/details_form.rb @@ -61,12 +61,6 @@ class DetailsForm < ApplicationForm caption: I18n.t("custom_fields.instructions.is_filter") ) - details_form.check_box( - name: :searchable, - label: I18n.t("activerecord.attributes.custom_field.searchable"), - caption: I18n.t("custom_fields.instructions.searchable") - ) - details_form.submit(name: :submit, label: I18n.t(:button_save), scheme: :default) end end diff --git a/app/forms/custom_fields/hierarchy/item_form.rb b/app/forms/custom_fields/hierarchy/item_form.rb index 96f66e73aa73..50f9d41e8529 100644 --- a/app/forms/custom_fields/hierarchy/item_form.rb +++ b/app/forms/custom_fields/hierarchy/item_form.rb @@ -39,6 +39,7 @@ class ItemForm < ApplicationForm value: @target_item.label, visually_hide_label: true, required: true, + autofocus: true, placeholder: I18n.t("custom_fields.admin.items.placeholder.label"), validation_message: validation_message_for(:label) ) diff --git a/app/forms/projects/custom_fields/custom_field_mapping_form.rb b/app/forms/projects/custom_fields/custom_field_mapping_form.rb index f637ea059934..1a3f71f3dbe6 100644 --- a/app/forms/projects/custom_fields/custom_field_mapping_form.rb +++ b/app/forms/projects/custom_fields/custom_field_mapping_form.rb @@ -31,8 +31,7 @@ class CustomFieldMappingForm < ApplicationForm include OpPrimer::ComponentHelpers form do |form| - form.group(layout: :vertical) do |group| - group.project_autocompleter( + form.project_autocompleter( name: :id, label: Project.model_name.human, visually_hide_label: true, @@ -48,13 +47,12 @@ class CustomFieldMappingForm < ApplicationForm } ) - group.check_box( + form.check_box( name: :include_sub_projects, label: I18n.t(:label_include_sub_projects), checked: false, label_arguments: { class: "no-wrap" } ) - end end def initialize(project_mapping:) diff --git a/app/helpers/colors_helper.rb b/app/helpers/colors_helper.rb index ac61eaa323ff..a049b8a5abc0 100644 --- a/app/helpers/colors_helper.rb +++ b/app/helpers/colors_helper.rb @@ -49,33 +49,41 @@ def selected_color(colored_thing) ## def color_css Color.find_each do |color| - set_background_colors_for class_name: ".__hl_inline_color_#{color.id}_dot::before", hexcode: color.hexcode - set_foreground_colors_for class_name: ".__hl_inline_color_#{color.id}_text", hexcode: color.hexcode + set_background_colors_for(class_name: ".#{hl_inline_class('color', color)}_dot::before", color:) + set_foreground_colors_for(class_name: ".#{hl_inline_class('color', color)}_text", color:) end end # # Styles to display the color of attributes (type, status etc.) for example in the WP view ## - def resource_color_css(name, scope) + def resource_color_css(name, scope, inline_foreground: false) scope.includes(:color).find_each do |entry| color = entry.color if color.nil? - concat ".__hl_inline_#{name}_#{entry.id}::before { display: none }\n" + concat ".#{hl_inline_class(name, entry)}::before { display: none }\n" next end - if name === "type" - set_foreground_colors_for class_name: ".__hl_inline_#{name}_#{entry.id}", hexcode: color.hexcode + if inline_foreground + set_foreground_colors_for(class_name: ".#{hl_inline_class(name, entry)}", color:) else - set_background_colors_for class_name: ".__hl_inline_#{name}_#{entry.id}::before", hexcode: color.hexcode + set_background_colors_for(class_name: ".#{hl_inline_class(name, entry)}::before", color:) end - set_background_colors_for class_name: ".__hl_background_#{name}_#{entry.id}", hexcode: color.hexcode + set_background_colors_for(class_name: ".#{hl_background_class(name, entry)}", color:) end end + def hl_inline_class(name, model) + "__hl_inline_#{name}_#{model.id}" + end + + def hl_background_class(name, model) + "__hl_background_#{name}_#{model.id}" + end + def icon_for_color(color, options = {}) return unless color @@ -90,10 +98,10 @@ def color_by_variable(variable) DesignColor.find_by(variable:)&.hexcode end - def set_background_colors_for(class_name:, hexcode:) + def set_background_colors_for(class_name:, color:) mode = User.current.pref.theme.split("_", 2)[0] - concat "#{class_name} { #{default_color_styles(hexcode)} }" + concat "#{class_name} { #{default_color_styles(color.hexcode)} }" if mode == "dark" concat "#{class_name} { #{default_variables_dark} }" concat "#{class_name} { #{highlighted_background_dark} }" @@ -103,10 +111,10 @@ def set_background_colors_for(class_name:, hexcode:) end end - def set_foreground_colors_for(class_name:, hexcode:) + def set_foreground_colors_for(class_name:, color:) mode = User.current.pref.theme.split("_", 2)[0] - concat "#{class_name} { #{default_color_styles(hexcode)} }" + concat "#{class_name} { #{default_color_styles(color.hexcode)} }" if mode == "dark" concat "#{class_name} { #{default_variables_dark} }" concat "#{class_name} { #{highlighted_foreground_dark} }" diff --git a/app/helpers/custom_fields_helper.rb b/app/helpers/custom_fields_helper.rb index 229e80f835aa..1c9d15ae2087 100644 --- a/app/helpers/custom_fields_helper.rb +++ b/app/helpers/custom_fields_helper.rb @@ -68,7 +68,7 @@ def custom_field_tag(name, custom_value) # rubocop:disable Metrics/AbcSize,Metri field_name = "#{name}[custom_field_values][#{custom_field.id}]" field_id = "#{name}_custom_field_values_#{custom_field.id}" - field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format) + field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format) tag = case field_format.try(:edit_as) when "date" @@ -146,7 +146,7 @@ def custom_field_tag_with_label(name, custom_value) def custom_field_tag_for_bulk_edit(name, custom_field, project = nil) # rubocop:disable Metrics/AbcSize field_name = "#{name}[custom_field_values][#{custom_field.id}]" field_id = "#{name}_custom_field_values_#{custom_field.id}" - field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format) + field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format) case field_format.try(:edit_as) when "date" @@ -172,6 +172,19 @@ def custom_field_tag_for_bulk_edit(name, custom_field, project = nil) # rubocop: options_for_select(base_options + custom_field.possible_values_options(project)), id: field_id, multiple: custom_field.multi_value?) + when "hierarchy" + base_options = [[I18n.t(:label_no_change_option), ""]] + result = CustomFields::Hierarchy::HierarchicalItemService.new + .get_descendants(item: custom_field.hierarchy_root, include_self: false) + .either( + ->(items) { items }, + ->(_) { [] } + ) + options = base_options + result.map do |item| + label = item.short.present? ? "#{item.label} (#{item.short})" : item.label + [label, item.id] + end + styled_select_tag(field_name, options_for_select(options), id: field_id, multiple: custom_field.multi_value?) else styled_text_field_tag(field_name, "", id: field_id) end @@ -186,10 +199,7 @@ def show_value(custom_value) # Return a string used to display a custom value def format_value(value, custom_field) - custom_value = CustomValue.new(custom_field:, - value:) - - custom_value.formatted_value + CustomValue.new(custom_field:, value:).formatted_value end # Return an array of custom field formats which can be used in select_tag @@ -198,21 +208,24 @@ def custom_field_formats_for_select(custom_field) format.name == "hierarchy" && !OpenProject::FeatureDecisions.custom_field_of_type_hierarchy_active? end - OpenProject::CustomFieldFormat - .all_for_field(custom_field) - .sort_by(&:order) - .reject { |format| format.label.nil? } - .reject(&hierarchy_if_deactivated) - .map do |custom_field_format| - [label_for_custom_field_format(custom_field_format.name), custom_field_format.name] - end + OpenProject::CustomFieldFormat.all_for_field(custom_field) + .sort_by(&:order) + .reject { |format| format.label.nil? } + .reject(&hierarchy_if_deactivated) + .map do |custom_field_format| + [label_for_custom_field_format(custom_field_format.name), custom_field_format.name] + end end def label_for_custom_field_format(format_string) - format = OpenProject::CustomFieldFormat.find_by_name(format_string) + format = OpenProject::CustomFieldFormat.find_by(name: format_string) + return "" if format.nil? - if format - format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label) - end + label = format.label.is_a?(Proc) ? format.label.call : I18n.t(format.label) + + show_enterprise_text = format_string == "hierarchy" && !EnterpriseToken.allows_to?(:custom_field_hierarchies) + suffix = show_enterprise_text ? " (#{I18n.t(:label_enterprise_addon)})" : "" + + "#{label}#{suffix}" end end diff --git a/app/models/attachment.rb b/app/models/attachment.rb index b1d7ae1942c3..f1eb8ad9cae3 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -163,8 +163,12 @@ def is_pdf? content_type == "application/pdf" end + def is_html? + content_type == "text/html" + end + def is_text? - content_type.match?(/\Atext\/.+/) + content_type.match?(/\Atext\/.+/) && !is_html? end def is_diff? diff --git a/app/models/custom_actions/actions/custom_field.rb b/app/models/custom_actions/actions/custom_field.rb index c1b0a82eba89..374b3406218a 100644 --- a/app/models/custom_actions/actions/custom_field.rb +++ b/app/models/custom_actions/actions/custom_field.rb @@ -49,7 +49,7 @@ def apply(work_package) def self.all WorkPackageCustomField - .order(:name) + .usable_as_custom_action .map do |cf| create_subclass(cf) end diff --git a/app/models/custom_field/order_statements.rb b/app/models/custom_field/order_statements.rb index 98c46c8c8167..0e4da57f8f52 100644 --- a/app/models/custom_field/order_statements.rb +++ b/app/models/custom_field/order_statements.rb @@ -27,152 +27,151 @@ #++ module CustomField::OrderStatements - # Returns a ORDER BY clause that can used to sort customized - # objects by their value of the custom field. - # Returns false, if the custom field can not be used for sorting. - def order_statements + # Returns the expression to use in ORDER BY clause to sort objects by their + # value of the custom field. + def order_statement + case field_format + when "string", "date", "bool", "link", "int", "float", "list", "user", "version", "hierarchy" + "cf_order_#{id}.value" + end + end + + # Returns the join statement that is required to sort objects by their value + # of the custom field. + def order_join_statement case field_format - when "list" - [order_by_list_sql] when "string", "date", "bool", "link" - [coalesce_select_custom_value_as_string] - when "int", "float" - # Make the database cast values into numeric - # Postgresql will raise an error if a value can not be casted! - # CustomValue validations should ensure that it doesn't occur - [select_custom_value_as_decimal] + join_for_order_by_string_sql + when "int" + join_for_order_by_int_sql + when "float" + join_for_order_by_float_sql + when "list" + join_for_order_by_list_sql when "user" - [order_by_user_sql] + join_for_order_by_user_sql when "version" - [order_by_version_sql] + join_for_order_by_version_sql + when "hierarchy" + join_for_order_by_hierarchy_sql end end - ## - # Returns the null handling for the given direction - def null_handling(asc) - return unless %w[int float].include?(field_format) - + # Returns the ORDER BY option defining order of objects without value for the + # custom field. + def order_null_handling(asc) null_direction = asc ? "FIRST" : "LAST" Arel.sql("NULLS #{null_direction}") end - # Returns the grouping result - # which differ for multi-value select fields, - # because in this case we do want the primary CV values + # Returns the expression to use in GROUP BY (and ORDER BY) clause to group + # objects by their value of the custom field. def group_by_statement - return order_statements unless field_format == "list" + return unless can_be_used_for_grouping? - if multi_value? - # We want to return the internal IDs in the case of grouping - select_custom_values_as_group - else - coalesce_select_custom_value_as_string - end + order_statement end - private - - def coalesce_select_custom_value_as_string - # COALESCE is here to make sure that blank and NULL values are sorted equally - <<-SQL.squish - COALESCE(#{select_custom_value_as_string}, '') - SQL - end + # Returns the expression to use in SELECT clause if it differs from one used + # to group by + def group_by_select_statement + return unless field_format == "list" - def select_custom_value_as_string - <<-SQL.squish - ( - SELECT cv_sort.value - FROM #{CustomValue.quoted_table_name} cv_sort - WHERE #{cv_sort_only_custom_field_condition_sql} - LIMIT 1 - ) - SQL + # MIN needed to not add this column to group by, ANY_VALUE can be used when + # minimum required PostgreSQL becomes 16 + "MIN(cf_order_#{id}.ids)" end - def select_custom_values_as_group - <<-SQL.squish - COALESCE( - ( - SELECT string_agg(cv_sort.value, '.') - FROM #{CustomValue.quoted_table_name} cv_sort - WHERE #{cv_sort_only_custom_field_condition_sql} - AND cv_sort.value IS NOT NULL - ), - '' - ) - SQL - end + # Returns the join statement that is required to group objects by their value + # of the custom field. + def group_by_join_statement + return unless can_be_used_for_grouping? - def select_custom_value_as_decimal - <<-SQL.squish - ( - SELECT CAST(cv_sort.value AS decimal(60,3)) - FROM #{CustomValue.quoted_table_name} cv_sort - WHERE #{cv_sort_only_custom_field_condition_sql} - AND cv_sort.value <> '' - AND cv_sort.value IS NOT NULL - LIMIT 1 - ) - SQL + order_join_statement end - def order_by_list_sql - columns = multi_value? ? "array_agg(co_sort.position ORDER BY co_sort.position)" : "co_sort.position" - limit = multi_value? ? "" : "LIMIT 1" + private + def can_be_used_for_grouping? = field_format.in?(%w[list date bool int float string link]) + + # Template for all the join statements. + # + # For single value custom fields the join ensures single value for every + # customized object using DISTINCT ON and selecting first value by id of + # custom value: + # + # LEFT OUTER JOIN ( + # SELECT DISTINCT ON (cv.customized_id), cv.customized_id, xxx "value" + # FROM custom_values cv + # WHERE … + # ORDER BY cv.customized_id, cv.id + # ) cf_order_NNN ON cf_order_NNN.customized_id = … + # + # For multi value custom fields the GROUP BY and value aggregate function + # ensure single value for every customized object: + # + # LEFT OUTER JOIN ( + # SELECT cv.customized_id, ARRAY_AGG(xxx ORDERY BY yyy) "value" + # FROM custom_values cv + # WHERE … + # GROUP BY cv.customized_id, cv.id + # ) cf_order_NNN ON cf_order_NNN.customized_id = … + # + def join_for_order_sql(value:, add_select: nil, join: nil, multi_value: false) <<-SQL.squish - ( - SELECT #{columns} - FROM #{CustomOption.quoted_table_name} co_sort - INNER JOIN #{CustomValue.quoted_table_name} cv_sort - ON cv_sort.value IS NOT NULL AND cv_sort.value != '' AND co_sort.id = cv_sort.value::bigint - WHERE #{cv_sort_only_custom_field_condition_sql} - #{limit} - ) + LEFT OUTER JOIN ( + SELECT + #{multi_value ? '' : 'DISTINCT ON (cv.customized_id)'} + cv.customized_id + , #{value} "value" + #{", #{add_select}" if add_select} + FROM #{CustomValue.quoted_table_name} cv + #{join} + WHERE cv.customized_type = #{CustomValue.connection.quote(self.class.customized_class.name)} + AND cv.custom_field_id = #{id} + AND cv.value IS NOT NULL + AND cv.value != '' + #{multi_value ? 'GROUP BY cv.customized_id' : 'ORDER BY cv.customized_id, cv.id'} + ) cf_order_#{id} + ON cf_order_#{id}.customized_id = #{self.class.customized_class.quoted_table_name}.id SQL end - def order_by_user_sql - columns_array = "ARRAY[cv_user.lastname, cv_user.firstname, cv_user.mail]" + def join_for_order_by_string_sql = join_for_order_sql(value: "cv.value") - columns = multi_value? ? "array_agg(#{columns_array} ORDER BY #{columns_array})" : columns_array - limit = multi_value? ? "" : "LIMIT 1" + def join_for_order_by_int_sql = join_for_order_sql(value: "cv.value::decimal(60)") - <<-SQL.squish - ( - SELECT #{columns} - FROM #{User.quoted_table_name} cv_user - INNER JOIN #{CustomValue.quoted_table_name} cv_sort - ON cv_sort.value IS NOT NULL AND cv_sort.value != '' AND cv_user.id = cv_sort.value::bigint - WHERE #{cv_sort_only_custom_field_condition_sql} - #{limit} - ) - SQL + def join_for_order_by_float_sql = join_for_order_sql(value: "cv.value::double precision") + + def join_for_order_by_list_sql + join_for_order_sql( + value: multi_value? ? "ARRAY_AGG(co.position ORDER BY co.position)" : "co.position", + add_select: "#{multi_value? ? "ARRAY_TO_STRING(ARRAY_AGG(cv.value ORDER BY co.position), '.')" : 'cv.value'} ids", + join: "INNER JOIN #{CustomOption.quoted_table_name} co ON co.id = cv.value::bigint", + multi_value: + ) end - def order_by_version_sql - columns = multi_value? ? "array_agg(cv_version.name ORDER BY cv_version.name)" : "cv_version.name" - limit = multi_value? ? "" : "LIMIT 1" + def join_for_order_by_user_sql + columns_array = "ARRAY[users.lastname, users.firstname, users.mail]" - <<-SQL.squish - ( - SELECT #{columns} - FROM #{Version.quoted_table_name} cv_version - INNER JOIN #{CustomValue.quoted_table_name} cv_sort - ON cv_sort.value IS NOT NULL AND cv_sort.value != '' AND cv_version.id = cv_sort.value::bigint - WHERE #{cv_sort_only_custom_field_condition_sql} - #{limit} - ) - SQL + join_for_order_sql( + value: multi_value? ? "ARRAY_AGG(#{columns_array} ORDER BY #{columns_array})" : columns_array, + join: "INNER JOIN #{User.quoted_table_name} users ON users.id = cv.value::bigint", + multi_value: + ) end - def cv_sort_only_custom_field_condition_sql - <<-SQL.squish - cv_sort.customized_type='#{self.class.customized_class.name}' - AND cv_sort.customized_id=#{self.class.customized_class.quoted_table_name}.id - AND cv_sort.custom_field_id=#{id} - SQL + def join_for_order_by_version_sql + join_for_order_sql( + value: multi_value? ? "array_agg(versions.name ORDER BY versions.name)" : "versions.name", + join: "INNER JOIN #{Version.quoted_table_name} versions ON versions.id = cv.value::bigint", + multi_value: + ) + end + + def join_for_order_by_hierarchy_sql + table_name = CustomField::Hierarchy::Item.quoted_table_name + join_for_order_sql(value: "item.label", join: "INNER JOIN #{table_name} item ON item.id = cv.value::bigint") end end diff --git a/app/models/custom_value.rb b/app/models/custom_value.rb index 5208e36cc605..60e6f317e019 100644 --- a/app/models/custom_value.rb +++ b/app/models/custom_value.rb @@ -59,7 +59,7 @@ def value=(val) def strategy @strategy ||= begin format = custom_field&.field_format || "empty" - OpenProject::CustomFieldFormat.find_by_name(format).formatter.new(self) # rubocop:disable Rails/DynamicFindBy + OpenProject::CustomFieldFormat.find_by(name: format).formatter.new(self) end end diff --git a/app/models/custom_value/hierarchy_strategy.rb b/app/models/custom_value/hierarchy_strategy.rb index 86d63d5145bb..2ce05be7336b 100644 --- a/app/models/custom_value/hierarchy_strategy.rb +++ b/app/models/custom_value/hierarchy_strategy.rb @@ -48,6 +48,8 @@ def ar_object(value) item = CustomField::Hierarchy::Item.find_by(id: value.to_s) if item.nil? "#{value} #{I18n.t(:label_not_found)}" + elsif item.short.present? + "#{item.label} (#{item.short})" else item.label end diff --git a/app/models/custom_value/link_strategy.rb b/app/models/custom_value/link_strategy.rb index 3e6951d6dec7..091c01de5d63 100644 --- a/app/models/custom_value/link_strategy.rb +++ b/app/models/custom_value/link_strategy.rb @@ -28,7 +28,7 @@ class CustomValue::LinkStrategy < CustomValue::FormatStrategy def typed_value - formatted_value + formatted_value if value.present? end def parse_value(val) diff --git a/app/models/journal.rb b/app/models/journal.rb index 04f66834916a..95da1c3ed52a 100644 --- a/app/models/journal.rb +++ b/app/models/journal.rb @@ -177,6 +177,16 @@ def has_cause? cause_type.present? end + def has_unread_notifications_for_user?(user) + # we optionally set the instance variable @unread_notifications in the ActivityEagerLoadingWrapper + # in order to avoid N+1 queries + if instance_variable_defined?(:@unread_notifications) + @unread_notifications&.any? { |notification| notification.recipient_id == user.id } + else + notifications.where(read_ian: false, recipient_id: user.id).any? + end + end + private def has_file_links? diff --git a/app/models/journal/base_journal.rb b/app/models/journal/base_journal.rb index ea9cd0fa0941..826b7c627671 100644 --- a/app/models/journal/base_journal.rb +++ b/app/models/journal/base_journal.rb @@ -37,7 +37,7 @@ def journaled_attributes end def self.journaled_attributes - @journaled_attributes ||= column_names.map(&:to_sym) - excluded_attributes + @journaled_attributes ||= columns.reject(&:virtual?).map { |col| col.name.to_sym } - excluded_attributes end def self.excluded_attributes diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb index 34d36be2cfc4..ba22823578ba 100644 --- a/app/models/permitted_params.rb +++ b/app/models/permitted_params.rb @@ -474,7 +474,6 @@ def self.permitted_attributes :searchable, :admin_only, :default_value, - :possible_values, :multi_value, :content_right_to_left, :custom_field_section_id, diff --git a/app/models/project.rb b/app/models/project.rb index cb377c6b5ad2..89191c1eba8b 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -86,6 +86,7 @@ class Project < ApplicationRecord has_many :notification_settings, dependent: :destroy has_many :project_storages, dependent: :destroy, class_name: "Storages::ProjectStorage" has_many :storages, through: :project_storages + has_many :life_cycle_steps, class_name: "Project::LifeCycleStep", dependent: :destroy store_attribute :settings, :deactivate_work_package_attachments, :boolean @@ -174,7 +175,7 @@ class Project < ApplicationRecord scopes :activated_time_activity, :visible_with_activated_time_activity - enum status_code: { + enum :status_code, { on_track: 0, at_risk: 1, off_track: 2, diff --git a/app/models/project/gate.rb b/app/models/project/gate.rb new file mode 100644 index 000000000000..46ee6fffdb74 --- /dev/null +++ b/app/models/project/gate.rb @@ -0,0 +1,42 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::Gate < Project::LifeCycleStep + alias_attribute :date, :start_date + + # This ensures the type cannot be changed after initialising the class. + validates :type, inclusion: { in: %w[Project::Gate], message: :must_be_a_gate } + validates :date, presence: true + validate :end_date_not_allowed + + def end_date_not_allowed + if end_date.present? + errors.add(:base, :end_date_not_allowed) + end + end +end diff --git a/app/models/project/gate_definition.rb b/app/models/project/gate_definition.rb new file mode 100644 index 000000000000..a51561075728 --- /dev/null +++ b/app/models/project/gate_definition.rb @@ -0,0 +1,35 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::GateDefinition < Project::LifeCycleStepDefinition + has_many :gates, # Alias for life_cycle_steps + class_name: "Project::Gate", + foreign_key: :definition_id, + inverse_of: :definition, + dependent: :destroy +end diff --git a/app/models/project/life_cycle_step.rb b/app/models/project/life_cycle_step.rb new file mode 100644 index 000000000000..dfa4b11efda9 --- /dev/null +++ b/app/models/project/life_cycle_step.rb @@ -0,0 +1,49 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::LifeCycleStep < ApplicationRecord + belongs_to :project, optional: false + belongs_to :definition, + optional: false, + class_name: "Project::LifeCycleStepDefinition" + has_many :work_packages, inverse_of: :project_life_cycle_step, dependent: :nullify + + attr_readonly :definition_id, :type + + validates :type, inclusion: { in: %w[Project::Stage Project::Gate], message: :must_be_a_stage_or_gate } + + def initialize(*args) + if instance_of? Project::LifeCycleStep + # Do not allow directly instantiating this class + raise NotImplementedError, "Cannot instantiate the base Project::LifeCycleStep class directly. " \ + "Use Project::Stage or Project::Gate instead." + end + + super + end +end diff --git a/app/models/project/life_cycle_step_definition.rb b/app/models/project/life_cycle_step_definition.rb new file mode 100644 index 000000000000..d511cc284cc4 --- /dev/null +++ b/app/models/project/life_cycle_step_definition.rb @@ -0,0 +1,54 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::LifeCycleStepDefinition < ApplicationRecord + has_many :life_cycle_steps, + class_name: "Project::LifeCycleStep", + foreign_key: :definition_id, + inverse_of: :definition, + dependent: :destroy + has_many :projects, through: :life_cycle_steps + belongs_to :color, optional: false + + validates :name, presence: true + validates :type, inclusion: { in: %w[Project::StageDefinition Project::GateDefinition], message: :must_be_a_stage_or_gate } + + attr_readonly :type + + acts_as_list + + def initialize(*args) + if instance_of? Project::LifeCycleStepDefinition + # Do not allow directly instantiating this class + raise NotImplementedError, "Cannot instantiate the base Project::LifeCycleStepDefinition class directly. " \ + "Use Project::StageDefinition or Project::GateDefinition instead." + end + + super + end +end diff --git a/app/models/project/stage.rb b/app/models/project/stage.rb new file mode 100644 index 000000000000..b49ca7787b71 --- /dev/null +++ b/app/models/project/stage.rb @@ -0,0 +1,33 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::Stage < Project::LifeCycleStep + # This ensures the type cannot be changed after initialising the class. + validates :type, inclusion: { in: %w[Project::Stage], message: :must_be_a_stage } + validates :start_date, :end_date, presence: true +end diff --git a/app/models/project/stage_definition.rb b/app/models/project/stage_definition.rb new file mode 100644 index 000000000000..91ae98584def --- /dev/null +++ b/app/models/project/stage_definition.rb @@ -0,0 +1,35 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class Project::StageDefinition < Project::LifeCycleStepDefinition + has_many :stages, # Alias for life_cycle_steps + class_name: "Project::Stage", + foreign_key: :definition_id, + inverse_of: :definition, + dependent: :destroy +end diff --git a/app/models/projects.rb b/app/models/projects.rb new file mode 100644 index 000000000000..27b2504bd994 --- /dev/null +++ b/app/models/projects.rb @@ -0,0 +1,5 @@ +module Projects + def self.table_name_prefix + "projects_" + end +end diff --git a/app/models/queries/filters.rb b/app/models/queries/filters.rb index 293f2469f206..503c69862dba 100644 --- a/app/models/queries/filters.rb +++ b/app/models/queries/filters.rb @@ -40,7 +40,8 @@ module Queries::Filters search: Queries::Filters::Strategies::Search, float: Queries::Filters::Strategies::Float, inexistent: Queries::Filters::Strategies::Inexistent, - empty_value: Queries::Filters::Strategies::EmptyValue + empty_value: Queries::Filters::Strategies::EmptyValue, + hierarchy: Queries::Filters::Strategies::Hierarchy }.freeze ## diff --git a/app/models/queries/filters/shared/custom_field_filter.rb b/app/models/queries/filters/shared/custom_field_filter.rb index 1e3cea7c7d58..45a9c3831e5f 100644 --- a/app/models/queries/filters/shared/custom_field_filter.rb +++ b/app/models/queries/filters/shared/custom_field_filter.rb @@ -70,29 +70,12 @@ def create!(name:, **) ## # Create a filter instance for the given custom field def from_custom_field!(custom_field:, **) - constant_name = subfilter_module(custom_field) - clazz = "::Queries::Filters::Shared::CustomFields::#{constant_name}".constantize - clazz.create!(custom_field:, custom_field_context:, **) + subfilter_class(custom_field).create!(custom_field:, custom_field_context:, **) rescue NameError => e Rails.logger.error "Failed to constantize custom field filter for #{name}. #{e}" raise ::Queries::Filters::InvalidError end - ## - # Get the subfilter class name for the given custom field - def subfilter_module(custom_field) - case custom_field.field_format - when "user" - :User - when "list", "version" - :ListOptional - when "bool" - :Bool - else - :Base - end - end - def all_custom_fields key = ["Queries::Filters::Shared::CustomFieldFilter", custom_field_context.custom_field_class, @@ -102,5 +85,22 @@ def all_custom_fields custom_field_context.custom_field_class.all.to_a end end + + private + + def subfilter_class(custom_field) + case custom_field.field_format + when "user" + ::Queries::Filters::Shared::CustomFields::User + when "list", "version" + ::Queries::Filters::Shared::CustomFields::ListOptional + when "hierarchy" + ::Queries::Filters::Shared::CustomFields::Hierarchy + when "bool" + ::Queries::Filters::Shared::CustomFields::Bool + else + ::Queries::Filters::Shared::CustomFields::Base + end + end end end diff --git a/app/models/queries/filters/shared/custom_fields/base.rb b/app/models/queries/filters/shared/custom_fields/base.rb index 1a6bc559cf71..07cf1b0cb30f 100644 --- a/app/models/queries/filters/shared/custom_fields/base.rb +++ b/app/models/queries/filters/shared/custom_fields/base.rb @@ -89,6 +89,8 @@ def type :text when "date" :date + when "hierarchy" + :hierarchy else :string end diff --git a/app/models/queries/filters/shared/custom_fields/hierarchy.rb b/app/models/queries/filters/shared/custom_fields/hierarchy.rb new file mode 100644 index 000000000000..81538bc4bdb4 --- /dev/null +++ b/app/models/queries/filters/shared/custom_fields/hierarchy.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module Queries + module Filters + module Shared + module CustomFields + class Hierarchy < Base + def ar_object_filter? + true + end + + def value_objects + CustomField::Hierarchy::Item + .where(id: @values) + .map { |item| HierarchyItemFilterAdapter.new(item:) } + end + end + + class HierarchyItemFilterAdapter + attr_reader :name + + delegate :id, to: :item + + def initialize(item:) + @item = item + @name = item.label + end + + private + + attr_accessor :item + end + end + end + end +end diff --git a/app/models/queries/filters/strategies/hierarchy.rb b/app/models/queries/filters/strategies/hierarchy.rb new file mode 100644 index 000000000000..158ff5ab0c63 --- /dev/null +++ b/app/models/queries/filters/strategies/hierarchy.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module Queries + module Filters + module Strategies + class Hierarchy < BaseStrategy + self.supported_operators = %w[= ! eq_with_descendants] + self.default_operator = "=" + + def operator_map + super.dup.tap do |super_value| + super_value["eq_with_descendants"] = ::Queries::Operators::CustomFields::Hierarchies::EqualsWithDescendants + end + end + end + end + end +end diff --git a/app/models/queries/operators/custom_fields/hierarchies/equals_with_descendants.rb b/app/models/queries/operators/custom_fields/hierarchies/equals_with_descendants.rb new file mode 100644 index 000000000000..941df671456f --- /dev/null +++ b/app/models/queries/operators/custom_fields/hierarchies/equals_with_descendants.rb @@ -0,0 +1,49 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module Queries + module Operators + module CustomFields + module Hierarchies + class EqualsWithDescendants < Base + label "equals_with_descendants" + set_symbol "eq_with_descendants" + + def self.sql_for_field(values, db_table, db_field) + items = CustomField::Hierarchy::Item.find(values) + service = ::CustomFields::Hierarchy::HierarchicalItemService.new + + actual_values = items.map { |item| service.get_descendants(item:).value! }.flatten.map(&:id).uniq + + Equals.sql_for_field(actual_values, db_table, db_field) + end + end + end + end + end +end diff --git a/app/models/queries/projects/orders/custom_field_order.rb b/app/models/queries/projects/orders/custom_field_order.rb index 30aa9e3b4558..b7ad4e3cf9f7 100644 --- a/app/models/queries/projects/orders/custom_field_order.rb +++ b/app/models/queries/projects/orders/custom_field_order.rb @@ -58,10 +58,16 @@ def available? private def order(scope) - joined_statement = custom_field.order_statements.map do |statement| - Arel.sql("#{statement} #{direction}") + if (join_statement = custom_field.order_join_statement) + scope = scope.joins(join_statement) end - scope.order(joined_statement) + order_statement = "#{custom_field.order_statement} #{direction}" + + if (null_handling = custom_field.order_null_handling(direction == :asc)) + order_statement = "#{order_statement} #{null_handling}" + end + + scope.order(Arel.sql(order_statement)) end end diff --git a/app/models/queries/work_packages/selects/custom_field_select.rb b/app/models/queries/work_packages/selects/custom_field_select.rb index c6e2a107d5da..6120e1111035 100644 --- a/app/models/queries/work_packages/selects/custom_field_select.rb +++ b/app/models/queries/work_packages/selects/custom_field_select.rb @@ -32,21 +32,20 @@ def initialize(custom_field) @cf = custom_field - set_name! - set_sortable! - set_groupable! - set_summable! - end - - def groupable_custom_field?(custom_field) - %w(list date bool int).include?(custom_field.field_format) + @name = custom_field.column_name.to_sym + @sortable = custom_field.order_statement + @sortable_join = custom_field.order_join_statement + @groupable = custom_field.group_by_statement + @groupable_join = custom_field.group_by_join_statement + @groupable_select = custom_field.group_by_select_statement + @summable = summable_statement end def caption @cf.name end - delegate :null_handling, to: :custom_field + def null_handling(...) = custom_field.order_null_handling(...) def custom_field @cf @@ -68,32 +67,6 @@ def self.instances(context = nil) private - def set_name! - self.name = custom_field.column_name.to_sym - end - - def set_sortable! - self.sortable = custom_field.order_statements || false - end - - def set_groupable! - self.groupable = custom_field.group_by_statement if groupable_custom_field?(custom_field) - self.groupable ||= false - end - - def set_summable! - self.summable = if %w(float int).include?(custom_field.field_format) - select = summable_select_statement - - ->(query, grouped) { - Queries::WorkPackages::Selects::WorkPackageSelect - .scoped_column_sum(summable_scope(query), select, grouped && query.group_by_statement) - } - else - false - end - end - def summable_scope(query) WorkPackage .where(id: query.results.work_packages) @@ -105,9 +78,22 @@ def summable_scope(query) def summable_select_statement if custom_field.field_format == "int" - "COALESCE(SUM(value::BIGINT)::BIGINT, 0) #{name}" + "COALESCE(SUM(#{CustomValue.quoted_table_name}.value::BIGINT)::BIGINT, 0) #{name}" + else + "COALESCE(ROUND(SUM(#{CustomValue.quoted_table_name}.value::NUMERIC), 2)::FLOAT, 0.0) #{name}" + end + end + + def summable_statement + if %w[float int].include?(custom_field.field_format) + select = summable_select_statement + + ->(query, grouped) { + Queries::WorkPackages::Selects::WorkPackageSelect + .scoped_column_sum(summable_scope(query), select, grouped:, query:) + } else - "COALESCE(ROUND(SUM(value::NUMERIC), 2)::FLOAT, 0.0) #{name}" + false end end end diff --git a/app/models/queries/work_packages/selects/property_select.rb b/app/models/queries/work_packages/selects/property_select.rb index c73db63aaeff..0a7da338fe3b 100644 --- a/app/models/queries/work_packages/selects/property_select.rb +++ b/app/models/queries/work_packages/selects/property_select.rb @@ -130,15 +130,12 @@ def caption shared_with_users: { sortable: false, groupable: false - } } def self.instances(_context = nil) - property_selects.filter_map do |name, options| - next unless !options[:if] || options[:if].call - - new(name, options.except(:if)) + property_selects.map do |name, options| + new(name, options) end end end diff --git a/app/models/queries/work_packages/selects/relation_of_type_select.rb b/app/models/queries/work_packages/selects/relation_of_type_select.rb index eb6809cec69c..f7dd9d4d668e 100644 --- a/app/models/queries/work_packages/selects/relation_of_type_select.rb +++ b/app/models/queries/work_packages/selects/relation_of_type_select.rb @@ -28,12 +28,9 @@ class Queries::WorkPackages::Selects::RelationOfTypeSelect < Queries::WorkPackages::Selects::RelationSelect def initialize(type) - self.type = type - super(name) - end + super(:"relations_of_type_#{type[:sym]}") - def name - :"relations_of_type_#{type[:sym]}" + @type = type end def sym diff --git a/app/models/queries/work_packages/selects/relation_select.rb b/app/models/queries/work_packages/selects/relation_select.rb index c12f7663eb2e..224b1e58f743 100644 --- a/app/models/queries/work_packages/selects/relation_select.rb +++ b/app/models/queries/work_packages/selects/relation_select.rb @@ -27,7 +27,7 @@ #++ class Queries::WorkPackages::Selects::RelationSelect < Queries::WorkPackages::Selects::WorkPackageSelect - attr_accessor :type + attr_reader :type def self.granted_by_enterprise_token EnterpriseToken.allows_to?(:work_package_query_relation_columns) diff --git a/app/models/queries/work_packages/selects/relation_to_type_select.rb b/app/models/queries/work_packages/selects/relation_to_type_select.rb index cd6ddcd432fc..7744ed717f10 100644 --- a/app/models/queries/work_packages/selects/relation_to_type_select.rb +++ b/app/models/queries/work_packages/selects/relation_to_type_select.rb @@ -28,14 +28,9 @@ class Queries::WorkPackages::Selects::RelationToTypeSelect < Queries::WorkPackages::Selects::RelationSelect def initialize(type) - super + super(:"relations_to_type_#{type.id}") - set_name! type - self.type = type - end - - def set_name!(type) - self.name = :"relations_to_type_#{type.id}" + @type = type end def caption diff --git a/app/models/queries/work_packages/selects/work_package_select.rb b/app/models/queries/work_packages/selects/work_package_select.rb index a3ffe42aa3b6..9b9603518367 100644 --- a/app/models/queries/work_packages/selects/work_package_select.rb +++ b/app/models/queries/work_packages/selects/work_package_select.rb @@ -27,19 +27,15 @@ #++ class Queries::WorkPackages::Selects::WorkPackageSelect - attr_accessor :highlightable, - :name, - :sortable_join, - :summable, - :default_order, - :association - alias_method :highlightable?, :highlightable - - attr_reader :groupable, - :sortable, - :displayable - - attr_writer :null_handling, + attr_reader :highlightable, + :name, + :sortable_join, + :groupable_join, + :groupable_select, + :summable, + :default_order, + :association, + :null_handling, :summable_select, :summable_work_packages_select @@ -51,17 +47,17 @@ def self.select_group_by(group_by_statement) group_by = group_by_statement group_by = group_by.first if group_by.is_a?(Array) - "#{group_by} id" + "#{group_by} group_id" end - def self.scoped_column_sum(scope, select, group_by) - scope = scope - .except(:order, :select) + def self.scoped_column_sum(scope, select, grouped:, query:) + scope = scope.except(:order, :select) - if group_by + if grouped scope - .group(group_by) - .select(select_group_by(group_by), select) + .joins(query.group_by_join_statement) + .group(query.group_by_statement) + .select(select_group_by(query.group_by_select), select) else scope .select(select) @@ -76,31 +72,25 @@ def null_handling(_asc) @null_handling end - def groupable=(value) - @groupable = name_or_value_or_false(value) + def displayable + @displayable.nil? ? true : @displayable end - def sortable=(value) - @sortable = name_or_value_or_false(value) + def sortable + name_or_value_or_false(@sortable) end - def displayable=(value) - @displayable = value.nil? ? true : value + def groupable + name_or_value_or_false(@groupable) end - def displayable? - displayable - end + def displayable? = !!displayable - # Returns true if the column is sortable, otherwise false - def sortable? - !!sortable - end + def sortable? = !!sortable - # Returns true if the column is groupable, otherwise false - def groupable? - !!groupable - end + def groupable? = !!groupable + + def highlightable? = !!highlightable def summable? summable || @summable_select || @summable_work_packages_select @@ -127,22 +117,25 @@ def value(model) end def initialize(name, options = {}) - self.name = name - - %i(sortable - sortable_join - displayable - groupable - summable - summable_select - summable_work_packages_select - association - null_handling - default_order).each do |attribute| - send(:"#{attribute}=", options[attribute]) + @name = name + + %i[ + sortable + sortable_join + displayable + groupable + groupable_join + summable + summable_select + summable_work_packages_select + association + null_handling + default_order + ].each do |attribute| + instance_variable_set(:"@#{attribute}", options[attribute]) end - self.highlightable = !!options.fetch(:highlightable, false) + @highlightable = !!options.fetch(:highlightable, false) end def caption diff --git a/app/models/query.rb b/app/models/query.rb index d8051b6b1d06..47eabd5b19d6 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -359,7 +359,15 @@ def group_by_column end def group_by_statement - group_by_column.try(:groupable) + group_by_column&.groupable + end + + def group_by_select + group_by_column&.groupable_select || group_by_statement + end + + def group_by_join_statement + group_by_column&.groupable_join end def statement diff --git a/app/models/query/results.rb b/app/models/query/results.rb index dbf58dcbfa8c..8bffcccd8ad0 100644 --- a/app/models/query/results.rb +++ b/app/models/query/results.rb @@ -82,6 +82,7 @@ def filtered_work_packages def sorted_work_packages work_package_scope .joins(sort_criteria_joins) + .joins(query.group_by_join_statement) .order(order_option) .order(sort_criteria_array) end @@ -195,10 +196,8 @@ def columns_hash_for(association = nil) ## # Return the case insensitive version for columns with a string type def case_insensitive_condition(column_key, condition, columns_hash) - if columns_hash[column_key]&.type == :string + if columns_hash[column_key]&.type == :string || custom_field_type(column_key) == "string" "LOWER(#{condition})" - elsif custom_field_type(column_key) == "string" - condition.map { |c| "LOWER(#{c})" } else condition end diff --git a/app/models/query/results/group_by.rb b/app/models/query/results/group_by.rb index b5609d28e876..c3097fdb03e7 100644 --- a/app/models/query/results/group_by.rb +++ b/app/models/query/results/group_by.rb @@ -46,6 +46,7 @@ def work_package_count_for(group) def group_counts_by_group work_packages_with_includes_for_count + .joins(query.group_by_join_statement) .group(group_by_for_count) .visible .references(:statuses, :projects) @@ -67,7 +68,7 @@ def group_by_for_count end def pluck_for_count - Array(query.group_by_statement).map { |statement| Arel.sql(statement) } + + Array(query.group_by_select).map { |statement| Arel.sql(statement) } + [Arel.sql('COUNT(DISTINCT "work_packages"."id")')] end @@ -98,7 +99,7 @@ def transform_list_custom_field_keys(custom_field, groups) groups.transform_keys do |key| if custom_field.multi_value? - key.split(".").map do |subkey| + (key ? key.split(".") : []).map do |subkey| options[subkey].first end else @@ -108,7 +109,7 @@ def transform_list_custom_field_keys(custom_field, groups) end def custom_options_for_keys(custom_field, groups) - keys = groups.keys.map { |k| k.split(".") } + keys = groups.keys.map { |k| k ? k.split(".") : [] } # Because of multi select cfs we might end up having overlapping groups # (e.g group "1" and group "1.3" and group "3" which represent concatenated ids). # This can result in us having ids in the keys array multiple times (e.g. ["1", "1", "3", "3"]). diff --git a/app/models/query/results/sums.rb b/app/models/query/results/sums.rb index 23509ef6656f..3eaf4dec7cca 100644 --- a/app/models/query/results/sums.rb +++ b/app/models/query/results/sums.rb @@ -42,24 +42,26 @@ def all_total_sums def all_group_sums return nil unless query.grouped? - sums_by_id = sums_select(true).inject({}) do |result, group_sum| - result[group_sum["id"]] = {} + transform_group_keys(sums_by_group_id) + end + + private + + def sums_by_group_id + sums_select(true).inject({}) do |result, group_sum| + result[group_sum["group_id"]] = {} query.summed_up_columns.each do |column| - result[group_sum["id"]][column] = group_sum[column.name.to_s] + result[group_sum["group_id"]][column] = group_sum[column.name.to_s] end result end - - transform_group_keys(sums_by_id) end - private - def sums_select(grouped = false) select = if grouped - ["work_packages.id"] + ["work_packages.group_id"] else [] end @@ -86,7 +88,7 @@ def sums_work_package_scope(grouped) .select(sums_work_package_scope_selects(grouped)) if grouped - scope.group(query.group_by_statement) + scope.joins(query.group_by_join_statement).group(query.group_by_statement) else scope end @@ -96,7 +98,8 @@ def sums_callable_joins(grouped) callable_summed_up_columns .map do |c| join_condition = if grouped - "#{c.name}.id = work_packages.id OR #{c.name}.id IS NULL AND work_packages.id IS NULL" + "#{c.name}.group_id = work_packages.group_id OR " \ + "#{c.name}.group_id IS NULL AND work_packages.group_id IS NULL" else "TRUE" end @@ -109,7 +112,7 @@ def sums_callable_joins(grouped) def sums_work_package_scope_selects(grouped) group_statement = if grouped - [Queries::WorkPackages::Selects::WorkPackageSelect.select_group_by(query.group_by_statement)] + [Queries::WorkPackages::Selects::WorkPackageSelect.select_group_by(query.group_by_select)] else [] end diff --git a/app/models/relation.rb b/app/models/relation.rb index f57f195fb1f7..947312b1c213 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -31,12 +31,12 @@ class Relation < ApplicationRecord belongs_to :to, class_name: "WorkPackage" TYPE_RELATES = "relates".freeze - TYPE_DUPLICATES = "duplicates".freeze - TYPE_DUPLICATED = "duplicated".freeze - TYPE_BLOCKS = "blocks".freeze - TYPE_BLOCKED = "blocked".freeze TYPE_PRECEDES = "precedes".freeze TYPE_FOLLOWS = "follows".freeze + TYPE_BLOCKS = "blocks".freeze + TYPE_BLOCKED = "blocked".freeze + TYPE_DUPLICATES = "duplicates".freeze + TYPE_DUPLICATED = "duplicated".freeze TYPE_INCLUDES = "includes".freeze TYPE_PARTOF = "partof".freeze TYPE_REQUIRES = "requires".freeze @@ -51,12 +51,13 @@ class Relation < ApplicationRecord TYPE_RELATES => { name: :label_relates_to, sym_name: :label_relates_to, order: 1, sym: TYPE_RELATES }, - TYPE_DUPLICATES => { - name: :label_duplicates, sym_name: :label_duplicated_by, order: 2, sym: TYPE_DUPLICATED + TYPE_PRECEDES => { + name: :label_precedes, sym_name: :label_follows, order: 6, + sym: TYPE_FOLLOWS, reverse: TYPE_FOLLOWS }, - TYPE_DUPLICATED => { - name: :label_duplicated_by, sym_name: :label_duplicates, order: 3, - sym: TYPE_DUPLICATES, reverse: TYPE_DUPLICATES + TYPE_FOLLOWS => { + name: :label_follows, sym_name: :label_precedes, order: 7, + sym: TYPE_PRECEDES }, TYPE_BLOCKS => { name: :label_blocks, sym_name: :label_blocked_by, order: 4, sym: TYPE_BLOCKED @@ -65,13 +66,12 @@ class Relation < ApplicationRecord name: :label_blocked_by, sym_name: :label_blocks, order: 5, sym: TYPE_BLOCKS, reverse: TYPE_BLOCKS }, - TYPE_PRECEDES => { - name: :label_precedes, sym_name: :label_follows, order: 6, - sym: TYPE_FOLLOWS, reverse: TYPE_FOLLOWS + TYPE_DUPLICATES => { + name: :label_duplicates, sym_name: :label_duplicated_by, order: 6, sym: TYPE_DUPLICATED }, - TYPE_FOLLOWS => { - name: :label_follows, sym_name: :label_precedes, order: 7, - sym: TYPE_PRECEDES + TYPE_DUPLICATED => { + name: :label_duplicated_by, sym_name: :label_duplicates, order: 7, + sym: TYPE_DUPLICATES, reverse: TYPE_DUPLICATES }, TYPE_INCLUDES => { name: :label_includes, sym_name: :label_part_of, order: 8, diff --git a/app/models/work_package.rb b/app/models/work_package.rb index e02d14aa81dd..a1ec03892668 100644 --- a/app/models/work_package.rb +++ b/app/models/work_package.rb @@ -54,6 +54,7 @@ class WorkPackage < ApplicationRecord belongs_to :assigned_to, class_name: "Principal", optional: true belongs_to :responsible, class_name: "Principal", optional: true belongs_to :version, optional: true + belongs_to :project_life_cycle_step, class_name: "Project::LifeCycleStep", optional: true belongs_to :priority, class_name: "IssuePriority" belongs_to :category, class_name: "Category", optional: true @@ -302,7 +303,7 @@ def included_in_totals_calculation? end def done_ratio - if WorkPackage.status_based_mode? && status && status.default_done_ratio + if WorkPackage.status_based_mode? && status&.default_done_ratio status.default_done_ratio else read_attribute(:done_ratio) @@ -377,7 +378,7 @@ def attributes=(new_attributes) # Set the done_ratio using the status if that setting is set. This will keep the done_ratios # even if the user turns off the setting later def update_done_ratio_from_status - if WorkPackage.status_based_mode? && status && status.default_done_ratio + if WorkPackage.status_based_mode? && status&.default_done_ratio self.done_ratio = status.default_done_ratio end end @@ -631,7 +632,7 @@ def self.update_versions(conditions = nil) # Default assignment based on category def default_assign - if assigned_to.nil? && category && category.assigned_to + if assigned_to.nil? && category&.assigned_to self.assigned_to = category.assigned_to end end diff --git a/app/models/work_package/exports/formatters/costs.rb b/app/models/work_package/exports/formatters/costs.rb index 9133f3cfe02e..310f864aff4b 100644 --- a/app/models/work_package/exports/formatters/costs.rb +++ b/app/models/work_package/exports/formatters/costs.rb @@ -38,8 +38,8 @@ def format_options def number_format_string # [$CUR] makes sure we have an actually working currency format with arbitrary currencies - curr = "[$CUR]".gsub "CUR", ERB::Util.h(Setting.plugin_costs["costs_currency"]) - format = ERB::Util.h Setting.plugin_costs["costs_currency_format"] + curr = "[$CUR]".gsub "CUR", ERB::Util.h(Setting.costs_currency) + format = ERB::Util.h Setting.costs_currency_format number = "#,##0.00" format.gsub("%n", number).gsub("%u", curr) diff --git a/app/models/work_package/pdf_export/common/attachments.rb b/app/models/work_package/pdf_export/common/attachments.rb new file mode 100644 index 000000000000..2a1574f8618d --- /dev/null +++ b/app/models/work_package/pdf_export/common/attachments.rb @@ -0,0 +1,77 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +require "mini_magick" + +module WorkPackage::PDFExport::Common::Attachments + def resize_image(file_path) + tmp_file = Tempfile.new(["temp_image", File.extname(file_path)]) + @resized_images = [] if @resized_images.nil? + + @resized_images << tmp_file + resized_file_path = tmp_file.path + + image = MiniMagick::Image.open(file_path) + image.resize("x800>") + image.write(resized_file_path) + + resized_file_path + end + + def pdf_embeddable?(content_type) + %w[image/jpeg image/png].include?(content_type) + end + + def delete_all_resized_images + @resized_images&.each(&:close!) + @resized_images = [] + end + + def attachment_image_local_file(attachment) + attachment.file.local_file + rescue StandardError => e + Rails.logger.error "Failed to access attachment #{attachment.id} file: #{e}" + nil # return nil as if the id was wrong and the attachment obj has not been found + end + + def attachment_image_filepath(work_package, src) + # images are embedded into markup with the api-path as img.src + attachment = attachment_by_api_content_src(work_package, src) + return nil if attachment.nil? || !pdf_embeddable?(attachment.content_type) + + local_file = attachment_image_local_file(attachment) + return nil if local_file.nil? + + resize_image(local_file.path) + end + + def attachment_by_api_content_src(work_package, src) + # find attachment by api-path + work_package.attachments.find { |a| api_url_helpers.attachment_content(a.id) == src } + end +end diff --git a/app/models/work_package/pdf_export/common.rb b/app/models/work_package/pdf_export/common/common.rb similarity index 89% rename from app/models/work_package/pdf_export/common.rb rename to app/models/work_package/pdf_export/common/common.rb index e9ccb01a6a1c..c91d44836ab5 100644 --- a/app/models/work_package/pdf_export/common.rb +++ b/app/models/work_package/pdf_export/common/common.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Common +module WorkPackage::PDFExport::Common::Common include Redmine::I18n include ActionView::Helpers::TextHelper include ActionView::Helpers::NumberHelper @@ -36,7 +36,7 @@ module WorkPackage::PDFExport::Common private def get_pdf(_language) - ::WorkPackage::PDFExport::View.new(current_language) + ::WorkPackage::PDFExport::Common::View.new(current_language) end def field_value(work_package, attribute) @@ -76,26 +76,11 @@ def with_vertical_margin(opts) pdf.move_down(opts[:bottom_margin]) if opts.key?(:bottom_margin) end - def write_optional_page_break - space_from_bottom = pdf.y - pdf.bounds.bottom - if space_from_bottom < styles.page_break_threshold - pdf.start_new_page - end - end - def get_column_value(work_package, column_name) formatter = formatter_for(column_name, :pdf) formatter.format(work_package) end - def get_column_value_cell(work_package, column_name) - value = get_column_value(work_package, column_name) - return get_id_column_cell(work_package, value) if column_name == :id - return get_subject_column_cell(work_package, value) if wants_report? && column_name == :subject - - escape_tags(value) - end - def get_formatted_value(value, column_name) return "" if value.nil? @@ -108,19 +93,6 @@ def escape_tags(value) value.to_s.gsub("<", "<").gsub(">", ">") end - def get_id_column_cell(work_package, value) - href = url_helpers.work_package_url(work_package) - make_link_href_cell(href, value) - end - - def get_subject_column_cell(work_package, value) - make_link_anchor(work_package.id, escape_tags(value)) - end - - def make_link_href_cell(href, caption) - "#{caption}" - end - def make_link_anchor(anchor, caption) "#{caption}" end @@ -306,6 +278,10 @@ def title_datetime DateTime.now.strftime("%Y-%m-%d_%H-%M") end + def footer_date + format_time(Time.zone.now) + end + def current_page_nr pdf.page_number + @page_count - (with_cover? ? 1 : 0) end diff --git a/app/models/work_package/pdf_export/common/logo.rb b/app/models/work_package/pdf_export/common/logo.rb new file mode 100644 index 000000000000..fe4cc81b6f28 --- /dev/null +++ b/app/models/work_package/pdf_export/common/logo.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module WorkPackage::PDFExport::Common::Logo + def logo_image + image_obj, image_info = pdf.build_image_object(logo_image_filename) + [image_obj, image_info] + end + + def logo_image_filename + custom_logo_image_filename || Rails.root.join("app/assets/images/logo_openproject.png") + end + + def custom_logo_image_filename + return unless CustomStyle.current.present? && + CustomStyle.current.export_logo.present? && CustomStyle.current.export_logo.local_file.present? + + image_file = CustomStyle.current.export_logo.local_file.path + content_type = OpenProject::ContentTypeDetector.new(image_file).detect + return unless pdf_embeddable?(content_type) + + image_file + end +end diff --git a/app/models/work_package/pdf_export/markdown_field.rb b/app/models/work_package/pdf_export/common/macro.rb similarity index 84% rename from app/models/work_package/pdf_export/markdown_field.rb rename to app/models/work_package/pdf_export/common/macro.rb index 53ccd93dc8b6..bb2a73b914db 100644 --- a/app/models/work_package/pdf_export/markdown_field.rb +++ b/app/models/work_package/pdf_export/common/macro.rb @@ -26,28 +26,15 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::MarkdownField - include WorkPackage::PDFExport::Markdown +module WorkPackage::PDFExport::Common::Macro PREFORMATTED_BLOCKS = %w(pre code).freeze - def write_markdown_field!(work_package, markdown, label) - return if markdown.blank? - - write_optional_page_break - with_margin(styles.wp_markdown_label_margins) do - pdf.formatted_text([styles.wp_markdown_label.merge({ text: label })]) - end - with_margin(styles.wp_markdown_margins) do - write_markdown! work_package, apply_markdown_field_macros(markdown, work_package) - end - end - - private - def apply_markdown_field_macros(markdown, work_package) apply_macros(markdown, work_package, WorkPackage::Exports::Macros::Attributes) end + private + def apply_macros(markdown, work_package, formatter) return markdown unless formatter.applicable?(markdown) diff --git a/app/models/work_package/pdf_export/view.rb b/app/models/work_package/pdf_export/common/view.rb similarity index 98% rename from app/models/work_package/pdf_export/view.rb rename to app/models/work_package/pdf_export/common/view.rb index 86f9c4418c61..8adc723fc043 100644 --- a/app/models/work_package/pdf_export/view.rb +++ b/app/models/work_package/pdf_export/common/view.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -class WorkPackage::PDFExport::View +class WorkPackage::PDFExport::Common::View include Prawn::View include Redmine::I18n diff --git a/app/models/work_package/pdf_export/document_generator.rb b/app/models/work_package/pdf_export/document_generator.rb new file mode 100644 index 000000000000..37b69c6b4ea0 --- /dev/null +++ b/app/models/work_package/pdf_export/document_generator.rb @@ -0,0 +1,94 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class WorkPackage::PDFExport::DocumentGenerator < Exports::Exporter + include WorkPackage::PDFExport::Common::Common + include WorkPackage::PDFExport::Common::Attachments + include WorkPackage::PDFExport::Common::Logo + include WorkPackage::PDFExport::Common::Macro + include WorkPackage::PDFExport::Generator::Generator + + attr_accessor :pdf + + self.model = WorkPackage + + alias :work_package :object + + def self.key + :generate_pdf + end + + def initialize(work_package, _options = {}) + super + + setup_page! + end + + def setup_page! + self.pdf = get_pdf(current_language) + end + + def export! + render_doc + success(pdf.render) + rescue StandardError => e + Rails.logger.error { "Failed to generate PDF: #{e} #{e.message}}." } + error(I18n.t(:error_pdf_failed_to_export, error: e.message)) + end + + def render_doc + generate_doc!( + apply_markdown_field_macros(work_package.description || "", work_package), + "contracts.yml" + ) + end + + def hyphenation_language + options[:hyphenation] + end + + def heading + options[:header_text_right] + end + + def footer_title + options[:footer_text_center] + end + + def title + # ____.pdf + build_pdf_filename([work_package.project, work_package.type, + "##{work_package.id}", work_package.subject].join("_")) + end + + def with_images? + true + end +end diff --git a/app/models/work_package/pdf_export/cover.rb b/app/models/work_package/pdf_export/export/cover.rb similarity index 98% rename from app/models/work_package/pdf_export/cover.rb rename to app/models/work_package/pdf_export/export/cover.rb index ebac1df6b501..e50d0c101c30 100644 --- a/app/models/work_package/pdf_export/cover.rb +++ b/app/models/work_package/pdf_export/export/cover.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Cover +module WorkPackage::PDFExport::Export::Cover def write_cover_page! write_cover_logo write_cover_hr diff --git a/app/models/work_package/pdf_export/export/export_common.rb b/app/models/work_package/pdf_export/export/export_common.rb new file mode 100644 index 000000000000..ace15b8f08c7 --- /dev/null +++ b/app/models/work_package/pdf_export/export/export_common.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module WorkPackage::PDFExport::Export::ExportCommon + def write_optional_page_break + space_from_bottom = pdf.y - pdf.bounds.bottom + if space_from_bottom < styles.page_break_threshold + pdf.start_new_page + end + end + + def make_link_href_cell(href, caption) + "#{caption}" + end + + def get_column_value_cell(work_package, column_name) + value = get_column_value(work_package, column_name) + return get_id_column_cell(work_package, value) if column_name == :id + return get_subject_column_cell(work_package, value) if wants_report? && column_name == :subject + + escape_tags(value) + end + + def get_id_column_cell(work_package, value) + href = url_helpers.work_package_url(work_package) + make_link_href_cell(href, value) + end + + def get_subject_column_cell(work_package, value) + make_link_anchor(work_package.id, escape_tags(value)) + end +end diff --git a/app/models/work_package/pdf_export/gantt.rb b/app/models/work_package/pdf_export/export/gantt.rb similarity index 98% rename from app/models/work_package/pdf_export/gantt.rb rename to app/models/work_package/pdf_export/export/gantt.rb index 778f286168f6..a395b4ce0710 100644 --- a/app/models/work_package/pdf_export/gantt.rb +++ b/app/models/work_package/pdf_export/export/gantt.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -43,7 +45,7 @@ # 1. Build the data classes, do the layout, measuring, etc. # 2. Paint the Gantt chart into the PDF -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt GANTT_DAY_COLUMN_WIDTHS = [64, 32, 24, 18].freeze GANTT_COLUMN_WIDTHS = [128, 64, 32, 24].freeze GANTT_COLUMN_WIDTHS_NAMES = %w[very_wide wide medium narrow].freeze diff --git a/app/models/work_package/pdf_export/gantt/gantt_builder.rb b/app/models/work_package/pdf_export/export/gantt/gantt_builder.rb similarity index 99% rename from app/models/work_package/pdf_export/gantt/gantt_builder.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_builder.rb index 334697cfbe75..1af1b7ee16a5 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_builder.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_builder.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttBuilder include Redmine::I18n BAR_CELL_PADDING = 5.to_f diff --git a/app/models/work_package/pdf_export/gantt/gantt_builder_days.rb b/app/models/work_package/pdf_export/export/gantt/gantt_builder_days.rb similarity index 97% rename from app/models/work_package/pdf_export/gantt/gantt_builder_days.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_builder_days.rb index 829e2f8bb41f..465a4f9515bc 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_builder_days.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_builder_days.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttBuilderDays < GanttBuilder def build_column_dates_range(range) range.to_a diff --git a/app/models/work_package/pdf_export/gantt/gantt_builder_months.rb b/app/models/work_package/pdf_export/export/gantt/gantt_builder_months.rb similarity index 98% rename from app/models/work_package/pdf_export/gantt/gantt_builder_months.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_builder_months.rb index 2505a1d2de52..fe8b8f252d8a 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_builder_months.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_builder_months.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttBuilderMonths < GanttBuilder def build_column_dates_range(range) range diff --git a/app/models/work_package/pdf_export/gantt/gantt_builder_quarters.rb b/app/models/work_package/pdf_export/export/gantt/gantt_builder_quarters.rb similarity index 98% rename from app/models/work_package/pdf_export/gantt/gantt_builder_quarters.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_builder_quarters.rb index c6767403b3fe..664f02d2048d 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_builder_quarters.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_builder_quarters.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttBuilderQuarters < GanttBuilder def build_column_dates_range(range) range diff --git a/app/models/work_package/pdf_export/gantt/gantt_builder_weeks.rb b/app/models/work_package/pdf_export/export/gantt/gantt_builder_weeks.rb similarity index 98% rename from app/models/work_package/pdf_export/gantt/gantt_builder_weeks.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_builder_weeks.rb index f0cc8750a423..337f04977d61 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_builder_weeks.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_builder_weeks.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttBuilderWeeks < GanttBuilder def build_column_dates_range(range) range diff --git a/app/models/work_package/pdf_export/gantt/gantt_painter.rb b/app/models/work_package/pdf_export/export/gantt/gantt_painter.rb similarity index 99% rename from app/models/work_package/pdf_export/gantt/gantt_painter.rb rename to app/models/work_package/pdf_export/export/gantt/gantt_painter.rb index 952b08b505b8..4247900974b1 100644 --- a/app/models/work_package/pdf_export/gantt/gantt_painter.rb +++ b/app/models/work_package/pdf_export/export/gantt/gantt_painter.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Gantt +module WorkPackage::PDFExport::Export::Gantt class GanttPainter GANTT_GRID_COLOR = "9b9ea3".freeze GANTT_LINE_COLOR = "2b8bd5".freeze diff --git a/app/models/work_package/pdf_export/markdown.rb b/app/models/work_package/pdf_export/export/markdown.rb similarity index 77% rename from app/models/work_package/pdf_export/markdown.rb rename to app/models/work_package/pdf_export/export/markdown.rb index a875f800bf89..eab8c54370a9 100644 --- a/app/models/work_package/pdf_export/markdown.rb +++ b/app/models/work_package/pdf_export/export/markdown.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -28,8 +30,8 @@ require "md_to_pdf/core" -module WorkPackage::PDFExport::Markdown - class MD2PDF +module WorkPackage::PDFExport::Export::Markdown + class MD2PDFExport include MarkdownToPDF::Core include MarkdownToPDF::Parser @@ -96,35 +98,10 @@ def warn(text, element, node) end end - def write_markdown!(work_package, markdown) - md2pdf = MD2PDF.new(styles.wp_markdown_styling_yml, pdf) + def write_markdown!(work_package, markdown, styling_yml) + md2pdf = MD2PDFExport.new(styling_yml, pdf) md2pdf.draw_markdown(markdown, pdf, ->(src) { with_images? ? attachment_image_filepath(work_package, src) : nil }) end - - private - - def attachment_image_local_file(attachment) - attachment.file.local_file - rescue StandardError => e - Rails.logger.error "Failed to access attachment #{attachment.id} file: #{e}" - nil # return nil as if the id was wrong and the attachment obj has not been found - end - - def attachment_image_filepath(work_package, src) - # images are embedded into markup with the api-path as img.src - attachment = attachment_by_api_content_src(work_package, src) - return nil if attachment.nil? || !pdf_embeddable?(attachment.content_type) - - local_file = attachment_image_local_file(attachment) - return nil if local_file.nil? - - resize_image(local_file.path) - end - - def attachment_by_api_content_src(work_package, src) - # find attachment by api-path - work_package.attachments.detect { |a| api_url_helpers.attachment_content(a.id) == src } - end end diff --git a/app/models/work_package/pdf_export/export/markdown_field.rb b/app/models/work_package/pdf_export/export/markdown_field.rb new file mode 100644 index 000000000000..02c097089ac1 --- /dev/null +++ b/app/models/work_package/pdf_export/export/markdown_field.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module WorkPackage::PDFExport::Export::MarkdownField + include WorkPackage::PDFExport::Export::Markdown + include WorkPackage::PDFExport::Common::Macro + + def write_markdown_field!(work_package, markdown, label) + return if markdown.blank? + + write_optional_page_break + write_markdown_field_label(label) + write_markdown_field_value(work_package, markdown) + end + + private + + def write_markdown_field_label(label) + with_margin(styles.wp_markdown_label_margins) do + pdf.formatted_text([styles.wp_markdown_label.merge({ text: label })]) + end + end + + def write_markdown_field_value(work_package, markdown) + with_margin(styles.wp_markdown_margins) do + write_markdown!( + work_package, + apply_markdown_field_macros(markdown, work_package), + styles.wp_markdown_styling_yml + ) + end + end +end diff --git a/app/models/work_package/pdf_export/overview_table.rb b/app/models/work_package/pdf_export/export/overview_table.rb similarity index 98% rename from app/models/work_package/pdf_export/overview_table.rb rename to app/models/work_package/pdf_export/export/overview_table.rb index c44684665114..10405fb87c6b 100644 --- a/app/models/work_package/pdf_export/overview_table.rb +++ b/app/models/work_package/pdf_export/export/overview_table.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::OverviewTable +module WorkPackage::PDFExport::Export::OverviewTable def write_work_packages_overview!(work_packages) if query.grouped? write_grouped!(work_packages) diff --git a/app/models/work_package/pdf_export/page.rb b/app/models/work_package/pdf_export/export/page.rb similarity index 83% rename from app/models/work_package/pdf_export/page.rb rename to app/models/work_package/pdf_export/export/page.rb index 571efcfaf76f..c63001e5060f 100644 --- a/app/models/work_package/pdf_export/page.rb +++ b/app/models/work_package/pdf_export/export/page.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Page +module WorkPackage::PDFExport::Export::Page MAX_NR_OF_PDF_FOOTER_LINES = 3 def configure_page_size!(layout) @@ -68,24 +70,6 @@ def logo_pdf_image [image_obj, image_info, scale] end - def logo_image - image_file = custom_logo_image - image_file = Rails.root.join("app/assets/images/logo_openproject.png") if image_file.nil? - image_obj, image_info = pdf.build_image_object(image_file) - [image_obj, image_info] - end - - def custom_logo_image - return unless CustomStyle.current.present? && - CustomStyle.current.export_logo.present? && CustomStyle.current.export_logo.local_file.present? - - image_file = CustomStyle.current.export_logo.local_file.path - content_type = OpenProject::ContentTypeDetector.new(image_file).detect - return unless pdf_embeddable?(content_type) - - image_file - end - def write_title! pdf.title = heading with_margin(styles.page_heading_margins) do @@ -126,10 +110,6 @@ def footer_page_nr current_page_nr.to_s + total_page_nr_text end - def footer_date - format_time(Time.zone.now) - end - def total_page_nr_text if @total_page_nr "/#{@total_page_nr - (with_cover? ? 1 : 0)}" diff --git a/app/models/work_package/pdf_export/schema.json b/app/models/work_package/pdf_export/export/schema.json similarity index 100% rename from app/models/work_package/pdf_export/schema.json rename to app/models/work_package/pdf_export/export/schema.json diff --git a/app/models/work_package/pdf_export/standard.yml b/app/models/work_package/pdf_export/export/standard.yml similarity index 100% rename from app/models/work_package/pdf_export/standard.yml rename to app/models/work_package/pdf_export/export/standard.yml diff --git a/app/models/work_package/pdf_export/style.rb b/app/models/work_package/pdf_export/export/style.rb similarity index 98% rename from app/models/work_package/pdf_export/style.rb rename to app/models/work_package/pdf_export/export/style.rb index 349bc977d67f..4a1a152adf1f 100644 --- a/app/models/work_package/pdf_export/style.rb +++ b/app/models/work_package/pdf_export/export/style.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::Style +module WorkPackage::PDFExport::Export::Style include MarkdownToPDF::StyleValidation class PDFStyles @@ -308,7 +310,6 @@ def load_style end def styles_asset_path - # TODO: where to put & load yml & json file File.dirname(File.expand_path(__FILE__)) end end diff --git a/app/models/work_package/pdf_export/sums_table.rb b/app/models/work_package/pdf_export/export/sums_table.rb similarity index 97% rename from app/models/work_package/pdf_export/sums_table.rb rename to app/models/work_package/pdf_export/export/sums_table.rb index c34c08ad4eb0..59c22e467c9e 100644 --- a/app/models/work_package/pdf_export/sums_table.rb +++ b/app/models/work_package/pdf_export/export/sums_table.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::SumsTable +module WorkPackage::PDFExport::Export::SumsTable def write_work_packages_sums!(_work_packages) return unless has_summable_column? diff --git a/app/models/work_package/pdf_export/table_of_contents.rb b/app/models/work_package/pdf_export/export/table_of_contents.rb similarity index 98% rename from app/models/work_package/pdf_export/table_of_contents.rb rename to app/models/work_package/pdf_export/export/table_of_contents.rb index 8d763bb21d09..2e6094626a4f 100644 --- a/app/models/work_package/pdf_export/table_of_contents.rb +++ b/app/models/work_package/pdf_export/export/table_of_contents.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,7 +28,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::TableOfContents +module WorkPackage::PDFExport::Export::TableOfContents def write_work_packages_toc!(work_packages, id_wp_meta_map) toc_list = build_toc_data_list work_packages, id_wp_meta_map with_margin(styles.toc_margins) do diff --git a/app/models/work_package/pdf_export/work_package_detail.rb b/app/models/work_package/pdf_export/export/work_package_detail.rb similarity index 98% rename from app/models/work_package/pdf_export/work_package_detail.rb rename to app/models/work_package/pdf_export/export/work_package_detail.rb index 24ad8fa359b7..f54b179a08c3 100644 --- a/app/models/work_package/pdf_export/work_package_detail.rb +++ b/app/models/work_package/pdf_export/export/work_package_detail.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -26,8 +28,8 @@ # See COPYRIGHT and LICENSE files for more details. #++ -module WorkPackage::PDFExport::WorkPackageDetail - include WorkPackage::PDFExport::MarkdownField +module WorkPackage::PDFExport::Export::WorkPackageDetail + include WorkPackage::PDFExport::Export::MarkdownField def write_work_packages_details!(work_packages, id_wp_meta_map) work_packages.each do |work_package| diff --git a/app/models/work_package/pdf_export/generator/contracts.yml b/app/models/work_package/pdf_export/generator/contracts.yml new file mode 100644 index 000000000000..97930db5db6b --- /dev/null +++ b/app/models/work_package/pdf_export/generator/contracts.yml @@ -0,0 +1,244 @@ +page: + font: 'NotoSans' + size: 11 + character-spacing: 0 + styles: [] + color: '000000' + page-size: 'A4' + page-layout: 'portrait' + margin-left: 20mm + margin-right: 20mm + margin-top: 40mm + margin-bottom: 35mm + leading: 6 + +page-footer: + filter-pages: [ ] + align: "left" + offset: -51 + size: 8 + +page-footer-2: + filter-pages: [ ] + align: "center" + offset: -51 + size: 8 + +page-footer-3: + filter-pages: [ ] + align: "right" + offset: -51 + size: 8 + +page-header: + filter-pages: [ ] + align: "right" + size: 8 + leading: 4 + offset: -61 + +page-logo: + filter-pages: [ ] + align: "left" + max-width: 40mm + offset: -70 + +paragraph: + align: 'justify' + padding-bottom: 3mm + +link: + color: '1b69b6' + +unordered-list: + spacing: 3mm + padding-bottom: 3mm + +unordered-list-point: + sign: "•" + spacing: 0.75mm + +ordered-list: + spacing: 3mm + padding-bottom: 3mm + +ordered-list-point: + spanning: true + +ordered-list-point-1: + template: '()' + +ordered-list-point-2: + template: ')' + alphabetical: true + +hrule: + margin-top: 2mm + margin-bottom: 4mm + line-width: 1 + +header: + styles: [ 'bold' ] + padding-top: 2mm + padding-bottom: 2mm + +header-1: + size: 18 + padding-top: 6mm +header-2: + size: 14 + padding-top: 5mm +header-3: + size: 12 + padding-top: 4mm +header-4: + size: 11 + padding-top: 3mm +header-5: + size: 10 +header-6: + size: 10 +header-7: + size: 10 +header-8: + size: 10 + +table: + margin-top: 2mm + margin-bottom: 4mm + header: + styles: [ 'bold' ] + background-color: 'F0F0F0' + size: 10 + cell: + no-border: true + padding: 1mm + size: 9 + +headless-table: + margin-top: 2mm + margin-bottom: 4mm + cell: + no-border: true + padding: 1mm + size: 9 + +blockquote: + background-color: 'f4f9ff' + size: 11 + styles: [ 'italic' ] + color: '0f3b66' + border-color: 'b8d6f4' + border-width: 1 + no-border-right: true + no-border-left: false + no-border-bottom: true + no-border-top: true + padding: 8mm + padding-left: 4mm + padding-right: 4mm + margin-top: 2mm + margin-bottom: 2mm + +alerts: + NOTE: + border_color: '0969da' + alert_color: '0969da' + padding: '4mm' + size: 10 + styles: [] + border_width: 2 + no_border_right: true + no_border_left: false + no_border_bottom: true + no_border_top: true + TIP: + border_color: '1a7f37' + alert_color: '1a7f37' + padding: '4mm' + size: 10 + styles: [ ] + border_width: 2 + no_border_right: true + no_border_left: false + no_border_bottom: true + no_border_top: true + IMPORTANT: + border_color: '8250df' + alert_color: '8250df' + padding: '4mm' + size: 10 + styles: [ ] + border_width: 2 + no_border_right: true + no_border_left: false + no_border_bottom: true + no_border_top: true + WARNING: + border_color: 'bf8700' + alert_color: 'bf8700' + padding: '4mm' + size: 10 + styles: [ ] + border_width: 2 + no_border_right: true + no_border_left: false + no_border_bottom: true + no_border_top: true + CAUTION: + border_color: 'd1242f' + alert_color: 'd1242f' + size: 10 + styles: [ ] + padding: '4mm' + border_width: 2 + no_border_right: true + no_border_left: false + no_border_bottom: true + no_border_top: true + +code: + font: 'SpaceMono' + color: '880000' + +codeblock: + background-color: 'F5F5F5' + font: 'SpaceMono' + size: 8 + color: '880000' + padding: 3mm + margin-top: 2mm + margin-bottom: 2mm + +image: + max-width: 50mm + margin: 2mm + margin-bottom: 3mm + align: "center" + +image-classes: + small: + max-width: 10mm + left: + margin: 0 + align: "left" + center: + margin: 0 + align: "center" + right: + margin: 0 + align: "right" + +footnote-definition: + point: + size: 13 + styles: [ 'superscript' ] + color: '000000' + +footnote-reference: + size: 13 + styles: [ 'superscript' ] + color: '000088' + +fields-default: + pdf_hyphenation: true diff --git a/app/models/work_package/pdf_export/generator/generator.rb b/app/models/work_package/pdf_export/generator/generator.rb new file mode 100644 index 000000000000..2e152e561526 --- /dev/null +++ b/app/models/work_package/pdf_export/generator/generator.rb @@ -0,0 +1,167 @@ +# frozen_string_literal: true + +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +require "md_to_pdf/core" + +module WorkPackage::PDFExport::Generator::Generator + class MD2PDFGenerator + include MarkdownToPDF::Core + include MarkdownToPDF::Parser + include MarkdownToPDF::StyleSchema + + def initialize(styling_yml) + symbol_yml = symbolize(styling_yml) + validate_schema!(symbol_yml, styles_schema) + @styles = MarkdownToPDF::Styles.new(symbol_yml) + init_options({ auto_generate_header_ids: false }) + end + + def init_pdf(pdf) + @pdf = pdf + init_pdf_page_styles(pdf) + pdf_init_md2pdf_fonts(pdf) + end + + def init_pdf_page_styles(pdf) + page_style = @styles.page + page_margins = opts_margin(page_style) + pdf.options[:page_layout] = (page_style[:page_layout] || "portrait").to_sym + pdf.options[:page_size] = page_style[:page_size] + %i[top_margin left_margin bottom_margin right_margin].each do |margin| + pdf.options[margin] = page_margins[margin] + end + end + + def generate!(markdown, options, image_loader) + @image_loader = image_loader + fields = {} + .merge(@styles.default_fields) + .merge(options) + doc = parse_frontmatter_markdown(markdown, fields) + @hyphens = Text::Hyphen.new(language: options[:language], left: 2, right: 2) if options[:language].present? + render_doc(doc) + end + + def render_doc(doc) + style = @styles.page + opts = pdf_root_options(style) + root = doc[:root] + draw_node(root, opts, true) + draw_footnotes(opts) + repeating_page_footer(doc, opts) + repeating_page_header(doc, opts) + repeating_page_logo(doc[:logo], root, opts) + end + + def image_url_to_local_file(url, _node = nil) + return nil if url.blank? || @image_loader.nil? + + @image_loader.call(url) + end + + def hyphenate(text) + return text if @hyphens.nil? + + @hyphens.visualize(text, Prawn::Text::SHY) + end + + def handle_mention_html_tag(tag, node, opts) + if tag.text.blank? + # + # + text = tag.attr("data-text") + if text.present? && !node.next.respond_to?(:string_content) && node.next.string_content != text + return [text_hash(text, opts)] + end + end + # @Some User + [] + end + + def handle_unknown_inline_html_tag(tag, node, opts) + result = if tag.name == "mention" + handle_mention_html_tag(tag, node, opts) + else + # unknown/unsupported html tags eg. hi are ignored + # but scanned for supported or text children + data_inlinehtml_tag(tag, node, opts) + end + [result, opts] + end + + def handle_unknown_html_tag(_tag, _node, opts) + # unknown/unsupported html tags eg. hi are ignored + # but scanned for supported or text children [true, ...] + [true, opts] + end + + def warn(text, element, node) + Rails.logger.warn "PDF-Export: #{text}\nGot #{element} at #{node.source_position.inspect}\n\n" + end + end + + def generate_doc!(markdown, styling_file) + md2pdf = MD2PDFGenerator.new(md_to_pdf_styling(styling_file)) + md2pdf.init_pdf(pdf) + md2pdf.generate!(markdown, md_to_pdf_options, ->(src) { + if src == logo_image_filename + logo_image_filename + else + attachment_image_filepath(work_package, src) + end + }) + end + + private + + def md_to_pdf_styling(styling_file) + styling = YAML::load_file(File.join(styling_asset_path, styling_file)) + # overwrite the paper size if it is set in the options + styling["page"]["page-size"] = options[:paper_size] if options[:paper_size].present? + styling + end + + def md_to_pdf_options + # rubocop:disable Naming/VariableNumber + { + language: hyphenation_language, + pdf_footer: footer_date, + pdf_footer_2: footer_title, + pdf_footer_3: I18n.t("pdf_generator.page_nr_footer", page: "", total: ""), + pdf_header_logo: logo_image_filename, + pdf_header: heading + } + # rubocop:enable Naming/VariableNumber + end + + def styling_asset_path + File.dirname(File.expand_path(__FILE__)) + end +end diff --git a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb index cf346d0f91c7..9a1ca49c949e 100644 --- a/app/models/work_package/pdf_export/work_package_list_to_pdf.rb +++ b/app/models/work_package/pdf_export/work_package_list_to_pdf.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -40,16 +42,20 @@ require "open3" class WorkPackage::PDFExport::WorkPackageListToPdf < WorkPackage::Exports::QueryExporter - include WorkPackage::PDFExport::Common - include WorkPackage::PDFExport::Attachments - include WorkPackage::PDFExport::OverviewTable - include WorkPackage::PDFExport::SumsTable - include WorkPackage::PDFExport::WorkPackageDetail - include WorkPackage::PDFExport::TableOfContents - include WorkPackage::PDFExport::Page - include WorkPackage::PDFExport::Gantt - include WorkPackage::PDFExport::Style - include WorkPackage::PDFExport::Cover + include WorkPackage::PDFExport::Common::Common + include WorkPackage::PDFExport::Common::Logo + include WorkPackage::PDFExport::Common::Attachments + include WorkPackage::PDFExport::Export::ExportCommon + include WorkPackage::PDFExport::Export::WorkPackageDetail + include WorkPackage::PDFExport::Export::Page + include WorkPackage::PDFExport::Export::Style + include WorkPackage::PDFExport::Export::OverviewTable + include WorkPackage::PDFExport::Export::SumsTable + include WorkPackage::PDFExport::Export::WorkPackageDetail + include WorkPackage::PDFExport::Export::TableOfContents + include WorkPackage::PDFExport::Export::Style + include WorkPackage::PDFExport::Export::Cover + include WorkPackage::PDFExport::Export::Gantt attr_accessor :pdf, :options diff --git a/app/models/work_package/pdf_export/work_package_to_pdf.rb b/app/models/work_package/pdf_export/work_package_to_pdf.rb index 9f85c9d9572b..5dcfa09dd8c8 100644 --- a/app/models/work_package/pdf_export/work_package_to_pdf.rb +++ b/app/models/work_package/pdf_export/work_package_to_pdf.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -27,11 +29,13 @@ #++ class WorkPackage::PDFExport::WorkPackageToPdf < Exports::Exporter - include WorkPackage::PDFExport::Common - include WorkPackage::PDFExport::Attachments - include WorkPackage::PDFExport::WorkPackageDetail - include WorkPackage::PDFExport::Page - include WorkPackage::PDFExport::Style + include WorkPackage::PDFExport::Common::Common + include WorkPackage::PDFExport::Common::Logo + include WorkPackage::PDFExport::Common::Attachments + include WorkPackage::PDFExport::Export::ExportCommon + include WorkPackage::PDFExport::Export::WorkPackageDetail + include WorkPackage::PDFExport::Export::Page + include WorkPackage::PDFExport::Export::Style attr_accessor :pdf, :columns @@ -54,7 +58,7 @@ def export! render_work_package success(pdf.render) rescue StandardError => e - Rails.logger.error { "Failed to generated PDF export: #{e} #{e.message}}." } + Rails.logger.error { "Failed to generate PDF export: #{e} #{e.message}}." } error(I18n.t(:error_pdf_failed_to_export, error: e.message)) end diff --git a/app/models/work_package_custom_field.rb b/app/models/work_package_custom_field.rb index 1b1a68fe5bc8..0c1776abe2ad 100644 --- a/app/models/work_package_custom_field.rb +++ b/app/models/work_package_custom_field.rb @@ -49,6 +49,11 @@ class WorkPackageCustomField < CustomField end } + scope :usable_as_custom_action, -> { + where.not(field_format: %w[hierarchy]) + order(:name) + } + def self.summable where(field_format: %w[int float]) end diff --git a/app/seeders/basic_data/color_seeder.rb b/app/seeders/basic_data/color_seeder.rb index 225c372b704d..760ec3ed6cf5 100644 --- a/app/seeders/basic_data/color_seeder.rb +++ b/app/seeders/basic_data/color_seeder.rb @@ -29,6 +29,7 @@ module BasicData class ColorSeeder < ModelSeeder self.model_class = Color self.seed_data_model_key = "colors" + self.attribute_names_for_lookups = %i[name] def model_attributes(color_data) { diff --git a/app/seeders/basic_data/life_cycle_color_seeder.rb b/app/seeders/basic_data/life_cycle_color_seeder.rb new file mode 100644 index 000000000000..835dd00cb2d8 --- /dev/null +++ b/app/seeders/basic_data/life_cycle_color_seeder.rb @@ -0,0 +1,44 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module BasicData + class LifeCycleColorSeeder < ColorSeeder + self.seed_data_model_key = "life_cycle_colors" + + def applicable? + missing_color_names.any? + end + + private + + def missing_color_names + color_names = models_data.pluck("name") + color_names - Color.where(name: color_names).pluck(:name) + end + end +end diff --git a/app/seeders/basic_data/life_cycle_step_definition_seeder.rb b/app/seeders/basic_data/life_cycle_step_definition_seeder.rb new file mode 100644 index 000000000000..54166f731019 --- /dev/null +++ b/app/seeders/basic_data/life_cycle_step_definition_seeder.rb @@ -0,0 +1,46 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ +module BasicData + class LifeCycleStepDefinitionSeeder < ModelSeeder + self.model_class = Project::LifeCycleStepDefinition + self.seed_data_model_key = "life_cycles" + self.needs = [ + BasicData::LifeCycleColorSeeder + ] + + self.attribute_names_for_lookups = %i[name type] + + def model_attributes(life_cyle_data) + { + name: life_cyle_data["name"], + type: life_cyle_data["type"], + color_id: color_id(life_cyle_data["color_name"]) + } + end + end +end diff --git a/app/seeders/common.yml b/app/seeders/common.yml index bd7e4a71f8b0..ee89fb7b1376 100644 --- a/app/seeders/common.yml +++ b/app/seeders/common.yml @@ -70,6 +70,23 @@ colors: t_name: Black hexcode: "#000000" +life_cycle_colors: + - reference: :default_color_pm2_orange + t_name: PM2 Orange + hexcode: "#F7983A" + - reference: :default_color_pm2_purple + t_name: PM2 Purple + hexcode: "#682D91" + - reference: :default_color_pm2_red + t_name: PM2 Red + hexcode: "#F05823" + - reference: :default_color_pm2_magenta + t_name: PM2 Magenta + hexcode: "#EC038A" + - reference: :default_color_pm2_green_yellow + t_name: PM2 Green Yellow + hexcode: "#B1D13A" + document_categories: - t_name: Documentation position: 1 diff --git a/app/seeders/root_seeder.rb b/app/seeders/root_seeder.rb index f1a150e4723f..0958652ca40c 100644 --- a/app/seeders/root_seeder.rb +++ b/app/seeders/root_seeder.rb @@ -75,6 +75,11 @@ def do_seed! seed_development_data if seed_development_data? seed_plugins_data seed_env_data + cleanup_seed_data + end + + def cleanup_seed_data + admin_user.lock! if Setting.seed_admin_user_locked? end def seed_development_data? diff --git a/app/seeders/source/seed_data.rb b/app/seeders/source/seed_data.rb index f3813a98e8c2..13f9726bfe39 100644 --- a/app/seeders/source/seed_data.rb +++ b/app/seeders/source/seed_data.rb @@ -60,7 +60,10 @@ def find_reference(reference, *fallbacks, default: :__unset__) default else references = [reference, *fallbacks].map(&:inspect) - message = "Nothing registered with #{'reference'.pluralize(references.count)} #{references.to_sentence(locale: false)}" + message = <<~STRING + Nothing registered with #{'reference'.pluralize(references.count)} #{references.to_sentence(locale: false)} + Perhaps you forgot to add the `attribute_names_for_lookups` for your seeder? + STRING raise ArgumentError, message end end diff --git a/app/seeders/standard.yml b/app/seeders/standard.yml index a177de929704..0e00dea26de8 100644 --- a/app/seeders/standard.yml +++ b/app/seeders/standard.yml @@ -26,6 +26,36 @@ # See COPYRIGHT and LICENSE files for more details. #++ +life_cycles: + - reference: :default_life_cycle_initiating + t_name: Initiating + type: Project::StageDefinition + color_name: :default_color_pm2_orange + - reference: :default_life_cycle_ready_for_planning + t_name: Ready for Planning + type: Project::GateDefinition + color_name: :default_color_pm2_purple + - reference: :default_life_cycle_planning + t_name: Planning + type: Project::StageDefinition + color_name: :default_color_pm2_red + - reference: :default_life_cycle_ready_for_executing + t_name: Ready for Executing + type: Project::GateDefinition + color_name: :default_color_pm2_purple + - reference: :default_life_cycle_executing + t_name: Executing + type: Project::StageDefinition + color_name: :default_color_pm2_magenta + - reference: :default_life_cycle_ready_for_closing + t_name: Ready for Closing + type: Project::GateDefinition + color_name: :default_color_pm2_purple + - reference: :default_life_cycle_closing + t_name: Closing + type: Project::StageDefinition + color_name: :default_color_pm2_green_yellow + priorities: - reference: :default_priority_low t_name: Low diff --git a/app/seeders/standard/basic_data_seeder.rb b/app/seeders/standard/basic_data_seeder.rb index 5c6c06c8ee29..d77525b74a16 100644 --- a/app/seeders/standard/basic_data_seeder.rb +++ b/app/seeders/standard/basic_data_seeder.rb @@ -37,6 +37,8 @@ def data_seeder_classes ::BasicData::TimeEntryActivitySeeder, ::BasicData::ColorSeeder, ::BasicData::ColorSchemeSeeder, + ::BasicData::LifeCycleColorSeeder, + ::BasicData::LifeCycleStepDefinitionSeeder, ::BasicData::WorkflowSeeder, ::BasicData::PrioritySeeder, ::BasicData::SettingSeeder, diff --git a/app/services/authorization/enterprise_service.rb b/app/services/authorization/enterprise_service.rb index 7ddd9730e29f..4e419b03d20e 100644 --- a/app/services/authorization/enterprise_service.rb +++ b/app/services/authorization/enterprise_service.rb @@ -34,6 +34,7 @@ class Authorization::EnterpriseService board_view conditional_highlighting custom_actions + custom_field_hierarchies date_alerts define_custom_style edit_attribute_groups diff --git a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb index 49b5f882da13..8d9421054652 100644 --- a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb +++ b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb @@ -88,6 +88,18 @@ def get_branch(item:) Success(item.self_and_ancestors.reverse) end + # Gets all descendant nodes in a tree starting from the item/node. + # @param item [CustomField::Hierarchy::Item] the node + # @param include_self [Boolean] flag + # @return [Success(Array)] + def get_descendants(item:, include_self: true) + if include_self + Success(item.self_and_descendants) + else + Success(item.descendants) + end + end + # Move an item/node to a new parent item/node # @param item [CustomField::Hierarchy::Item] the parent of the node # @param new_parent [CustomField::Hierarchy::Item] the new parent of the node diff --git a/app/views/admin/settings/project_custom_fields/new.html.erb b/app/views/admin/settings/project_custom_fields/new.html.erb index 1d1b501fd099..f95642bc2048 100644 --- a/app/views/admin/settings/project_custom_fields/new.html.erb +++ b/app/views/admin/settings/project_custom_fields/new.html.erb @@ -34,6 +34,11 @@ See COPYRIGHT and LICENSE files for more details. <%= error_messages_for 'custom_field' %> +<% content_controller "admin--custom-fields", + dynamic: true, + 'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config +%> + <%= labelled_tabular_form_for @custom_field, as: :custom_field, url: admin_settings_project_custom_fields_path, html: { id: 'custom_field_form' } do |f| %> diff --git a/app/views/custom_fields/_custom_options.html.erb b/app/views/custom_fields/_custom_options.html.erb index f20f6934f719..3f8b60b1f70d 100644 --- a/app/views/custom_fields/_custom_options.html.erb +++ b/app/views/custom_fields/_custom_options.html.erb @@ -86,13 +86,17 @@ See COPYRIGHT and LICENSE files for more details. > - <%= co_f.hidden_field :id, class: 'custom-option-id' %> + <%= co_f.hidden_field :id, + disabled:true, + class: 'custom-option-id' %> <%= co_f.text_field :value, + disabled: true, container_class: 'custom-option-value', no_label: true %> <%= co_f.check_box :default_value, + disabled: true, container_class: 'custom-option-default-value', data: { 'admin--custom-fields-target': 'customOptionDefaults', diff --git a/app/views/custom_fields/_form.html.erb b/app/views/custom_fields/_form.html.erb index b85a490efcdd..aa06e6d44711 100644 --- a/app/views/custom_fields/_form.html.erb +++ b/app/views/custom_fields/_form.html.erb @@ -32,9 +32,6 @@ See COPYRIGHT and LICENSE files for more details.
<%= f.text_field :name, @@ -61,7 +58,19 @@ See COPYRIGHT and LICENSE files for more details. 'admin--custom-fields-target': 'format' } %> +
> + <%= angular_component_tag "opce-enterprise-banner", + inputs: { + collapsible: true, + topMargin: true, + opReferrer: "custom-field-hierarchy", + textMessage: I18n.t("custom_fields.upsale.custom_field_format_hierarchy"), + moreInfoLink: OpenProject::Static::Links.links[:enterprise_docs][:boards][:href] + } + %> +
+
>
<%= t(:label_min_max_length) %>
@@ -91,7 +100,10 @@ See COPYRIGHT and LICENSE files for more details. <% if @custom_field.new_record? || @custom_field.multi_value_possible? %>
> <%= f.check_box :multi_value, - data: { action: 'admin--custom-fields#checkOnlyOne' } %> + data: { action: "admin--custom-fields#checkOnlyOne" } %> +
+

<%= t("custom_fields.instructions.multi_select") %>

+
> diff --git a/app/views/custom_fields/edit.html.erb b/app/views/custom_fields/edit.html.erb index b6741374f91c..cce977d02363 100644 --- a/app/views/custom_fields/edit.html.erb +++ b/app/views/custom_fields/edit.html.erb @@ -33,6 +33,11 @@ See COPYRIGHT and LICENSE files for more details. <%= error_messages_for 'custom_field' %> +<% content_controller "admin--custom-fields", + dynamic: true, + 'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config +%> + <% if @custom_field.field_format_hierarchy? %> <%= render CustomFields::DetailsComponent.new(@custom_field) %> <% else %> diff --git a/app/views/custom_fields/new.html.erb b/app/views/custom_fields/new.html.erb index eeae3a50da0a..e83345b9aee3 100644 --- a/app/views/custom_fields/new.html.erb +++ b/app/views/custom_fields/new.html.erb @@ -42,10 +42,20 @@ See COPYRIGHT and LICENSE files for more details. <%= error_messages_for 'custom_field' %> +<% content_controller "admin--custom-fields", + dynamic: true, + 'admin--custom-fields-format-config-value': OpenProject::CustomFieldFormatDependent.stimulus_config, + 'admin--custom-fields-enterprise-edition-value': EnterpriseToken.allows_to?(:custom_field_hierarchies) +%> + <%= labelled_tabular_form_for @custom_field, as: :custom_field, url: custom_fields_path, html: {id: 'custom_field_form', class: "-wide-labels"} do |f| %> <%= render partial: 'form', locals: { f: f } %> <%= hidden_field_tag 'type', @custom_field.type %> - <%= styled_button_tag t(:button_save), class: '-primary -with-icon icon-checkmark' %> + <%= styled_button_tag t(:button_save), + class: '-primary -with-icon icon-checkmark', + data: { + 'admin--custom-fields-target': 'submitButton' + } %> <% end %> diff --git a/app/views/highlighting/styles.css.erb b/app/views/highlighting/styles.css.erb index f140ef23ff0b..8f981cd72f6e 100644 --- a/app/views/highlighting/styles.css.erb +++ b/app/views/highlighting/styles.css.erb @@ -1,7 +1,10 @@ <%# Highlightable resources %> <%= resource_color_css('status', ::Status) %> <%= resource_color_css('priority', ::IssuePriority) %> -<%= resource_color_css('type', ::Type) %> +<%= resource_color_css('type', ::Type, inline_foreground: true) %> +<%# Color coded icons %> +<%= resource_color_css('life_cycle_step_definition', Project::LifeCycleStepDefinition, inline_foreground: true) %> + <%= color_css() %> <%# Overdue tasks %> diff --git a/app/views/work_package_relations_tab/_index.html.erb b/app/views/work_package_relations_tab/_index.html.erb new file mode 100644 index 000000000000..43c920b15910 --- /dev/null +++ b/app/views/work_package_relations_tab/_index.html.erb @@ -0,0 +1,6 @@ +<%= render( + WorkPackageRelationsTab::IndexComponent.new( + work_package: @work_package, + relations: @relations + ) +) %> diff --git a/config/application.rb b/config/application.rb index 31298b2ed02c..0b5c8cff7a79 100644 --- a/config/application.rb +++ b/config/application.rb @@ -75,6 +75,18 @@ class Application < Rails::Application # set to true. config.active_record.belongs_to_required_by_default = false + ### + # Enable raising on assignment to attr_readonly attributes. The previous + # behavior would allow assignment but silently not persist changes to the + # database. + # This is a rails 7.1 behaviour. + # Ideally this should be defined in the `config/initializers/new_framework_defaults_7_1.rb` + # file, but since there is a bug, that file is not loaded correctly in the production environment. + # Once [the issue](https://community.openproject.org/wp/59474) is solved, this configuration can + # be moved to the `config/initializers/new_framework_defaults_7_1.rb`. + #++ + config.active_record.raise_on_assign_to_attr_readonly = true + # Sets up logging for STDOUT and configures the default logger formatter # so that all environments receive level and timestamp information # diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb index 16fe9e0705f2..8c7c30a1bd65 100644 --- a/config/constants/settings/definition.rb +++ b/config/constants/settings/definition.rb @@ -923,6 +923,12 @@ class Definition default: "https://releases.openproject.com/v1/check.svg", writable: false }, + seed_admin_user_locked: { + description: "Lock the created admin user after seeding, so it can not be used for logging in. " \ + "If set to true, an admin user has to be created manually or through an SSO provider.", + default: false, + writable: false + }, seed_admin_user_password: { description: 'Password to set for the initially created admin user (Login remains "admin").', default: "admin", diff --git a/config/environments/test.rb b/config/environments/test.rb index f5826c7c4b1b..2ac8d639f9a1 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -26,7 +26,7 @@ # See COPYRIGHT and LICENSE files for more details. #++ -require 'active_support/core_ext/integer/time' +require "active_support/core_ext/integer/time" # The test environment is used exclusively to run your application's # test suite. You never need to work with it otherwise. Remember that @@ -52,7 +52,7 @@ # Configure public file server for tests with Cache-Control for performance. config.public_file_server.enabled = true - config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=3600' } + config.public_file_server.headers = { "Cache-Control" => "public, max-age=3600" } # Show full error reports and disable caching. config.consider_all_requests_local = true @@ -75,11 +75,11 @@ config.action_mailer.delivery_method = :test # Silence deprecations early on for testing on CI - deprecators.silenced = ENV['CI'].present? + deprecators.silenced = ENV["CI"].present? # Print deprecation notices to the stderr. config.active_support.deprecation = - if ENV['CI'] + if ENV["CI"] :silence else :stderr @@ -114,7 +114,7 @@ # Use in-memory store for testing Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new - if ENV['TEST_ENV_NUMBER'] + if ENV["TEST_ENV_NUMBER"] assets_cache_path = Rails.root.join("tmp/cache/assets/paralleltests#{ENV['TEST_ENV_NUMBER']}") config.assets.cache = Sprockets::Cache::FileStore.new(assets_cache_path) end diff --git a/config/initializers/custom_field_format.rb b/config/initializers/custom_field_format.rb index 9784807381dd..5ac81f1759f9 100644 --- a/config/initializers/custom_field_format.rb +++ b/config/initializers/custom_field_format.rb @@ -80,6 +80,7 @@ fields.register OpenProject::CustomFieldFormat.new("hierarchy", label: :label_hierarchy, + only: %w(WorkPackage), order: 12, formatter: "CustomValue::HierarchyStrategy") end diff --git a/config/initializers/feature_decisions.rb b/config/initializers/feature_decisions.rb index 371c20ae6d57..1af9d4f3b80d 100644 --- a/config/initializers/feature_decisions.rb +++ b/config/initializers/feature_decisions.rb @@ -43,6 +43,10 @@ OpenProject::FeatureDecisions.add :built_in_oauth_applications, description: "Allows the display and use of built-in OAuth applications." +OpenProject::FeatureDecisions.add :generate_pdf_from_work_package, + description: "Allows to generate a PDF document from a work package description. " \ + "See #45896 for details." + OpenProject::FeatureDecisions.add :custom_field_of_type_hierarchy, description: "Allows the use of the custom field type 'Hierarchy'." @@ -52,3 +56,6 @@ (Setting.exists?("feature_primerized_work_package_activities_active") && Setting.send(:feature_primerized_work_package_activities_active?)) end + +OpenProject::FeatureDecisions.add :stages_and_gates, + description: "Enables the under construction feature of stages and gates." diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb index e52606a27690..33bdb9cd0d25 100644 --- a/config/initializers/menus.rb +++ b/config/initializers/menus.rb @@ -546,18 +546,6 @@ icon: "op-enterprise-addons", if: proc { User.current.admin? && OpenProject::Configuration.ee_manager_visible? } - menu.push :admin_costs, - { controller: "/admin/settings", action: "show_plugin", id: :costs }, - if: Proc.new { User.current.admin? }, - caption: :project_module_costs, - icon: "op-cost-reports" - - menu.push :costs_setting, - { controller: "/admin/settings", action: "show_plugin", id: :costs }, - if: Proc.new { User.current.admin? }, - caption: :label_setting_plural, - parent: :admin_costs - menu.push :admin_backlogs, { controller: "/backlogs_settings", action: :show }, if: Proc.new { User.current.admin? }, diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb index e39bd17a2107..cda7419b65dc 100644 --- a/config/initializers/new_framework_defaults_7_1.rb +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -167,7 +167,7 @@ # behavior would allow assignment but silently not persist changes to the # database. #++ -# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true +Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true ### # Enable validating only parent-related columns for presence when the parent is mandatory. diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb index 51b4d6184a41..87f571f46a9d 100644 --- a/config/initializers/permissions.rb +++ b/config/initializers/permissions.rb @@ -224,13 +224,16 @@ "work_packages/reports": %i[report report_details], "work_packages/activities_tab": %i[index update_streams update_sorting update_filter], "work_packages/menus": %i[show], - "work_packages/hover_card": %i[show] + "work_packages/hover_card": %i[show], + work_package_relations_tab: %i[index] }, permissible_on: %i[work_package project], contract_actions: { work_packages: %i[read] } wpt.permission :add_work_packages, - {}, + { + work_package_relations: %i[new create] + }, permissible_on: :project, dependencies: :view_work_packages, contract_actions: { work_packages: %i[create] } @@ -316,13 +319,15 @@ wpt.permission :manage_work_package_relations, { - work_package_relations: %i[create destroy] + work_package_relations: %i[edit update create destroy] }, permissible_on: %i[work_package project], dependencies: :view_work_packages wpt.permission :manage_subtasks, - {}, + { + work_package_children: %i[new create destroy] + }, permissible_on: :project, dependencies: :view_work_packages # Queries diff --git a/config/locales/crowdin/af.seeders.yml b/config/locales/crowdin/af.seeders.yml index 1a0133932ff8..ba06813fff96 100644 --- a/config/locales/crowdin/af.seeders.yml +++ b/config/locales/crowdin/af.seeders.yml @@ -34,6 +34,17 @@ af: name: Grys (donker) item_13: name: Swart + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentasie @@ -70,6 +81,21 @@ af: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Laag diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml index 70918c5d3ed6..de1fd0964c60 100644 --- a/config/locales/crowdin/af.yml +++ b/config/locales/crowdin/af.yml @@ -33,7 +33,7 @@ af: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ af: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ af: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ af: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Verwyder rekening" @@ -1028,6 +1090,20 @@ af: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ af: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ af: label_environment: "Omgewing" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Voorbeeld" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ af: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/ar.seeders.yml b/config/locales/crowdin/ar.seeders.yml index 24b7203ccdfe..a8893b7e0be7 100644 --- a/config/locales/crowdin/ar.seeders.yml +++ b/config/locales/crowdin/ar.seeders.yml @@ -34,6 +34,17 @@ ar: name: رمادي (داكن) item_13: name: الأسود + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: التوثيق @@ -70,6 +81,21 @@ ar: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: منخفضة diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index a0aadbc0caa9..a0a404e3fa01 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -33,7 +33,7 @@ ar: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ ar: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ ar: single: "أو" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -664,6 +666,66 @@ ar: no_results_title_text: لا يوجد حالياً أي أنواع متاحة. version: no_results_title_text: لا يوجد حاليا أي إصدارات متوفرة. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: دعوة account: delete: "حذف الحساب" @@ -1060,6 +1122,20 @@ ar: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1967,6 +2043,23 @@ ar: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2325,6 +2418,7 @@ ar: label_environment: "بيئة" label_estimates_and_progress: "Estimates and progress" label_equals: "يكون" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "مثال" label_experimental: "شارة تجريبية" @@ -2589,6 +2683,8 @@ ar: label_related_work_packages: "مجموعات العمل ذات الصلة" label_relates: "المتعلقة ب" label_relates_to: "المتعلقة ب" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "حذف علاقة" label_relation_new: "علاقة جديدة" label_release_notes: "ملاحظات الإصدار" diff --git a/config/locales/crowdin/az.seeders.yml b/config/locales/crowdin/az.seeders.yml index 20b0d93fe91e..3a55fc4f270a 100644 --- a/config/locales/crowdin/az.seeders.yml +++ b/config/locales/crowdin/az.seeders.yml @@ -34,6 +34,17 @@ az: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ az: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml index 616066243227..8243c829fe5c 100644 --- a/config/locales/crowdin/az.yml +++ b/config/locales/crowdin/az.yml @@ -33,7 +33,7 @@ az: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ az: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ az: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ az: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ az: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ az: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ az: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ az: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/be.seeders.yml b/config/locales/crowdin/be.seeders.yml index 1ccd09e6d716..9b0aa35e6dae 100644 --- a/config/locales/crowdin/be.seeders.yml +++ b/config/locales/crowdin/be.seeders.yml @@ -34,6 +34,17 @@ be: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ be: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml index 326f71a20347..36a5480e7c0d 100644 --- a/config/locales/crowdin/be.yml +++ b/config/locales/crowdin/be.yml @@ -33,7 +33,7 @@ be: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ be: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ be: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -648,6 +650,66 @@ be: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1044,6 +1106,20 @@ be: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1895,6 +1971,23 @@ be: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2253,6 +2346,7 @@ be: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2517,6 +2611,8 @@ be: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/bg.seeders.yml b/config/locales/crowdin/bg.seeders.yml index e37724895544..40ee59d99231 100644 --- a/config/locales/crowdin/bg.seeders.yml +++ b/config/locales/crowdin/bg.seeders.yml @@ -34,6 +34,17 @@ bg: name: Тъмно сиво item_13: name: Черно + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Документация @@ -70,6 +81,21 @@ bg: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Нисък diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml index 3b188fc1b9b6..16fe66e6ae2b 100644 --- a/config/locales/crowdin/bg.yml +++ b/config/locales/crowdin/bg.yml @@ -33,7 +33,7 @@ bg: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ bg: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > За да добавите нови потребителски полета към даден проект, първо трябва да ги създадете, преди да можете да ги добавите към този проект. is_enabled_globally: "Активирано е глобално" @@ -265,20 +267,20 @@ bg: single: "или" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ bg: no_results_title_text: В момента има няма типове на разположение. version: no_results_title_text: В момента няма налични версии. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Покана account: delete: "Изтриване на профил" @@ -1028,6 +1090,20 @@ bg: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ bg: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ bg: label_environment: "Среда" label_estimates_and_progress: "Оценки и напредък" label_equals: "е" + label_equals_with_descendants: "is any with descendants" label_everywhere: "навсякъде" label_example: "Пример" label_experimental: "Експериментален" @@ -2445,6 +2539,8 @@ bg: label_related_work_packages: "Свързани работени пакети" label_relates: "свързани с" label_relates_to: "свързани с" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Изтриване на връзка" label_relation_new: "Нова връзка" label_release_notes: "Бележки по изданието" diff --git a/config/locales/crowdin/ca.seeders.yml b/config/locales/crowdin/ca.seeders.yml index 6e1a9d38c2c4..566db78036cb 100644 --- a/config/locales/crowdin/ca.seeders.yml +++ b/config/locales/crowdin/ca.seeders.yml @@ -34,6 +34,17 @@ ca: name: Gris (fosc) item_13: name: Negre + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentació @@ -70,6 +81,21 @@ ca: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Baixa diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml index 72570ff4d529..b7bb86d49e2a 100644 --- a/config/locales/crowdin/ca.yml +++ b/config/locales/crowdin/ca.yml @@ -33,7 +33,7 @@ ca: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -236,6 +236,8 @@ ca: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Per afegir nous camps personalitzats a un projecte primer has de crear-los abans de poder-los afegir a aquest projecte. is_enabled_globally: "És habilitat globalment" @@ -262,20 +264,20 @@ ca: single: "o" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -628,6 +630,66 @@ ca: no_results_title_text: Actualment no hi ha cap classe disponible. version: no_results_title_text: Hi ha actualment cap versió disponible. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitació account: delete: "Elimina el compte" @@ -1024,6 +1086,20 @@ ca: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1819,6 +1895,23 @@ ca: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponible (opcional)" @@ -2177,6 +2270,7 @@ ca: label_environment: "Entorn" label_estimates_and_progress: "Estimates and progress" label_equals: "és" + label_equals_with_descendants: "is any with descendants" label_everywhere: "a tot arreu" label_example: "Exemple" label_experimental: "Experimental" @@ -2441,6 +2535,8 @@ ca: label_related_work_packages: "Paquets de treball relacionats" label_relates: "relacionat amb" label_relates_to: "relacionat amb" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Suprimir relació" label_relation_new: "Nova Relació" label_release_notes: "Notes de llançament" diff --git a/config/locales/crowdin/ckb-IR.seeders.yml b/config/locales/crowdin/ckb-IR.seeders.yml index b39c2d26124f..69f25799ecee 100644 --- a/config/locales/crowdin/ckb-IR.seeders.yml +++ b/config/locales/crowdin/ckb-IR.seeders.yml @@ -34,6 +34,17 @@ ckb-IR: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ ckb-IR: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml index 34686405eb3e..5c277918eac6 100644 --- a/config/locales/crowdin/ckb-IR.yml +++ b/config/locales/crowdin/ckb-IR.yml @@ -33,7 +33,7 @@ ckb-IR: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ ckb-IR: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ ckb-IR: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ ckb-IR: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ ckb-IR: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ ckb-IR: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ ckb-IR: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ ckb-IR: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/cs.seeders.yml b/config/locales/crowdin/cs.seeders.yml index 7cfb555f71e0..bbf4cc05ebb4 100644 --- a/config/locales/crowdin/cs.seeders.yml +++ b/config/locales/crowdin/cs.seeders.yml @@ -34,6 +34,17 @@ cs: name: Šedá (tmavá) item_13: name: Černá + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentace @@ -70,6 +81,21 @@ cs: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Nízká diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml index 45eeb3f98088..11bcf84caaaf 100644 --- a/config/locales/crowdin/cs.yml +++ b/config/locales/crowdin/cs.yml @@ -33,10 +33,10 @@ cs: label_activity_show_only_changes: "Zobrazit pouze změny" label_sort_asc: "Nejnovější v dolní části" label_sort_desc: "Nejnovější nahoře" - label_type_to_comment: "Pro komentování pište zde" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Odeslat komentář" changed_on: "změněno dne" - created_on: "created this on" + created_on: "toto vytvořil/a dne" changed: "změněno" created: "vytvořeno" commented: "komentováno" @@ -224,7 +224,7 @@ cs: actions: "Akce položky" blankslate: root: - title: "Your list of items is empty" + title: "Váš seznam položek je prázdný" description: "Start by adding items to the custom field of type hierarchy. Each item can be used to create a hierarchy bellow it. To navigate and create sub-items inside a hierarchy click on the created item." item: title: This item doesn't have any hierarchy level below @@ -239,6 +239,8 @@ cs: zero: žádné dílčí položky one: 1 dílčí položka other: "%{count} dílčí položky" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > 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" @@ -265,26 +267,26 @@ cs: single: "nebo" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "musí být celé číslo" + filled?: "musí být vyplněno" + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: - depth: "Depth" - item: "Item" - label: "Label" - short: "Short name" - parent: "Parent" + depth: "Hloubka" + item: "Položka" + label: "Popisek" + short: "Krátký název" + parent: "Nadřazený" global_search: placeholder: "Hledat v %{app_title}" overwritten_tabs: @@ -648,6 +650,66 @@ cs: no_results_title_text: V současné době nejsou k dispozici žádné typy. version: no_results_title_text: V současné době nejsou k dispozici žádné verze. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Pozvánka account: delete: "Odstranit účet" @@ -1044,6 +1106,20 @@ cs: attributes: project_ids: blank: "Vyberte prosím projekt." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1895,6 +1971,23 @@ cs: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext k dispozici (volitelné)" @@ -2253,6 +2346,7 @@ cs: label_environment: "Prostředí" label_estimates_and_progress: "Odhady a posup" label_equals: "je" + label_equals_with_descendants: "is any with descendants" label_everywhere: "všude" label_example: "Příklad" label_experimental: "Experimentální" @@ -2517,6 +2611,8 @@ cs: label_related_work_packages: "Související pracovní balíčky" label_relates: "související s" label_relates_to: "související s" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Odstranit vztah" label_relation_new: "Nový vztah" label_release_notes: "Poznámky k verzi" diff --git a/config/locales/crowdin/da.seeders.yml b/config/locales/crowdin/da.seeders.yml index 19b036c71dbc..8633314d30c3 100644 --- a/config/locales/crowdin/da.seeders.yml +++ b/config/locales/crowdin/da.seeders.yml @@ -34,6 +34,17 @@ da: name: Grå (mørk) item_13: name: Sort + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ da: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Lav diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml index 07f03fcfbffb..80fdcdf95e9b 100644 --- a/config/locales/crowdin/da.yml +++ b/config/locales/crowdin/da.yml @@ -33,7 +33,7 @@ da: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -237,6 +237,8 @@ da: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > For at tilføje nye brugerdefinerede felter til et projekt, skal du først oprette dem, før du kan føje dem til dette projekt. is_enabled_globally: "Er aktiveret globalt" @@ -263,20 +265,20 @@ da: single: "eller" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -630,6 +632,66 @@ da: no_results_title_text: Der er i øjeblikket ingen tilgængelige typer. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Slet konto" @@ -1026,6 +1088,20 @@ da: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1821,6 +1897,23 @@ da: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2179,6 +2272,7 @@ da: label_environment: "Miljø" label_estimates_and_progress: "Estimates and progress" label_equals: "er" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Eksempel" label_experimental: "Eksperimental" @@ -2443,6 +2537,8 @@ da: label_related_work_packages: "Forbundne arbejdspakker" label_relates: "Forbundet til" label_relates_to: "Forbundet til" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Slet forbindelse" label_relation_new: "Ny forbindelse" label_release_notes: "Udgivelsesnoter" diff --git a/config/locales/crowdin/de.seeders.yml b/config/locales/crowdin/de.seeders.yml index fb9a79295154..eb4a94235c39 100644 --- a/config/locales/crowdin/de.seeders.yml +++ b/config/locales/crowdin/de.seeders.yml @@ -34,6 +34,17 @@ de: name: Grau (dunkel) item_13: name: Schwarz + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Lila + item_2: + name: PM2 Rot + item_3: + name: PM2 Rosa + item_4: + name: PM2 Grüngelb document_categories: item_0: name: Dokumentation @@ -70,6 +81,21 @@ de: item_1: name: Globale Standardrolle standard: + life_cycles: + item_0: + name: Initiierung + item_1: + name: Bereit für Planung + item_2: + name: Planung + item_3: + name: Bereit für Durchführung + item_4: + name: Durchführung + item_5: + name: Bereit für Abschluss + item_6: + name: Abschluss priorities: item_0: name: Niedrig diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml index 7c22ff0a024b..f0ce8b5fb5d6 100644 --- a/config/locales/crowdin/de.yml +++ b/config/locales/crowdin/de.yml @@ -33,7 +33,7 @@ de: label_activity_show_only_changes: "Nur Änderungen anzeigen" label_sort_asc: "Neueste unten" label_sort_desc: "Neueste oben" - label_type_to_comment: "Tippen Sie hier, um zu kommentieren" + label_type_to_comment: "Einen Kommentar hinzufügen. @ tippen, um Personen zu benachrichtigen." label_submit_comment: "Kommentar absenden" changed_on: "geändert am" created_on: "erstellte dies am" @@ -236,6 +236,8 @@ de: zero: keine Unterelemente one: 1 Unterelement other: "%{count} Unterelemente" + upsale: + custom_field_format_hierarchy: "Benötigen Sie eine Hierarchie in den benutzerdefinierten Feldern ihrer Arbeitspakete?" text_add_new_custom_field: > Um neue benutzerdefinierte Felder einem Projekt zuzuweisen, müssen Sie diese erst global erstellen, um Sie dann an dieser Stelle aktivieren zu können. is_enabled_globally: "Für alle Projekte aktiviert" @@ -262,26 +264,26 @@ de: single: "oder" dry_validation: errors: - integer?: "muss eine ganze Zahl sein" - filled?: "muss ausgefüllt sein" - greater_or_equal_zero: "muss größer oder gleich 0 sein" - not_found: "nicht gefunden" + int?: "muss eine ganze Zahl sein." + filled?: "muss ausgefüllt werden." + greater_or_equal_zero: "muss größer oder gleich 0 sein." + not_found: "nicht gefunden." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "kann keine Hierarchiewurzel sein." + not_persisted: "muss ein bereits vorhandenes Element sein." label: - not_unique: "muss innerhalb der gleichen Hierarchieebene eindeutig sein" + not_unique: "muss innerhalb der gleichen Hierarchieebene eindeutig sein." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "muss innerhalb der gleichen Hierarchieebene eindeutig sein." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "muss ein Abkömmling der Hierarchiewurzel sein." rules: - depth: "Depth" - item: "Item" + depth: "Tiefe" + item: "Element" label: "Bezeichnung" - short: "Short name" - parent: "Parent" + short: "Kurzname" + parent: "Übergeordnetes Arbeitspaket" global_search: placeholder: "Suche in %{app_title}" overwritten_tabs: @@ -625,6 +627,66 @@ de: no_results_title_text: Derzeit stehen keine Typen zur Verfügung. version: no_results_title_text: Derzeit sind keine Versionen verfügbar. + work_package_relations_tab: + index: + action_bar_title: "Fügen Sie eine Beziehung mit einem anderen Arbeitspaket hinzu, um eine Verbindung zwischen ihnen herzustellen." + no_results_title_text: Derzeit sind keine Beziehungen verfügbar. + blankslate_heading: "Keine Beziehungen" + blankslate_description: "Dieses Arbeitspaket hat noch keine Beziehungen." + label_add_x: "%{x} hinzufügen" + label_edit_x: "%{x} editieren" + label_add_description: "Beschreibung hinzufügen" + relations: + label_relates_singular: "Beziehung mit" + label_relates_plural: "Beziehungen mit" + label_relates_to_singular: "Beziehung mit" + label_relates_to_plural: "Beziehung mit" + relates_description: "Erstellt eine sichtbare Beziehung zwischen den zwei Arbeitspaketen ohne weitere Auswirkungen" + relates_to_description: "Erstellt eine sichtbare Beziehung zwischen den zwei Arbeitspaketen ohne weitere Auswirkungen" + label_precedes_singular: "Nachfolger" + label_precedes_plural: "Nachfolger" + precedes_description: "Das verknüpfte Arbeitspaket kann erst nach dem Ende dieses Arbeitspakets starten" + label_follows_singular: "Vorgänger" + label_follows_plural: "Vorgänger" + follows_description: "Das verknüpfte Arbeitspaket muss beendet sein bevor dieses Arbeitspaket starten kann" + label_child_singular: "Untergeordnetes Arbeitspaket" + label_child_plural: "Untergeordnete Arbeitspakete" + child_description: "Ordnet das verknüpfte Arbeitspaket diesem Arbeitspaket unter" + label_blocks_singular: "Blockiert" + label_blocks_plural: "Blockiert" + blocks_description: "Das verknüpfte Arbeitspaket kann erst geschlossen werden, wenn dieses Arbeitspaket geschlossen ist" + label_blocked_singular: "Blockiert durch" + label_blocked_plural: "Blockiert durch" + label_blocked_by_singular: "Blockiert durch" + label_blocked__by_plural: "Blockiert durch" + blocked_description: "Dieses Arbeitspaket kann erst geschlossen werden, nachdem das verknüpfte Arbeitspaket geschlossen wurde" + blocked_by_description: "Dieses Arbeitspaket kann erst geschlossen werden, nachdem das verknüpfte Arbeitspaket geschlossen wurde" + label_duplicates_singular: "Dupliziert" + label_duplicates_plural: "Dupliziert" + duplicates_description: "Dies ist eine Kopie des verknüpften Arbeitspakets" + label_duplicated_singular: "Dupliziert durch" + label_duplicated_plural: "Dupliziert durch" + label_duplicated_by_singular: "Dupliziert durch" + label_duplicated_by_plural: "Dupliziert durch" + duplicated_by_description: "Das zugehörige Arbeitspaket ist eine Kopie dieses Arbeitspakets" + duplicated_description: "Das zugehörige Arbeitspaket ist eine Kopie dieses Arbeitspakets" + label_includes_singular: "Beinhaltet" + label_includes_plural: "Beinhaltet" + includes_description: "Das verknüpfte Arbeitspaket beinhaltet dieses Arbeitspaket, ohne dass dies zusätzliche Auswirkungen hat" + label_partof_singular: "Teil von" + label_partof_plural: "Teil von" + label_part_of_singular: "Teil von" + label_part_of_plural: "Teil von" + partof_description: "Dieses Arbeitspaket enthält das verknüpfte Arbeitspaket, ohne dass dies zusätzliche Auswirkungen hat" + part_of_description: "Dieses Arbeitspaket enthält das verknüpfte Arbeitspaket, ohne dass dies zusätzliche Auswirkungen hat" + label_requires_singular: "Benötigt" + label_requires_plural: "Benötigt" + requires_description: "Markiert dieses Arbeitspaket als Voraussetzung für das verknüpfte Arbeitspaket" + label_required_singular: "Benötigt von" + label_required_plural: "Benötigt von" + required_description: "Markiert dieses Arbeitspaket als Voraussetzung für das verknüpfte Arbeitspaket" + label_parent_singular: "Übergeordnetes Arbeitspaket" + label_parent_plural: "Übergeordnete Arbeitspakete" label_invitation: Einladung account: delete: "Konto löschen" @@ -1021,6 +1083,20 @@ de: attributes: project_ids: blank: "Bitte wählen Sie ein Projekt aus." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "muss entweder ein Project::StageDefinition oder Project::GateDefinition sein" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "muss entweder ein Project::Stage oder Project::Gate sein" + must_be_a_stage: "muss ein Project::Stage sein" + must_be_a_gate: "muss ein Project::Gate sein" + project/gate: + attributes: + base: + end_date_not_allowed: "Einem Project::Gate kann kein `end_date` zugewiesen werden" query: attributes: project: @@ -1816,6 +1892,23 @@ de: units: hours: h days: d + pdf_generator: + page_nr_footer: "Seite %{page} von %{total}" + dialog: + title: PDF generieren + submit: Generieren + header_right: + label: Kopfzeile rechts + caption: Text, der rechts neben der Kopfzeile angezeigt werden soll + footer_center: + label: Fußzeile mittig + caption: Text, der in der Mitte der Fußzeile angezeigt werden soll + hyphenation: + label: Silbentrennung + caption: Wörter zwischen den Zeilen umbrechen, um die Textausrichtung und die Lesbarkeit zu verbessern. + paper_size: + label: Papierformat + caption: Die Größe des Papiers, das für das PDF verwendet werden soll. extraction: available: pdftotext: "Pdftotext verfügbar (optional)" @@ -2174,6 +2267,7 @@ de: label_environment: "Umgebung" label_estimates_and_progress: "Schätzungen und Fortschritt" label_equals: "ist" + label_equals_with_descendants: "ist (ODER) inkl. Unterelementen " label_everywhere: "überall" label_example: "Beispiel" label_experimental: "Experimentel" @@ -2438,6 +2532,8 @@ de: label_related_work_packages: "Zugehörige Arbeitspakete" label_relates: "Verwandt mit" label_relates_to: "Verwandt mit" + label_relation: "Beziehung" + label_relation_actions: "Beziehungsaktionen" label_relation_delete: "Beziehung löschen" label_relation_new: "Neue Beziehung" label_release_notes: "Release Notes" @@ -2836,9 +2932,9 @@ de: notice_locking_conflict: "Die Informationen wurde zwischenzeitlich von einem anderen Benutzer geändert." notice_locking_conflict_additional_information: "Die Änderung(en) wurde(n) durchgeführt von %{users}." notice_locking_conflict_reload_page: "Bitte laden Sie die Seite neu, prüfen Sie die Anpassungen und geben Sie Ihre Änderungen noch einmal ein." - notice_locking_conflict_warning: "This page has been updated by someone else. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_danger: "Could not save your changes because of conflicting modifications. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_action_button: "Discard changes and reload" + notice_locking_conflict_warning: "Diese Seite wurde von jemand anderem aktualisiert. Um Ihre Änderungen nicht zu verlieren, kopieren Sie sie lokal und laden Sie sie erneut, um die aktualisierte Version anzuzeigen." + notice_locking_conflict_danger: "Ihre Änderungen konnten wegen in Konflikt stehender Änderungen nicht gespeichert werden. Um Ihre Änderungen nicht zu verlieren, kopieren Sie sie lokal und laden Sie sie erneut, um die aktualisierte Version anzuzeigen." + notice_locking_conflict_action_button: "Änderungen verwerfen und neu laden" notice_member_added: '%{name} zum Projekt hinzugefügt.' notice_members_added: '%{number} Benutzer zum Projekt hinzugefügt.' notice_member_removed: "%{user} aus dem Projekt entfernt." diff --git a/config/locales/crowdin/el.seeders.yml b/config/locales/crowdin/el.seeders.yml index f66e11f53c33..9e4d42390f91 100644 --- a/config/locales/crowdin/el.seeders.yml +++ b/config/locales/crowdin/el.seeders.yml @@ -34,6 +34,17 @@ el: name: Γκρι (σκούρο) item_13: name: Μαύρο + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Τεκμηρίωση @@ -70,6 +81,21 @@ el: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Χαμηλή diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml index 877268cfc21e..4f10230940bd 100644 --- a/config/locales/crowdin/el.yml +++ b/config/locales/crowdin/el.yml @@ -33,7 +33,7 @@ el: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -235,6 +235,8 @@ el: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Για να προσθέσετε νέα προσαρμοσμένα πεδία σε ένα έργο, πρέπει πρώτα να τα δημιουργήσετε για να τα προσθέσετε σε αυτό το έργο. is_enabled_globally: "Είναι ενεργοποιημένο σε όλο το σύστημα" @@ -261,20 +263,20 @@ el: single: "ή" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -628,6 +630,66 @@ el: no_results_title_text: Προς το παρόν δεν υπάρχουν διαθέσιμοι τύποι. version: no_results_title_text: Προς το παρόν δεν υπάρχουν διαθέσιμες εκδόσεις. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Πρόσκληση account: delete: "Διαγραφή λογαριασμού" @@ -1024,6 +1086,20 @@ el: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1819,6 +1895,23 @@ el: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Το Pdftotext είναι διαθέσιμο (προαιρετικό)" @@ -2177,6 +2270,7 @@ el: label_environment: "Περιβάλλον" label_estimates_and_progress: "Estimates and progress" label_equals: "είναι" + label_equals_with_descendants: "is any with descendants" label_everywhere: "παντού" label_example: "Παράδειγμα" label_experimental: "Πειραματικό" @@ -2441,6 +2535,8 @@ el: label_related_work_packages: "Σχετικά πακέτα εργασίας" label_relates: "σχετίζεται με" label_relates_to: "σχετίζεται με" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Διαγραφή συσχέτισης" label_relation_new: "Νέα συσχέτιση" label_release_notes: "Σημειώσεις έκδοσης" diff --git a/config/locales/crowdin/eo.seeders.yml b/config/locales/crowdin/eo.seeders.yml index a44603386b6a..988c8867d4b2 100644 --- a/config/locales/crowdin/eo.seeders.yml +++ b/config/locales/crowdin/eo.seeders.yml @@ -34,6 +34,17 @@ eo: name: Griza (malhela) item_13: name: Nigra + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentado @@ -70,6 +81,21 @@ eo: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Malalta diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml index 702304a4f84e..0c3f35431547 100644 --- a/config/locales/crowdin/eo.yml +++ b/config/locales/crowdin/eo.yml @@ -33,7 +33,7 @@ eo: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ eo: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Ĉie ŝaltita" @@ -265,20 +267,20 @@ eo: single: "aŭ" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ eo: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invito account: delete: "Forigi konton" @@ -1028,6 +1090,20 @@ eo: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ eo: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdfaltekto disponebla (nedeviga)" @@ -2181,6 +2274,7 @@ eo: label_environment: "Medio" label_estimates_and_progress: "Estimates and progress" label_equals: "estas" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Ekzemplo" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ eo: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/es.seeders.yml b/config/locales/crowdin/es.seeders.yml index d9958b5cc5c8..802fcff4a1e8 100644 --- a/config/locales/crowdin/es.seeders.yml +++ b/config/locales/crowdin/es.seeders.yml @@ -34,6 +34,17 @@ es: name: Gris (oscuro) item_13: name: Negro + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentación @@ -70,6 +81,21 @@ es: item_1: name: Rol global estándar standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Baja diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml index d13df8d8e3f9..fb159873968e 100644 --- a/config/locales/crowdin/es.yml +++ b/config/locales/crowdin/es.yml @@ -33,7 +33,7 @@ es: label_activity_show_only_changes: "Mostrar solo los cambios" label_sort_asc: "Lo más reciente en la parte inferior" label_sort_desc: "Lo más reciente en la parte superior" - label_type_to_comment: "Escriba aquí para comentar" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Enviar comentario" changed_on: "cambiado el" created_on: "creó esto el" @@ -236,6 +236,8 @@ es: zero: ningún subelemento one: 1 subelemento other: "%{count} subelementos" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Para agregar nuevos campos personalizados a un proyecto, primero debe crearlos, y luego añadirlos a este proyecto. is_enabled_globally: "Está activado a nivel global" @@ -262,20 +264,20 @@ es: single: "o bien" dry_validation: errors: - integer?: "debe ser un número entero" - filled?: "debe rellenarse" - greater_or_equal_zero: "debe ser mayor o igual a 0" - not_found: "no encontrado" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "no puede ser un elemento raíz" - not_persisted: "debe ser un elemento ya existente" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "debe ser único dentro del mismo nivel de jerarquía" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "debe ser único dentro del mismo nivel de jerarquía" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "debe ser descendiente de la raíz de la jerarquía" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Profundidad" item: "Elemento" @@ -629,6 +631,66 @@ es: no_results_title_text: Actualmente no hay tipos de paquete disponibles. version: no_results_title_text: No hay versiones disponibles por el momento. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitación account: delete: "Borrar cuenta" @@ -1025,6 +1087,20 @@ es: attributes: project_ids: blank: "Por favor, selecciona un proyecto." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1820,6 +1896,23 @@ es: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponible (opcional)" @@ -2178,6 +2271,7 @@ es: label_environment: "Entorno" label_estimates_and_progress: "Estimaciones y progreso" label_equals: "es" + label_equals_with_descendants: "is any with descendants" label_everywhere: "todo" label_example: "Ejemplo" label_experimental: "Experimental" @@ -2442,6 +2536,8 @@ es: label_related_work_packages: "Paquetes de trabajo relacionados" label_relates: "relacionado con" label_relates_to: "relacionado con" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Eliminar relación" label_relation_new: "Nueva relación" label_release_notes: "Notas de lanzamiento" diff --git a/config/locales/crowdin/et.seeders.yml b/config/locales/crowdin/et.seeders.yml index 3e52442b2075..7eeda9076d9c 100644 --- a/config/locales/crowdin/et.seeders.yml +++ b/config/locales/crowdin/et.seeders.yml @@ -34,6 +34,17 @@ et: name: Hall (tume) item_13: name: Must + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ et: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Aega on diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml index e5e222c87fef..675a403bcc2c 100644 --- a/config/locales/crowdin/et.yml +++ b/config/locales/crowdin/et.yml @@ -33,7 +33,7 @@ et: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ et: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ et: single: "või" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ et: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Kutse account: delete: "Kustuta konto" @@ -1028,6 +1090,20 @@ et: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ et: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ et: label_environment: "Keskkond" label_estimates_and_progress: "Estimates and progress" label_equals: "võrdub" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Näide" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ et: label_related_work_packages: "Seotud teemad" label_relates: "seotud" label_relates_to: "seotud" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Kustuta seos" label_relation_new: "Uus seos" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/eu.seeders.yml b/config/locales/crowdin/eu.seeders.yml index f99a4011426e..6dbcc6d929c9 100644 --- a/config/locales/crowdin/eu.seeders.yml +++ b/config/locales/crowdin/eu.seeders.yml @@ -34,6 +34,17 @@ eu: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentazioa @@ -70,6 +81,21 @@ eu: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml index 4ee2069d8177..d55207d08642 100644 --- a/config/locales/crowdin/eu.yml +++ b/config/locales/crowdin/eu.yml @@ -33,7 +33,7 @@ eu: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ eu: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ eu: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ eu: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ eu: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ eu: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ eu: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ eu: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/fa.seeders.yml b/config/locales/crowdin/fa.seeders.yml index ee47d6e33b96..3fb3f11ecf05 100644 --- a/config/locales/crowdin/fa.seeders.yml +++ b/config/locales/crowdin/fa.seeders.yml @@ -34,6 +34,17 @@ fa: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ fa: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: کم diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml index 40b8e93d13bf..72e94acf9f01 100644 --- a/config/locales/crowdin/fa.yml +++ b/config/locales/crowdin/fa.yml @@ -33,7 +33,7 @@ fa: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ fa: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ fa: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ fa: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: دعوت نامه account: delete: "حذف حساب کاربری" @@ -1028,6 +1090,20 @@ fa: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ fa: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ fa: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ fa: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/fi.seeders.yml b/config/locales/crowdin/fi.seeders.yml index 7da943e4aeab..ef183484f6ff 100644 --- a/config/locales/crowdin/fi.seeders.yml +++ b/config/locales/crowdin/fi.seeders.yml @@ -34,6 +34,17 @@ fi: name: Harmaa (tumma) item_13: name: Musta + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Käyttöohjeet @@ -70,6 +81,21 @@ fi: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Matala diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml index 90b11e2f0704..6a2f40f432fc 100644 --- a/config/locales/crowdin/fi.yml +++ b/config/locales/crowdin/fi.yml @@ -33,7 +33,7 @@ fi: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ fi: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Jotta voit lisätä tälle projektille uusia muokattavia kenttiä, tulee sinun ensin luoda ne. is_enabled_globally: "On käytössä kaikkialla" @@ -265,20 +267,20 @@ fi: single: "tai" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ fi: no_results_title_text: Tällä hetkellä tyyppejä ei ole saatavilla. version: no_results_title_text: Tällä hetkellä versioita ei ole saatavilla. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Kutsu account: delete: "Poista tili" @@ -1028,6 +1090,20 @@ fi: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ fi: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ fi: label_environment: "Ympäristö" label_estimates_and_progress: "Estimates and progress" label_equals: "on" + label_equals_with_descendants: "is any with descendants" label_everywhere: "kaikkialla" label_example: "Esimerkki" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ fi: label_related_work_packages: "Tehtävän riippuvuudet" label_relates: "liittyy" label_relates_to: "liittyy" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Poista riippuvuus" label_relation_new: "Uusi riippuvuus" label_release_notes: "Julkaisutiedot" diff --git a/config/locales/crowdin/fil.seeders.yml b/config/locales/crowdin/fil.seeders.yml index c039bf70a2f0..ae8647e85e25 100644 --- a/config/locales/crowdin/fil.seeders.yml +++ b/config/locales/crowdin/fil.seeders.yml @@ -34,6 +34,17 @@ fil: name: Grey (madilim) item_13: name: Itim + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentasyon @@ -70,6 +81,21 @@ fil: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Mababa diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml index 34ed98dca619..089711d09815 100644 --- a/config/locales/crowdin/fil.yml +++ b/config/locales/crowdin/fil.yml @@ -33,7 +33,7 @@ fil: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ fil: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Upang magdagdag ng mga kustom na patlang sa isang proyekto kinakailangan mo muna likhain bago ka muna sila idagdag sa proyektong ito. is_enabled_globally: "Ay pinagana pandaigdigan" @@ -265,20 +267,20 @@ fil: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ fil: no_results_title_text: Sa kasalukuyan ay walang mga uri na available. version: no_results_title_text: Walang kasalukuyang bersyon ang magagamit. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Imbitasyon account: delete: "Alisin ang akawnt" @@ -1028,6 +1090,20 @@ fil: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ fil: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext ay magagamit (opsyonal)" @@ -2181,6 +2274,7 @@ fil: label_environment: "Kalikasan" label_estimates_and_progress: "Estimates and progress" label_equals: "ay" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Halimbawa" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ fil: label_related_work_packages: "Nauugnay sa mga work package" label_relates: "nauugnay sa" label_relates_to: "nauugnay sa" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Burahin ang relasyon" label_relation_new: "Bagong relasyon" label_release_notes: "Paglabas ng mga talaan" diff --git a/config/locales/crowdin/fr.seeders.yml b/config/locales/crowdin/fr.seeders.yml index 9d93e97255df..bb76409aebb7 100644 --- a/config/locales/crowdin/fr.seeders.yml +++ b/config/locales/crowdin/fr.seeders.yml @@ -34,6 +34,17 @@ fr: name: Gris (foncé) item_13: name: Noir + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ fr: item_1: name: Rôle global standard standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Basse diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml index 84f5084e189a..a03acb2c154b 100644 --- a/config/locales/crowdin/fr.yml +++ b/config/locales/crowdin/fr.yml @@ -33,7 +33,7 @@ fr: label_activity_show_only_changes: "Afficher uniquement les modifications" label_sort_asc: "Les plus récents en bas" label_sort_desc: "Les plus récents en haut" - label_type_to_comment: "Saisissez ici votre commentaire" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Envoyer le commentaire" changed_on: "modifié le" created_on: "a créé ce lot de travaux le" @@ -239,6 +239,8 @@ fr: zero: aucun sous-élément one: 1 sous-élément other: "%{count} sous-éléments" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Pour ajouter de nouveaux champs personnalisés à un projet, vous devez d’abord les créer avant de pouvoir les ajouter à ce projet. is_enabled_globally: "Est activé globalement" @@ -265,20 +267,20 @@ fr: single: "ou" dry_validation: errors: - integer?: "doit être un nombre entier" - filled?: "doit être renseigné" - greater_or_equal_zero: "doit être supérieur ou égal à 0" - not_found: "introuvable" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "ne peut pas être un élément racine" - not_persisted: "doit être un élément déjà existant" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "doit être unique au sein d'un même niveau hiérarchique" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "doit être unique au sein d'un même niveau hiérarchique" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "doit être un descendant de la racine de la hiérarchie" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Profondeur" item: "Élément" @@ -630,6 +632,66 @@ fr: no_results_title_text: Il n'y a actuellement aucun type disponible. version: no_results_title_text: Il n'y a actuellement aucune version disponible. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Supprimer le compte" @@ -1026,6 +1088,20 @@ fr: attributes: project_ids: blank: "Veuillez sélectionner un projet." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1821,6 +1897,23 @@ fr: units: hours: h days: j + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponible (optionnel)" @@ -2179,6 +2272,7 @@ fr: label_environment: "Environement" label_estimates_and_progress: "Estimations et progression" label_equals: "est" + label_equals_with_descendants: "is any with descendants" label_everywhere: "partout" label_example: "Exemple" label_experimental: "Expérimental" @@ -2443,6 +2537,8 @@ fr: label_related_work_packages: "Lots de Travaux associés" label_relates: "En relation avec" label_relates_to: "En relation avec" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Supprimer la relation" label_relation_new: "Nouvelle relation" label_release_notes: "Notes de version" diff --git a/config/locales/crowdin/he.seeders.yml b/config/locales/crowdin/he.seeders.yml index 09658ff82b4d..55f8cc76c61f 100644 --- a/config/locales/crowdin/he.seeders.yml +++ b/config/locales/crowdin/he.seeders.yml @@ -34,6 +34,17 @@ he: name: אפור (כהה) item_13: name: שחור + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ he: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: נמוך diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml index 93b439f23e36..68e63bdbb081 100644 --- a/config/locales/crowdin/he.yml +++ b/config/locales/crowdin/he.yml @@ -33,7 +33,7 @@ he: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ he: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ he: single: "או" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -648,6 +650,66 @@ he: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "מחק חשבון" @@ -1044,6 +1106,20 @@ he: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1895,6 +1971,23 @@ he: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2253,6 +2346,7 @@ he: label_environment: "סביבה" label_estimates_and_progress: "Estimates and progress" label_equals: "הינו" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "דוגמה" label_experimental: "Experimental" @@ -2517,6 +2611,8 @@ he: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/hi.seeders.yml b/config/locales/crowdin/hi.seeders.yml index ca87b8e9af03..20b5e9fc5fa3 100644 --- a/config/locales/crowdin/hi.seeders.yml +++ b/config/locales/crowdin/hi.seeders.yml @@ -34,6 +34,17 @@ hi: name: धूसर (डार्क) item_13: name: काला + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ hi: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: निम्न diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml index 5e372d03eaff..e7ab6f56f39d 100644 --- a/config/locales/crowdin/hi.yml +++ b/config/locales/crowdin/hi.yml @@ -33,7 +33,7 @@ hi: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ hi: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > परियोजना में नई custom fields जोडनें हेतु, पहले आपको उनका सृजन करना पडेगा, तत्पष्चात ही आप उन्हें परियोजना में जोड सकेंगे. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ hi: single: "या" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -630,6 +632,66 @@ hi: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "खाता हटाएं" @@ -1026,6 +1088,20 @@ hi: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1821,6 +1897,23 @@ hi: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext उपलब्ध (वैकल्पिक)" @@ -2179,6 +2272,7 @@ hi: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2443,6 +2537,8 @@ hi: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/hr.seeders.yml b/config/locales/crowdin/hr.seeders.yml index ed01578a116d..6a33cfdaa29f 100644 --- a/config/locales/crowdin/hr.seeders.yml +++ b/config/locales/crowdin/hr.seeders.yml @@ -34,6 +34,17 @@ hr: name: Siva (tamna) item_13: name: Crna + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentacija @@ -70,6 +81,21 @@ hr: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Nizak diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml index 9ec55d64894d..2759fb4b6387 100644 --- a/config/locales/crowdin/hr.yml +++ b/config/locales/crowdin/hr.yml @@ -33,7 +33,7 @@ hr: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ hr: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ hr: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -640,6 +642,66 @@ hr: no_results_title_text: Trenutno nema dostupnih tipova. version: no_results_title_text: Trenutno ne postoje dostupne verzije projekta. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Pozivnica account: delete: "Izbriši korisnički račun" @@ -1036,6 +1098,20 @@ hr: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1859,6 +1935,23 @@ hr: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2217,6 +2310,7 @@ hr: label_environment: "Okruženje" label_estimates_and_progress: "Estimates and progress" label_equals: "je" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Primjer" label_experimental: "Experimental" @@ -2481,6 +2575,8 @@ hr: label_related_work_packages: "Pripadajući radni paketi" label_relates: "se odnose na" label_relates_to: "se odnose na" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Izbriši relaciju" label_relation_new: "Nova relacija" label_release_notes: "Napomene uz izdavanje" diff --git a/config/locales/crowdin/hu.seeders.yml b/config/locales/crowdin/hu.seeders.yml index 79909cfabeba..7fcbe3c36848 100644 --- a/config/locales/crowdin/hu.seeders.yml +++ b/config/locales/crowdin/hu.seeders.yml @@ -34,6 +34,17 @@ hu: name: Szürke (sötét) item_13: name: Fekete + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentáció @@ -70,6 +81,21 @@ hu: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Alacsony diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml index 48b5cc29d65d..3710cd6d857c 100644 --- a/config/locales/crowdin/hu.yml +++ b/config/locales/crowdin/hu.yml @@ -33,7 +33,7 @@ hu: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -238,6 +238,8 @@ hu: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Új egyéni mezők hozzáadásához először létre kell hozni őket, még mielőtt felvenné azokat a projekthez. is_enabled_globally: "Globálisan engedélyezve van" @@ -264,20 +266,20 @@ hu: single: "vagy" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -629,6 +631,66 @@ hu: no_results_title_text: Jelenleg nincs elérhető típus. version: no_results_title_text: Nincs elérhető verzió. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Meghívó account: delete: "Felhasználói hozzáférés törölése" @@ -1025,6 +1087,20 @@ hu: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1820,6 +1896,23 @@ hu: units: hours: óra days: nap + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext elérhető (opcionális)" @@ -2178,6 +2271,7 @@ hu: label_environment: "Környezet" label_estimates_and_progress: "Estimates and progress" label_equals: "van" + label_equals_with_descendants: "is any with descendants" label_everywhere: "bárhol" label_example: "Példa" label_experimental: "Kísérleti" @@ -2442,6 +2536,8 @@ hu: label_related_work_packages: "Kapcsolódó munkacsomagok" label_relates: "Kapcsolódó" label_relates_to: "Kapcsolódó" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Kapcsolat törlése" label_relation_new: "Új kapcsolat" label_release_notes: "Kiadási megjegyzések" diff --git a/config/locales/crowdin/id.seeders.yml b/config/locales/crowdin/id.seeders.yml index 608702b3e9ad..69dc28858561 100644 --- a/config/locales/crowdin/id.seeders.yml +++ b/config/locales/crowdin/id.seeders.yml @@ -34,6 +34,17 @@ id: name: Abu-abu (gelap) item_13: name: Hitam + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentasi @@ -70,6 +81,21 @@ id: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml index e00e8bb8797b..ce5520c7f9b4 100644 --- a/config/locales/crowdin/id.yml +++ b/config/locales/crowdin/id.yml @@ -33,7 +33,7 @@ id: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -233,6 +233,8 @@ id: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Untuk menambahkan kolom kustom baru untuk sebuah proyek, pertama-tama Anda harus membuatnya, sebelum Anda dapat menambahkannya ke proyek ini. is_enabled_globally: "Diaktifkan secara global" @@ -259,20 +261,20 @@ id: single: "atau" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -617,6 +619,66 @@ id: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Undangan account: delete: "Hapus akun" @@ -1013,6 +1075,20 @@ id: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1780,6 +1856,23 @@ id: units: hours: j days: h + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdf2teks tersedia (opsional)" @@ -2138,6 +2231,7 @@ id: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "adalah" + label_equals_with_descendants: "is any with descendants" label_everywhere: "di mana pun" label_example: "Contoh" label_experimental: "Experimental" @@ -2402,6 +2496,8 @@ id: label_related_work_packages: "Paket-Penugasan terkait" label_relates: "terkait dengan" label_relates_to: "terkait dengan" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Hapus keterkaitan" label_relation_new: "Keterkaitan baru" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/it.seeders.yml b/config/locales/crowdin/it.seeders.yml index 06f927728b7a..824c08feb711 100644 --- a/config/locales/crowdin/it.seeders.yml +++ b/config/locales/crowdin/it.seeders.yml @@ -34,6 +34,17 @@ it: name: Grigio (scuro) item_13: name: Nero + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentazione @@ -70,6 +81,21 @@ it: item_1: name: Ruolo globale standard standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Basso diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml index d359fd5cbf48..3bf1b421ba91 100644 --- a/config/locales/crowdin/it.yml +++ b/config/locales/crowdin/it.yml @@ -33,7 +33,7 @@ it: label_activity_show_only_changes: "Mostra solo le modifiche" label_sort_asc: "Più recenti in fondo" label_sort_desc: "Più recenti in cima" - label_type_to_comment: "Digita qui per commentare" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Invia commento" changed_on: "ha modificato il" created_on: "l'ha creata il" @@ -236,6 +236,8 @@ it: zero: nessun sottoelemento one: 1 sottoelemento other: "%{count} sottoelementi" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Per aggiungere nuovi campi personalizzati a un progetto, è necessario prima crearli. is_enabled_globally: "Abilitato a livello globale" @@ -262,20 +264,20 @@ it: single: "oppure" dry_validation: errors: - integer?: "deve essere un intero" - filled?: "deve essere compilato" - greater_or_equal_zero: "deve essere maggiore o uguale a 0" - not_found: "non trovato" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "non può essere un elemento radice" - not_persisted: "deve essere un elemento già esistente" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "deve essere unico all'interno dello stesso livello gerarchico" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "deve essere unico all'interno dello stesso livello gerarchico" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "deve essere un discendente della radice gerarchica" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Profondità" item: "Elemento" @@ -628,6 +630,66 @@ it: no_results_title_text: Al momento non sono disponibili tipi. version: no_results_title_text: Al momento non vi sono versioni disponibili. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invito account: delete: "Cancella account" @@ -1024,6 +1086,20 @@ it: attributes: project_ids: blank: "Seleziona un progetto." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1819,6 +1895,23 @@ it: units: hours: o days: g + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdfatesto disponibile (opzionale)" @@ -2177,6 +2270,7 @@ it: label_environment: "Ambiente" label_estimates_and_progress: "Stime e progressi" label_equals: "è" + label_equals_with_descendants: "is any with descendants" label_everywhere: "ovunque" label_example: "Esempio" label_experimental: "Sperimentale" @@ -2441,6 +2535,8 @@ it: label_related_work_packages: "Macro-attività correlate" label_relates: "correlato con" label_relates_to: "correlato con" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Eliminare la relazione" label_relation_new: "Nuova relazione" label_release_notes: "Note di rilascio" diff --git a/config/locales/crowdin/ja.seeders.yml b/config/locales/crowdin/ja.seeders.yml index 842a1f24ea11..b1f2e2b9c8e2 100644 --- a/config/locales/crowdin/ja.seeders.yml +++ b/config/locales/crowdin/ja.seeders.yml @@ -34,6 +34,17 @@ ja: name: グレー(濃い) item_13: name: 黒 + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: 文章 @@ -70,6 +81,21 @@ ja: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: 低め diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml index e9c5054811ff..60c64a0f3ea8 100644 --- a/config/locales/crowdin/ja.yml +++ b/config/locales/crowdin/ja.yml @@ -33,7 +33,7 @@ ja: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -237,6 +237,8 @@ ja: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > 新しいカスタムフィールドをプロジェクトに追加するには、それをこのプロジェクトに追加する前に、まず作成する必要があります。 is_enabled_globally: "グローバルで有効" @@ -263,20 +265,20 @@ ja: single: "または" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -620,6 +622,66 @@ ja: no_results_title_text: 現在、有効な種類はありません。 version: no_results_title_text: 現在、有効なバージョンはありません。 + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: 案内 account: delete: "アカウントを削除" @@ -1016,6 +1078,20 @@ ja: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1783,6 +1859,23 @@ ja: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotextが利用可能 (オプション)" @@ -2141,6 +2234,7 @@ ja: label_environment: "環境" label_estimates_and_progress: "Estimates and progress" label_equals: "等しい" + label_equals_with_descendants: "is any with descendants" label_everywhere: "どこにでも" label_example: "例" label_experimental: "実験的" @@ -2405,6 +2499,8 @@ ja: label_related_work_packages: "関係するワークパッケージ" label_relates: "関係している" label_relates_to: "関連している" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "関係の削除" label_relation_new: "新しい関係" label_release_notes: "リリースノート" diff --git a/config/locales/crowdin/js-af.yml b/config/locales/crowdin/js-af.yml index 2e85ba0c0360..1b7233869545 100644 --- a/config/locales/crowdin/js-af.yml +++ b/config/locales/crowdin/js-af.yml @@ -105,6 +105,7 @@ af: button_update: "Opdateer" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Skep" card: add_new: "Add new card" @@ -356,10 +357,10 @@ af: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ af: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-ar.yml b/config/locales/crowdin/js-ar.yml index 2ed8f35668fb..0578854d62a2 100644 --- a/config/locales/crowdin/js-ar.yml +++ b/config/locales/crowdin/js-ar.yml @@ -105,6 +105,7 @@ ar: button_update: "التحديث" button_export-pdf: "تنزيل PDF" button_export-atom: "تحميل Atom" + button_generate_pdf: "Generate PDF" button_create: "إنشاء" card: add_new: "Add new card" @@ -356,10 +357,10 @@ ar: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ ar: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-az.yml b/config/locales/crowdin/js-az.yml index a1e627b6cf03..5d74c5a26ca3 100644 --- a/config/locales/crowdin/js-az.yml +++ b/config/locales/crowdin/js-az.yml @@ -105,6 +105,7 @@ az: button_update: "Yeniləmə" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ az: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ az: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-be.yml b/config/locales/crowdin/js-be.yml index 34f8c231e8ff..c97a47def68d 100644 --- a/config/locales/crowdin/js-be.yml +++ b/config/locales/crowdin/js-be.yml @@ -105,6 +105,7 @@ be: button_update: "Абнавіць" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ be: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ be: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-bg.yml b/config/locales/crowdin/js-bg.yml index fd684a72a226..dc746f1faec3 100644 --- a/config/locales/crowdin/js-bg.yml +++ b/config/locales/crowdin/js-bg.yml @@ -105,6 +105,7 @@ bg: button_update: "Обнови" button_export-pdf: "Свали PDF" button_export-atom: "Свали Atom" + button_generate_pdf: "Generate PDF" button_create: "Създаване" card: add_new: "Add new card" @@ -356,10 +357,10 @@ bg: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ bg: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-ca.yml b/config/locales/crowdin/js-ca.yml index 71ff3534c146..ff9ce8e274ce 100644 --- a/config/locales/crowdin/js-ca.yml +++ b/config/locales/crowdin/js-ca.yml @@ -105,6 +105,7 @@ ca: button_update: "Actualitza" button_export-pdf: "Descarregar PDF" button_export-atom: "Descarregar Atom" + button_generate_pdf: "Generate PDF" button_create: "Crear" card: add_new: "Afegir nova targeta" @@ -356,10 +357,10 @@ ca: learn_about: "Més informació sobre les noves funcions" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "S'ha produït un error en carregar les dades." @@ -575,7 +576,7 @@ ca: members: "Convida nous membres a afegir-se al teu projecte." quick_add_button: "Fes clic a la icona de més (+) en la navegació superior per crear un nou projecte o convidar companys de feina." sidebar_arrow: "Utilitza la fletxa de retorn a la cantonada esquerra per tornar al menú principal del projecte." - welcome: "Segueix la introducció de tres minuts per aprendre les funcions més importants.
Recomanem completar les passes fins al final. Podràs tornar a començar aquesta introducció en qualsevol moment." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Dintre de la wiki pots documentar i compartir el coneixement conjuntament amb el teu equip." backlogs: overview: "Administra la teva feina en vistes de treballs pendents." diff --git a/config/locales/crowdin/js-ckb-IR.yml b/config/locales/crowdin/js-ckb-IR.yml index 25322f5c6e10..76c5fcc7be48 100644 --- a/config/locales/crowdin/js-ckb-IR.yml +++ b/config/locales/crowdin/js-ckb-IR.yml @@ -105,6 +105,7 @@ ckb-IR: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ ckb-IR: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ ckb-IR: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml index 537e4567c8d1..9f3493c02919 100644 --- a/config/locales/crowdin/js-cs.yml +++ b/config/locales/crowdin/js-cs.yml @@ -105,6 +105,7 @@ cs: button_update: "Aktualizovat" button_export-pdf: "Stáhnout PDF" button_export-atom: "Stáhnout Atom" + button_generate_pdf: "Generate PDF" button_create: "Vytvořit" card: add_new: "Přidat novou kartu" @@ -355,10 +356,10 @@ cs: learn_about: "Další informace o nových funkcích" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Přihlásit kalendář k odběru" inital_setup_error_message: "Při načítání dat došlo k chybě." @@ -574,7 +575,7 @@ cs: members: "Pozvěte nové členy , aby se připojili k vašemu projektu." quick_add_button: "Klikněte na ikonu plus (+) v záhlaví pro vytvoření nového projektu nebo pro pozvání spolupracovníků." sidebar_arrow: "Pomocí šipky zpět v levém horním rohu se vrátíte do hlavního menu projektu." - welcome: "Naučte se během tří minut důležité funkce.
Doporučujeme dokončit prohlídku až do konce. Prohlídku můžete kdykoliv restartovat." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "V rámci Wiki můžete dokumentovat a sdílet znalosti společně se svým týmem." backlogs: overview: "Spravujte svou práci v backlogs zobrazení." diff --git a/config/locales/crowdin/js-da.yml b/config/locales/crowdin/js-da.yml index 1f7260e04fb0..451ef1c4b401 100644 --- a/config/locales/crowdin/js-da.yml +++ b/config/locales/crowdin/js-da.yml @@ -105,6 +105,7 @@ da: button_update: "Opdater" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Opret" card: add_new: "Add new card" @@ -355,10 +356,10 @@ da: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -574,7 +575,7 @@ da: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Tag en tre minutters introduktionsturné for at lære de mest vigtige funktioner .
Vi anbefaler at du gennemfører trinende til slutningen. Du kan når som helst genstarte turen." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-de.yml b/config/locales/crowdin/js-de.yml index bf7dc90d3d9e..bf27e3438309 100644 --- a/config/locales/crowdin/js-de.yml +++ b/config/locales/crowdin/js-de.yml @@ -105,6 +105,7 @@ de: button_update: "Aktualisieren" button_export-pdf: "PDF-Download" button_export-atom: "Atom-Download" + button_generate_pdf: "PDF generieren" button_create: "Anlegen" card: add_new: "Neue Karte hinzufügen" @@ -355,10 +356,10 @@ de: learn_about: "Erfahren Sie mehr über die neuen Funktionen" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - Das Release beinhaltet verschiedene neue Funktionen und Verbesserungen für Sie, z.B.
  • Verbessern Sie Ihre Kommunikation mit einer besser strukturierten Aktivitäts-Registerkarte, in Echtzeit ladenden Updates und Benachrichtigungen, Emoji-Reaktionen und mehr.
  • Profitieren Sie von einfachen Single Sign-On-Authentifizierungseinstellungen mit SAML und OIDC in Ihrer Enterprise Cloud-Administration.
  • Nutzen Sie die neue 'Standard global role' und aktivieren Sie Berechtigungen zum Anzeigen von E-Mail-Adressen.
  • Profitieren Sie von einer einfacheren Navigation in Projektlisten mithilfe von Schnellzugriff-Tabellenüberschriften.
  • Erleben Sie vereinfachte Design-Einstellungen durch weniger erforderliche Design-Variablen in der Seitenleiste.
  • Sparen Sie sich manuelle Anpassungen, wenn Sie einem Arbeitspakettyp ein selbstdefiniertes Feld hinzufügen - dieses wird nicht mehr automatisch auf alle Projekte angewendet.
  • Profitieren Sie von einer verbesserten Navigationsübersicht - 'Mein Konto' wurde in 'Kontoeinstellungen' umbenannt.
+ Die Version bringt verschiedene Funktionen und Verbesserungen für Sie, z.B.
  • Benutzerdefinierte Felder vom Typ Hierarchie (Enterprise Add-on).
  • Neugestaltung des Beziehungen-Tabs in Arbeitspaketen.
  • Neugestaltung der Meeting-Indexseite.
  • Manuelle Seitenumbrüche beim Export von PDF-Arbeitspaketen.
  • Zen-Modus für Projektlisten.
ical_sharing_modal: title: "Kalender abonnieren" inital_setup_error_message: "Beim Abrufen der Daten ist ein Fehler aufgetreten." diff --git a/config/locales/crowdin/js-el.yml b/config/locales/crowdin/js-el.yml index b843a70eec32..ce944329bdec 100644 --- a/config/locales/crowdin/js-el.yml +++ b/config/locales/crowdin/js-el.yml @@ -105,6 +105,7 @@ el: button_update: "Ενημέρωση" button_export-pdf: "Λήψη PDF" button_export-atom: "Κατεβάστε το Atom" + button_generate_pdf: "Generate PDF" button_create: "Δημιουργία" card: add_new: "Προσθέστε νέα κάρτα" @@ -355,10 +356,10 @@ el: learn_about: "Μάθετε περισσότερα για τις νέες λειτουργίες" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -574,7 +575,7 @@ el: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Κάντε μια τρίλεπτη εισαγωγική περιήγηση για να μάθετε τα πιο σημαντικά χαρακτηριστικά.
Προτείνουμε να ολοκληρώσετε τα βήματα μέχρι το τέλος. Μπορείτε να επανεκκινήσετε την περιήγηση ανά πάσα στιγμή." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-eo.yml b/config/locales/crowdin/js-eo.yml index fab34948e671..00f11c8d6d45 100644 --- a/config/locales/crowdin/js-eo.yml +++ b/config/locales/crowdin/js-eo.yml @@ -105,6 +105,7 @@ eo: button_update: "Ĝisdatigi" button_export-pdf: "Elŝuti PDF" button_export-atom: "Elŝuti Atom" + button_generate_pdf: "Generate PDF" button_create: "Krei" card: add_new: "Aldoni novan karton" @@ -356,10 +357,10 @@ eo: learn_about: "Lerni pli pri la novaj plibonigoj" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ eo: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-es.yml b/config/locales/crowdin/js-es.yml index e1f4184ebf47..b2fd8f5bb9ca 100644 --- a/config/locales/crowdin/js-es.yml +++ b/config/locales/crowdin/js-es.yml @@ -105,6 +105,7 @@ es: button_update: "Actualizar" button_export-pdf: "Descargar PDF" button_export-atom: "Descargar Atom" + button_generate_pdf: "Generate PDF" button_create: "Crear" card: add_new: "Añadir nueva tarjeta" @@ -356,10 +357,10 @@ es: learn_about: "Más información sobre las nuevas funciones" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - La versión trae varias características y mejoras para usted, por ejemplo
  • Aumente su comunicación con una pestaña de Actividad mejor estructurada, mensajes y notificaciones de carga en tiempo real, reacciones emoji y mucho más.
  • Benefíciese de una sencilla configuración de autenticación de inicio de sesión único con SAML y OIDC en su administración de Enterprise Cloud.
  • Utilice el nuevo «rol global estándar» y habilite los permisos para ver las direcciones de correo electrónico.
  • Disfrute de una navegación más sencilla en las listas de proyectos con encabezados de tabla de acción rápida.
  • Experimente una configuración de diseño simplificada con menos variables de diseño de barra lateral necesarias.
  • Reduzca la limpieza manual cuando añada un campo personalizado a un tipo. Ya no se aplica automáticamente a todos los proyectos.
  • Benefíciese de una claridad de navegación mejorada. «Mi cuenta» cambia de nombre a «Ajustes de la cuenta».
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Suscribirse al calendario" inital_setup_error_message: "Se ha producido un error al obtener los datos." @@ -575,7 +576,7 @@ es: members: "Invitar a nuevos miembros a unirse a tu proyecto." quick_add_button: "Haga clic en el icono del signo más (+) en el menú de navegación del encabezado para crear un proyecto o invitar a compañeros." sidebar_arrow: "Usa la flecha de retorno en la esquina superior izquierda para regresar al menú principal del proyecto." - welcome: "Realice un paseo de introducción de tres minutos para conocer las funciones más importantes.
Le recomendamos que complete todos los pasos. Puede volver a iniciar el paseo en cualquier momento." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "En la wiki, puede elaborar documentos y compartir conocimientos con su equipo." backlogs: overview: "Administre su trabajo en la vista de trabajos pendientes." diff --git a/config/locales/crowdin/js-et.yml b/config/locales/crowdin/js-et.yml index eda78d83c57f..acf06de0967d 100644 --- a/config/locales/crowdin/js-et.yml +++ b/config/locales/crowdin/js-et.yml @@ -105,6 +105,7 @@ et: button_update: "Uuenda" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Loo uus" card: add_new: "Add new card" @@ -356,10 +357,10 @@ et: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ et: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-eu.yml b/config/locales/crowdin/js-eu.yml index e4277f4a90d4..a0f4fd38aace 100644 --- a/config/locales/crowdin/js-eu.yml +++ b/config/locales/crowdin/js-eu.yml @@ -105,6 +105,7 @@ eu: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ eu: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ eu: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-fa.yml b/config/locales/crowdin/js-fa.yml index 1bd6049c6dd2..56a14dc267cb 100644 --- a/config/locales/crowdin/js-fa.yml +++ b/config/locales/crowdin/js-fa.yml @@ -105,6 +105,7 @@ fa: button_update: "به روز رسانی" button_export-pdf: "دانلود PDF" button_export-atom: "دریافت Atom" + button_generate_pdf: "Generate PDF" button_create: "ایجاد" card: add_new: "Add new card" @@ -356,10 +357,10 @@ fa: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ fa: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "یک تور معرفی سه دقیقه‌ای را برای یادگیری مهم‌ترین ویژگی ها در پیش گیرید.
وصیه می‌کنیم مراحل را تا پایان کامل کنید. شما می توانید تور را در هر زمان دیگری هم دوباره راه اندازی کنید." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "کار خود را در نمای backlogs مدیریت کنید." diff --git a/config/locales/crowdin/js-fi.yml b/config/locales/crowdin/js-fi.yml index e7af4d41e6e1..52a5b29a49aa 100644 --- a/config/locales/crowdin/js-fi.yml +++ b/config/locales/crowdin/js-fi.yml @@ -105,6 +105,7 @@ fi: button_update: "Päivitä" button_export-pdf: "Lataa PDF" button_export-atom: "Lataa Atom" + button_generate_pdf: "Generate PDF" button_create: "Uusi" card: add_new: "Uusi kortti" @@ -356,10 +357,10 @@ fi: learn_about: "Lisätietoja uusista ominaisuuksista" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ fi: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-fil.yml b/config/locales/crowdin/js-fil.yml index ec72e1f98195..d1c475adf801 100644 --- a/config/locales/crowdin/js-fil.yml +++ b/config/locales/crowdin/js-fil.yml @@ -105,6 +105,7 @@ fil: button_update: "I-update" button_export-pdf: "I-download ang PDF" button_export-atom: "I-download ang atom" + button_generate_pdf: "Generate PDF" button_create: "Lumikha" card: add_new: "Add new card" @@ -356,10 +357,10 @@ fil: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ fil: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-fr.yml b/config/locales/crowdin/js-fr.yml index cd5ced7a11ae..7b00b593544a 100644 --- a/config/locales/crowdin/js-fr.yml +++ b/config/locales/crowdin/js-fr.yml @@ -105,6 +105,7 @@ fr: button_update: "Mettre à jour" button_export-pdf: "Télécharger le PDF" button_export-atom: "Télécharger Atom" + button_generate_pdf: "Générer un fichier PDF" button_create: "Créer" card: add_new: "Ajouter une nouvelle carte" @@ -188,8 +189,8 @@ fr: without_type: "Créer un lot de travaux" with_type: "Créer un lot de travaux (Type : %{typename})" embedded_table: - button: "Tableau intégré de lots de travaux" - text: "[Placeholder] Tableau intégré de lots de travaux" + button: "Intégrer le lot de travaux" + text: "[Placeholder] Tableau du lot de travaux intégré" embedded_calendar: text: "[Placeholder] Calendrier embarqué" admin: @@ -356,10 +357,10 @@ fr: learn_about: "En savoir plus sur les nouvelles fonctionnalités" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - Cette version apporte diverses fonctionnalités et améliorations, notamment :
  • Améliorez votre communication grâce à un onglet Activité mieux structuré, au chargement en temps réel des messages et des notifications, aux réactions par émoji et plus encore.
  • Bénéficiez de paramètres d'authentification simples avec SAML et OIDC dans votre interface d'administration Enterprise Cloud.
  • Utilisez le nouveau « rôle global standard » et activez les autorisations pour voir les adresses e-mail.
  • Profitez d'une navigation plus facile dans les listes de projets avec des en-têtes de tableau avec action rapide.
  • Bénéficiez de paramètres de conception simplifiés avec la réduction du nombre de variables de conception de barre latérale nécessaires.
  • Réduisez le nettoyage manuel lors de l'ajout d'un champ personnalisé à un type. Il n'y a plus d'application automatique à tous les projets.
  • Bénéficiez d'une meilleure clarté de navigation : « Mon compte » est renommé « Paramètres du compte ».
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "S'abonner au calendrier" inital_setup_error_message: "Une erreur est survenue lors de la récupération des données." @@ -575,7 +576,7 @@ fr: members: "Invitez de nouveaux membres à rejoindre votre projet." quick_add_button: "Cliquez sur l'icône plus (+) dans l'en-tête de navigation pour créer un nouveau projet ou inviter des collègues." sidebar_arrow: "Utilisez la flèche de retour dans le coin supérieur gauche pour retourner au menu principal du projet." - welcome: "Faites une visite d’introduction de trois minutes d’apprendre le plus de caractéristiques importantes de .
il est recommandé d’avoir effectué les étapes jusqu'à la fin. Vous pouvez redémarrer la tournée à tout moment." + welcome: "Faites une visite d’introduction de trois minutes pour apprendre les fonctionnalités les plus importantes.
Il est recommandé d’effectuer les étapes jusqu'à la fin. Vous pouvez redémarrer cette visite à tout moment." wiki: "Dans le wiki vous pouvez documenter et partager vos connaissances avec votre équipe." backlogs: overview: "Gérez votre travail dans la vue backlogs." diff --git a/config/locales/crowdin/js-he.yml b/config/locales/crowdin/js-he.yml index 5a8d338ccb36..9ccb008bddb1 100644 --- a/config/locales/crowdin/js-he.yml +++ b/config/locales/crowdin/js-he.yml @@ -105,6 +105,7 @@ he: button_update: "עדכון" button_export-pdf: "הורד קובץ PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "צור" card: add_new: "Add new card" @@ -356,10 +357,10 @@ he: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ he: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-hi.yml b/config/locales/crowdin/js-hi.yml index 329cb1f25b1c..a739f006dd74 100644 --- a/config/locales/crowdin/js-hi.yml +++ b/config/locales/crowdin/js-hi.yml @@ -105,6 +105,7 @@ hi: button_update: "अद्यतन करें" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "रचना करें" card: add_new: "Add new card" @@ -356,10 +357,10 @@ hi: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ hi: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-hr.yml b/config/locales/crowdin/js-hr.yml index 258e305c1892..1382033ba64c 100644 --- a/config/locales/crowdin/js-hr.yml +++ b/config/locales/crowdin/js-hr.yml @@ -105,6 +105,7 @@ hr: button_update: "Ažuriraj" button_export-pdf: "Preuzmi PDF" button_export-atom: "Preuzmite Atom" + button_generate_pdf: "Generate PDF" button_create: "Stvori" card: add_new: "Add new card" @@ -356,10 +357,10 @@ hr: learn_about: "Saznaj više o novim značajkama" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ hr: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-hu.yml b/config/locales/crowdin/js-hu.yml index 3a3b31374ebf..d796727faf32 100644 --- a/config/locales/crowdin/js-hu.yml +++ b/config/locales/crowdin/js-hu.yml @@ -105,6 +105,7 @@ hu: button_update: "Frissítés" button_export-pdf: "PDF-fájl letöltése" button_export-atom: "Atom letöltés" + button_generate_pdf: "Generate PDF" button_create: "Létrehoz" card: add_new: "Új kártya hozzáadása" @@ -356,10 +357,10 @@ hu: learn_about: "Tudjon meg többet az új funkciókról" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ hu: members: "Új tagok meghívása, hogy a projekthez csatlakozzanak." quick_add_button: "Kattintson a fejlécben található (+) ikonra hogy create a new project vagy invite coworkers." sidebar_arrow: "Használja a vissza nyilat bal felül hogy visszatérjen a projektekhez main menu.." - welcome: "Áldozzon három percet erre a bemutatóra, hogy megismerje a legfontosabb szolgáltatásokat
Javasoljuk, hogy végezze el a lépéseket egészen a végéig. A túra bármikor újraindítható." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "A Wiki modulban tudását dokumentálhatja és megoszthatja a csapatával." backlogs: overview: "Munka kezelése a backlogs nézetben" diff --git a/config/locales/crowdin/js-id.yml b/config/locales/crowdin/js-id.yml index 4c8e30546296..f9cdd02ce311 100644 --- a/config/locales/crowdin/js-id.yml +++ b/config/locales/crowdin/js-id.yml @@ -105,6 +105,7 @@ id: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Buat baru" card: add_new: "Add new card" @@ -356,10 +357,10 @@ id: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ id: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-it.yml b/config/locales/crowdin/js-it.yml index 649e90143f8f..41e9de7e47b9 100644 --- a/config/locales/crowdin/js-it.yml +++ b/config/locales/crowdin/js-it.yml @@ -105,6 +105,7 @@ it: button_update: "Aggiorna" button_export-pdf: "Scarica PDF" button_export-atom: "Scarica Atom" + button_generate_pdf: "Generate PDF" button_create: "Crea" card: add_new: "Aggiungi una nuova carta" @@ -356,10 +357,10 @@ it: learn_about: "Scopri di più sulle nuove funzionalità" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - Questa versione offre diverse funzionalità e miglioramenti, ad esempio
  • Migliora la tua comunicazione con una scheda Attività meglio strutturata, messaggi e notifiche di caricamento in tempo reale, reazioni emoji e altro ancora.
  • Approfitta delle semplici impostazioni di autenticazione Single Sign-On con SAML e OIDC nella tua amministrazione Enterprise Cloud.
  • Utilizza il nuovo "Ruolo globale standard" e abilita le autorizzazioni per visualizzare gli indirizzi e-mail.
  • Goditi una navigazione più semplice negli elenchi di progetti con intestazioni di tabella di azioni rapide.
  • Scopri impostazioni di progettazione semplificate con meno variabili di progettazione della barra laterale necessarie.
  • Riduci la pulizia manuale quando aggiungi un campo personalizzato a un tipo: niente più applicazione automatica a tutti i progetti.
  • Approfitta di una navigazione più chiara: "Il mio account" è stato rinominato "Impostazioni account".
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Iscriviti al calendario" inital_setup_error_message: "Si è verificato un errore recuperando i dati." @@ -575,7 +576,7 @@ it: members: "Invita nuovi membri per entrare al tuo progetto." quick_add_button: "Clicca sull'icona più (+) nella navigazione dell'intestazione per creare un nuovo progetto o per invitare colleghi." sidebar_arrow: "Utilizza la freccia di ritorno nell'angolo in alto a sinistra per tornare al menu principale del progetto." - welcome: "Fai un tour introduttivo di tre minuti per apprendere le funzioni importanti.
Consigliamo di completare i passaggi fino alla fine. Puoi riavviare il tour in qualsiasi momento." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Nella wiki puoi documentare e condividere la conoscenza con il tuo team." backlogs: overview: "Gestisci il tuo lavoro nella vista backlog." diff --git a/config/locales/crowdin/js-ja.yml b/config/locales/crowdin/js-ja.yml index 3ee15dedf82a..2d53bbd958f4 100644 --- a/config/locales/crowdin/js-ja.yml +++ b/config/locales/crowdin/js-ja.yml @@ -106,6 +106,7 @@ ja: button_update: "更新" button_export-pdf: "PDFファイルをダウンロード" button_export-atom: "Atomをダウンロード" + button_generate_pdf: "Generate PDF" button_create: "作成" card: add_new: "新規カード追加" @@ -357,10 +358,10 @@ ja: learn_about: "新機能の詳細はこちら" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -576,7 +577,7 @@ ja: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "3分間の導入ツアーで、最も重要な機能を確認します。
最後まで手順を完了することをお勧めします。 ツアーはいつでも再開できます。" + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-ka.yml b/config/locales/crowdin/js-ka.yml index de78ca5aa76c..526cbd906243 100644 --- a/config/locales/crowdin/js-ka.yml +++ b/config/locales/crowdin/js-ka.yml @@ -105,6 +105,7 @@ ka: button_update: "განახლება" button_export-pdf: "გადმოწერე PDF" button_export-atom: "Atom-ის გადმოწერა" + button_generate_pdf: "Generate PDF" button_create: "შექმნა" card: add_new: "ახალი ბარათის დამატება" @@ -356,10 +357,10 @@ ka: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ ka: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-kk.yml b/config/locales/crowdin/js-kk.yml index ef989f591977..1118b73a2826 100644 --- a/config/locales/crowdin/js-kk.yml +++ b/config/locales/crowdin/js-kk.yml @@ -105,6 +105,7 @@ kk: button_update: "Жаңарту" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ kk: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ kk: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-ko.yml b/config/locales/crowdin/js-ko.yml index 8cf7ed3b9857..c29d57085ced 100644 --- a/config/locales/crowdin/js-ko.yml +++ b/config/locales/crowdin/js-ko.yml @@ -105,6 +105,7 @@ ko: button_update: "업데이트" button_export-pdf: "PDF 다운로드" button_export-atom: "Atom 다운로드" + button_generate_pdf: "Generate PDF" button_create: "만들기" card: add_new: "새로운 카드를 추가하다" @@ -356,10 +357,10 @@ ko: learn_about: "새로운 기능에 대해 자세히 알아보기" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "캘린더 구독" inital_setup_error_message: "데이터를 가져오는 중에 오류가 발생했습니다." @@ -575,7 +576,7 @@ ko: members: "프로젝트에 참여할 새로운 멤버를 초대하세요." quick_add_button: "헤더 탐색에서 더하기(+) 아이콘을 클릭하여 새 프로젝트를 생성하거나 동료를 초대하세요." sidebar_arrow: "프로젝트의 기본 메뉴로 돌아가려면 왼쪽 상단의 뒤로 화살표를 사용하세요." - welcome: "3분 소개 투어를 보고 가장 중요한 기능에 대해 알아보세요.
끝까지 단계를 완료하는 것이 좋습니다. 언제든지 투어를 다시 시작할 수 있습니다." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Wiki에서 문서화하고 팀과 함께 지식을 공유할 수 있습니다." backlogs: overview: "백로그 보기에서 작업을 관리하세요." diff --git a/config/locales/crowdin/js-lt.yml b/config/locales/crowdin/js-lt.yml index 8dff71eb4d77..a85ccb593784 100644 --- a/config/locales/crowdin/js-lt.yml +++ b/config/locales/crowdin/js-lt.yml @@ -105,6 +105,7 @@ lt: button_update: "Atnaujinti" button_export-pdf: "Atsisiųsti PDF" button_export-atom: "Atsisiųsti Atom" + button_generate_pdf: "Generate PDF" button_create: "Kurti" card: add_new: "Pridėti naują kortelę" @@ -356,10 +357,10 @@ lt: learn_about: "Sužinokite daugiau apie naujas galimybes" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Prenumeruoti kalendorių" inital_setup_error_message: "Gaunant duomenis įvyko klaida." @@ -575,7 +576,7 @@ lt: members: "Pakvieskite naujus narius prisijungti prie projekto." quick_add_button: "Paspauskite pliuso (+) ženklą navigacijos antraštėje ir sukursite naują projektą arba pakviesite bendradarbius." sidebar_arrow: "Pasinaudokite grįžimo rodykle viršutiniame kairiajame kampe grįžimui į projekto pagrindinį meniu." - welcome: "Paskirkite tris minutes įvadinei kelionei ir išmokite daugumą svarbių sistemos galimybių.
Rekomenduojame atlikti visus veiksmus iki pabaigos. Ekskursiją galite paleisti iš naujo bet kuriuo metu." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Wiki'yje galite dokumentuoti ir dalintis žiniomis su savo komandos nariais." backlogs: overview: "Valdykite savo darbus Darbų sąrašo vaizde." diff --git a/config/locales/crowdin/js-lv.yml b/config/locales/crowdin/js-lv.yml index 123b62fb6bb4..9d70db165667 100644 --- a/config/locales/crowdin/js-lv.yml +++ b/config/locales/crowdin/js-lv.yml @@ -105,6 +105,7 @@ lv: button_update: "Atjaunot" button_export-pdf: "Lejupielādēt PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Izveidot" card: add_new: "Add new card" @@ -356,10 +357,10 @@ lv: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ lv: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-mn.yml b/config/locales/crowdin/js-mn.yml index 07730680615c..03e95456cf42 100644 --- a/config/locales/crowdin/js-mn.yml +++ b/config/locales/crowdin/js-mn.yml @@ -105,6 +105,7 @@ mn: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ mn: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ mn: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml index e4691fd83b1b..94472d471e24 100644 --- a/config/locales/crowdin/js-ms.yml +++ b/config/locales/crowdin/js-ms.yml @@ -105,6 +105,7 @@ ms: button_update: "Kemas kini" button_export-pdf: "Muat turun PDF" button_export-atom: "Muat Turun Atom" + button_generate_pdf: "Generate PDF" button_create: "Cipta" card: add_new: "Tambah kad baharu" @@ -356,10 +357,10 @@ ms: learn_about: "Ketahui lebih lanjut mengenai fitur-fitur baharu." #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Langgan kalendar" inital_setup_error_message: "Ralat berlaku ketika sedang mengambil data." @@ -575,7 +576,7 @@ ms: members: "Jemput ahli baharu untuk sertai projek anda." quick_add_button: "Klik ikon tambah (+) dalam navigasi pengepala untuk cipta projek baharu atau untuk jemput rakan sekerja." sidebar_arrow: "Guna anak panah kembali di sudut kiri atas untuk kembali ke menu utama projek." - welcome: "Ambil lawatan pengenalan 3 minit untuk belajar fitur-fitur penting dengan banyak.
Kami sarankan melengkapi langkah-langkah tersebut sehingga ke akhirnya. Anda boleh mula semula lawatan bila-bila masa." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama pasukan anda." backlogs: overview: "Kendalikan kerja anda dalam paparan tunggakan." diff --git a/config/locales/crowdin/js-ne.yml b/config/locales/crowdin/js-ne.yml index a87b44f29ec6..8fba28800552 100644 --- a/config/locales/crowdin/js-ne.yml +++ b/config/locales/crowdin/js-ne.yml @@ -105,6 +105,7 @@ ne: button_update: "Update" button_export-pdf: "PDF डाउनलोड गर्नुहोस्" button_export-atom: "एटम डाउनलोड गर्नुहोस्" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "नयाँ कार्ड थप्नुहोस्" @@ -356,10 +357,10 @@ ne: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ ne: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-nl.yml b/config/locales/crowdin/js-nl.yml index 7a2030cfe250..1d811294c413 100644 --- a/config/locales/crowdin/js-nl.yml +++ b/config/locales/crowdin/js-nl.yml @@ -105,6 +105,7 @@ nl: button_update: "Bijwerken" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Maken" card: add_new: "Nieuwe kaart toevoegen" @@ -356,10 +357,10 @@ nl: learn_about: "Meer informatie over de nieuwe functies" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Abonneren op agenda" inital_setup_error_message: "Er is een fout opgetreden tijdens het ophalen van gegevens." @@ -575,7 +576,7 @@ nl: members: "Nodig nieuwe leden uit om deel te nemen aan uw project." quick_add_button: "Klik op het plus (+) pictogram in de koptekst navigatie om een nieuw project te maken of collega's uit te nodigen." sidebar_arrow: "Gebruik de terug pijl in de linkerbovenhoek om terug te keren naar het project hoofdmenu." - welcome: "Neem drie minuten introductie rondleiding om de meeste belangrijke kenmerken te leren.
het is raadzaam de stappen uit te voeren tot het einde. U kunt de tour ieder moment opnieuw doen." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Binnen de wiki kunt u kennis delen en documenteren met uw team." backlogs: overview: "Beheer uw werk in de backlogs weergave." diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml index 883d329932df..c671d6a2d25f 100644 --- a/config/locales/crowdin/js-no.yml +++ b/config/locales/crowdin/js-no.yml @@ -105,6 +105,7 @@ button_update: "Oppdatèr" button_export-pdf: "Last ned PDF" button_export-atom: "Last ned Atom" + button_generate_pdf: "Generate PDF" button_create: "Opprett" card: add_new: "Legg til nytt kort" @@ -356,10 +357,10 @@ learn_about: "Lær mer om de nye funksjonene" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Abonner på kalender" inital_setup_error_message: "En feil oppstod under henting av data." @@ -575,7 +576,7 @@ members: "Inviter nye medlemmer til å bli med i prosjektet ditt." quick_add_button: "Klikk på plussikonet (+) i toppnavigasjonen til opprette et nytt prosjekt eller for å inviterer kolleger." sidebar_arrow: "Bruk returpilen i øvre venstre hjørne for å gå tilbake til prosjektets hovedmeny." - welcome: "Ta en tre minutters introduksjon for å lære de viktigste mulighetene.
Vi anbefaler å fullføre alle trinnene. Du kan når som helst starte på nytt." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "I wiki kan du dokumentere og dele kunnskap sammen med teamet." backlogs: overview: "Administrer arbeidet ditt i - backlogs -visningen." diff --git a/config/locales/crowdin/js-pl.yml b/config/locales/crowdin/js-pl.yml index d6287a1855fa..15a751e25827 100644 --- a/config/locales/crowdin/js-pl.yml +++ b/config/locales/crowdin/js-pl.yml @@ -105,6 +105,7 @@ pl: button_update: "Aktualizacja" button_export-pdf: "Pobierz plik PDF" button_export-atom: "Pobierz Atom" + button_generate_pdf: "Generate PDF" button_create: "Utwórz" card: add_new: "Dodaj nową kartę" @@ -356,10 +357,10 @@ pl: learn_about: "Dowiedz się więcej o nowych funkcjach" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - Ta wersja wprowadza różne funkcje i ulepszenia, takie jak:
  • Usprawnienie komunikacji dzięki lepiej zorganizowanej karcie Aktywność, ładowaniu wiadomości i powiadomień w czasie rzeczywistym, reakcjom emoji itd.
  • Korzystanie z łatwych ustawień uwierzytelniania logowania jednokrotnego przy użyciu SAML i OIDC w administracji Enterprise Cloud.
  • Korzystanie z nowej „standardowej roli globalnej” i włączanie uprawnień do wyświetlania adresów e-mail.
  • Łatwiejsza nawigacja na listach projektów dzięki nagłówkom tabel szybkich działań.
  • Uproszczone ustawienia projektu z mniejszą liczbą potrzebnych zmiennych projektu paska bocznego.
  • Ograniczenie ręcznego czyszczenia podczas dodawania niestandardowego pola do typu — koniec z automatycznym stosowaniem do wszystkich projektów.
  • Lepsza przejrzystość nawigacji — nazwa „Moje konto” została zmieniona na „Ustawienia konta”.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subskrybuj kalendarz" inital_setup_error_message: "Podczas pobierania danych wystąpił błąd." @@ -575,7 +576,7 @@ pl: members: "Zaproś nowych członków do swojego projektu." quick_add_button: "Kliknij ikonę plus (+) w nawigacji nagłówka, aby utworzyć nowy projekt lub zaprosić współpracowników." sidebar_arrow: "Użyj strzałki powrotu w lewym górnym rogu, aby wrócić do menu głównego projektu." - welcome: "Poświęć trzy minuty na zapoznanie się z najważniejszymi funkcjami. \n
Zalecamy wykonanie tych kroków do końca. Zwiedzanie można w każdej chwili zacząć od nowa." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "W wiki możesz dokumentować wiedzę i dzielić się nią z zespołem." backlogs: overview: "Zarządzaj swoją pracą w widoku backlogs." diff --git a/config/locales/crowdin/js-pt-BR.yml b/config/locales/crowdin/js-pt-BR.yml index 9b4463d68952..0d354c51128e 100644 --- a/config/locales/crowdin/js-pt-BR.yml +++ b/config/locales/crowdin/js-pt-BR.yml @@ -105,6 +105,7 @@ pt-BR: button_update: "Atualizar" button_export-pdf: "Baixar PDF" button_export-atom: "Baixar Atom" + button_generate_pdf: "Generate PDF" button_create: "Criar" card: add_new: "Adicionar novo cartão" @@ -355,10 +356,10 @@ pt-BR: learn_about: "Saiba mais sobre os novos recursos" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - A versão traz vários recursos e melhorias para você, por exemplo:
  • Impulsione sua comunicação com uma guia de Atividades melhor estruturada, mensagens de carregamento em tempo real e notificações, reações com emojis e muito mais.
  • Beneficie-se de configurações fáceis de autenticação Single Sign-On com SAML e OIDC na administração da sua Enterprise Cloud.
  • Use o novo ‘Papel global padrão’ e habilite permissões para visualizar endereços de e-mail.
  • Desfrute de navegação mais fácil nas listas de projetos com cabeçalhos de tabela de ações rápidas.
  • Experimente configurações de design simplificadas, com menos variáveis de design na barra lateral necessárias.
  • Reduza a limpeza manual ao adicionar um campo personalizado a um tipo (sem mais aplicação automática a todos os projetos).
  • Beneficie-se de uma navegação mais clara – "Minha conta" foi renomeado para "Configurações da conta".
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Assinar calendário" inital_setup_error_message: "Ocorreu um erro ao buscar dados." @@ -574,14 +575,14 @@ pt-BR: members: "Convide novos membros para participar de seu projeto." quick_add_button: "Clique no ícone mais (+) no menu de navegação para criar um novo projeto ou para convidar colegas de trabalho." sidebar_arrow: "Use a seta de retorno no canto superior esquerdo para retornar ao menu principal do projeto." - welcome: "Acompanhe um tour de apresentação de 3 minutos para descobrir mais recursos importantes.
Recomendamos que você conclua as etapas até o final. Você pode reiniciar o tour a qualquer momento." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Na wiki, você pode documentar e compartilhar conhecimento junto com sua equipe. " backlogs: overview: "Gerencie seu trabalho na visão de backlogs." - sprints: "À direita você encontra o backlog do produto e de erros, à esquerda você encontra os respectivos sprints. Aqui você pode criar épicos, histórias de usuário e bugs, priorizar através de arrastar e soltar e adicioná-los a um sprint." - task_board_arrow: "Para ver o seu quadro de tarefas, abra o menu suspenso de sprint ... " + sprints: "À direita, você tem o backlog de produto e o backlog de erro, à esquerda, você tem as respectivas sprints. Aqui você pode criar épicos, user stories e erros, priorizar via arrastar e soltar e adicioná-los a uma sprint." + task_board_arrow: "Para ver o seu quadro de tarefas, abra o menu suspenso da sprint..." task_board_select: "... e selecione a entrada do quadro de tarefas. " - task_board: "O painel de tarefas visualiza o progresso deste sprint. Clique no ícone mais (+) ao lado de uma história de usuário para adicionar novas tarefas ou impedimentos.
A situação pode ser atualizada arrastando e soltando." + task_board: "O quadro de tarefas visualiza o progresso desta sprint. Clique no ícone de mais (+) ao lado de uma user story para adicionar novas tarefas ou impedimentos.
O status pode ser atualizado por arrastar e soltar." boards: overview: "Selecione quadros para mudar a visão e gerenciar seu projeto usando a exibição de quadros ágeis." lists_kanban: "Aqui você pode criar várias listas (colunas) dentro do seu painel. Este recurso permite que você crie um Quadro Kanban, por exemplo." diff --git a/config/locales/crowdin/js-pt-PT.yml b/config/locales/crowdin/js-pt-PT.yml index 12f36114d7f0..b6804f138edf 100644 --- a/config/locales/crowdin/js-pt-PT.yml +++ b/config/locales/crowdin/js-pt-PT.yml @@ -105,6 +105,7 @@ pt-PT: button_update: "Atualizar" button_export-pdf: "Transferir PDF" button_export-atom: "Transferir Atom" + button_generate_pdf: "Generate PDF" button_create: "Criar" card: add_new: "Adicionar novo cartão" @@ -356,10 +357,10 @@ pt-PT: learn_about: "Saiba mais sobre os novos recursos" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - A versão traz várias funcionalidades e melhorias para si, por exemplo,
  • Melhore a sua comunicação com um separador Atividade melhor estruturado, mensagens e notificações de carregamento em tempo real, reações com emoji e muito mais.
  • Beneficie de definições fáceis de autenticação Single Sign-On (Início de sessão único) com SAML e OIDC na sua administração do Enterprise Cloud.
  • Utilize a nova "Função global padrão" e ative as permissões para visualizar endereços de e-mail.
  • Desfrute de uma navegação mais fácil nas listas de projetos com cabeçalhos de tabela de ação rápida.
  • Experimente configurações de design simplificadas com menos variáveis de design da barra lateral necessárias.
  • Reduza a limpeza manual ao adicionar um campo personalizado a um tipo – já não se aplica automaticamente a todos os projetos.
  • Beneficie de uma maior clareza de navegação – "A minha conta" foi renomeada para "Definições da conta".
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscrever o calendário" inital_setup_error_message: "Ocorreu um erro ao recuperar os dados." @@ -575,7 +576,7 @@ pt-PT: members: "Convide novos membros para participarem no seu projeto." quick_add_button: "Clique no ícone mais (+) no menu de navegação para criar um novo projeto ou convidar colegas." sidebar_arrow: "Use a seta de retorno no canto superior esquerdo para voltar ao menu principal do projeto." - welcome: "Acompanhe um tour de apresentação de 3 minutos para descobrir mais recursos importantes.
Recomendamos que conclua as etapas até ao final. Pode reiniciar o tour a qualquer momento." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Na wiki pode documentar e partilhar conhecimento com a sua equipa." backlogs: overview: "Faça a gestão do seu trabalho na vista de backlogs." diff --git a/config/locales/crowdin/js-ro.yml b/config/locales/crowdin/js-ro.yml index 7c582d9b7c2e..d04b14c5cac4 100644 --- a/config/locales/crowdin/js-ro.yml +++ b/config/locales/crowdin/js-ro.yml @@ -97,7 +97,7 @@ ro: button_show_table: "Afișați vizualizarea tabelului" button_show_gantt: "Arată vizualizarea Gantt" button_show_fullscreen: "Arată vizualizarea pe tot ecranul" - button_more_actions: "Mai multe actiuni" + button_more_actions: "Mai multe acțiuni" button_quote: "Citat" button_save: "Salvează" button_settings: "Setări" @@ -105,6 +105,7 @@ ro: button_update: "Actualizare" button_export-pdf: "Descarcă PDF" button_export-atom: "Descarcă Atom" + button_generate_pdf: "Generate PDF" button_create: "Creează" card: add_new: "Adaugă card nou" @@ -239,7 +240,7 @@ ro: upsale: become_hero: "Deveniți un erou!" enterprise_info_html: "%{feature_title} is an Enterprise add-on." - upgrade_info: "Vă rugăm să treceți la un plan plătit pentru a-l activa și a începe să îl utilizați în echipa dumneavoastră." + upgrade_info: "Te rog să treci la un plan plătit pentru a-l activa și a începe să îl utilizezi în echipa ta." benefits: description: "Care sunt avantajele ediției Enterprise on-premise?" high_security: "Caracteristici de securitate" @@ -252,7 +253,7 @@ ro: professional_support_text: "Beneficiați de asistență fiabilă, de înaltă calitate, din partea unor ingineri de asistență seniori cu cunoștințe de specialitate în ceea ce privește utilizarea OpenProject în medii critice pentru afaceri." button_start_trial: "Începeți o încercare gratuită" button_upgrade: "Actualizează acum" - button_contact_us: "Contactați-ne pentru o demonstrație" + button_contact_us: "Contactează-ne pentru o demonstrație" button_book_now: "Rezervă acum" confidence: > Oferim încrederea unui software de gestionare a proiectelor de clasă enterprise testat și susținut - cu Open Source și o minte deschisă. @@ -351,14 +352,14 @@ ro: homescreen: blocks: new_features: - text_new_features: "Citiți despre noile caracteristici și actualizări de produse." + text_new_features: "Citește despre noile caracteristici și actualizări de produse." learn_about: "Aflați mai multe despre noile caracteristici" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -372,14 +373,14 @@ ro: success_message: 'The URL "%{name}" was successfully copied to your clipboard. Paste it in your calendar client to complete the subscription.' label_activate: "Activare" label_assignee: "Executant" - label_add_column_after: "Adauga o coloana dupa" - label_add_column_before: "Adauga o coloana inainte" - label_add_columns: "Adaugați coloane" + label_add_column_after: "Adaugă coloană după" + label_add_column_before: "Adaugă coloană înainte" + label_add_columns: "Adaugă coloane" label_add_comment: "Adăugare comentariu" label_add_comment_title: "Comentează și tastează @ pentru a notifica alte persoane" label_add_row_after: "Adauga un rand dupa" label_add_row_before: "Adauga un rand inainte" - label_add_selected_columns: "Adăugați coloanele selectate" + label_add_selected_columns: "Adaugă coloanele selectate" label_added_by: "adăugat de" label_added_time_by: 'Adăugat de %{author} acum %{age}' label_ago: "zile în urmă" @@ -425,7 +426,7 @@ ro: label_expanded: "extins" label_expand_all: "Extindere totală" label_expand_project_menu: "Deschideți meniul proiectului" - label_export: "Exportare" + label_export: "Exportă" label_export_preparing: "Exportul este în curs de pregătire și va fi descărcat în curând." label_favorites: "Favorite" label_filename: "Fișier" @@ -444,7 +445,7 @@ ro: label_in_more_than: "în mai mult de" label_incoming_emails: "E-mailuri primite" label_information_plural: "Informații" - label_invalid: "Nevalid" + label_invalid: "Invalid" label_import: "Importă" label_latest_activity: "Activitate recentă" label_last_updated_on: "Ultima actualizare la data de" @@ -486,8 +487,8 @@ ro: label_recent: "Recente" label_reset: "Resetare" label_remove: "Eliminare" - label_remove_column: "Elimina colana" - label_remove_columns: "Eliminare coloane selectate" + label_remove_column: "Elimină coloana" + label_remove_columns: "Elimină coloane selectate" label_remove_row: "Elimina rand" label_report: "Raportare" label_repository_plural: "Repo-uri" @@ -516,7 +517,7 @@ ro: label_time_entry_plural: "Timp consumat" label_up: "Sus" label_user_plural: "Utilizatori" - label_activity_show_only_comments: "Afișați doar activitățile ce conțin comentarii" + label_activity_show_only_comments: "Arată doar activitățile cu comentarii" label_activity_show_all: "Afișează toate activitățile" label_total_progress: "%{percent} % Progres total" label_total_amount: "Total: %{amount}" @@ -544,8 +545,8 @@ ro: label_attachments: Atașamente label_drop_files: "Aruncați fișierele aici pentru a atașa fișiere." label_drop_or_click_files: "Trage fișierele aici sau clic aici pentru a atașa." - label_drop_folders_hint: Nu puteți încărca dosare ca atașament. Vă rugăm să selectați fișiere individuale. - label_add_attachments: "Atașare fișiere" + label_drop_folders_hint: Nu poți încărca dosare ca atașament. Te rog selectează fișiere individuale. + label_add_attachments: "Atașează fișiere" label_formattable_attachment_hint: "Atașați și legați fișiere prin plasarea în acest câmp sau prin lipirea din clipboard." label_remove_file: "Ştergere %{fileName}" label_remove_watcher: "Eliminare observator %{name}" @@ -574,7 +575,7 @@ ro: members: "Invitați noi membri să se alăture proiectului dumneavoastră." quick_add_button: "Dă click pe pictograma plus (+) din antetul navigării pentru a crea un nou proiect sau invita colaboratori." sidebar_arrow: "Folosește săgeata de întoarcere din colțul din stânga sus pentru a te întoarce în meniul al proiectului." - welcome: "Faceți un tur introductiv de trei minute pentru a afla cele mai importante caracteristici.
Vă recomandăm să parcurgeți pașii până la sfârșit. Puteți relua turul în orice moment.
" + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "În cadrul Wiki puteți documenta și împărtăși cunoștințe împreună cu echipa dumneavoastră." backlogs: overview: "Gestionează-ți munca în vizualizarea backlogs." @@ -615,7 +616,7 @@ ro: created: "Creat pe" scheduled: "Planificat" commented: "Cu comentarii" - processed: "Processed" + processed: "Procesat" prioritized: "Prioritized" dateAlert: "Alertă dată" shared: "Partajat" @@ -637,14 +638,14 @@ ro: few: "și %{count} alții" other: "și %{count} alții" no_results: - at_all: "Aici vor apărea notificări noi atunci când există o activitate care vă interesează." + at_all: "Aici vor apărea notificări noi atunci când există o activitate care te interesează." with_current_filter: "Nu există notificări în această vizualizare în acest moment" mark_all_read: "Marchează toate ca și citite" mark_as_read: "Marchează ca Citit" text_update_date_by: "%{date} de" total_count_warning: "Se afișează %{newest_count} cele mai recente notificări. %{more_count} în plus nu sunt afișate." empty_state: - no_notification: "Se pare că v-ați pus la punct." + no_notification: "Se pare că ești cu toate la zi." no_notification_with_current_project_filter: "Se pare că v-ați pus la punct cu proiectul selectat." no_notification_with_current_filter: "Se pare că ești la zi cu filtrul %{filter}." no_notification_for_filter: "Looks like you are all caught up for this filter." @@ -653,16 +654,16 @@ ro: message: "Există notificări noi." link_text: "Click here to load them." settings: - change_notification_settings: 'Puteți modifica setările de notificare pentru a vă asigura că nu pierdeți niciodată o actualizare importantă.' + change_notification_settings: 'Poți modifica setările de notificare pentru a te asigura că nu pierzi niciodată o actualizare importantă.' title: "Setări notificare" - notify_me: "Anunta-ma" + notify_me: "Notifică-mă" reminders: no_notification: Nicio notificare timeframes: normal: PT0S: în aceeași zi - P1D: Cu 1 zi înainte - P3D: Cu 3 zile înainte + P1D: cu 1 zi înainte + P3D: cu 3 zile înainte P7D: ' cu o săptămână înainte ' overdue: P1D: zilnic @@ -671,7 +672,7 @@ ro: reasons: mentioned: title: "Menţionat" - description: "Primește o notificare de fiecare dată când cineva mă menționează oriunde" + description: "Primesc o notificare de fiecare dată când cineva mă menționează oriunde" assignee: "Executant" responsible: "Responsabil" shared: "Partajat" @@ -679,7 +680,7 @@ ro: work_package_commented: "Toate comentariile noi" work_package_created: "Pachete de lucru noi" work_package_processed: "Toate modificările de stare" - work_package_prioritized: "Toate modificările prioritare" + work_package_prioritized: "Toate modificările de prioritate" work_package_scheduled: "Toate modificările dății" global: immediately: @@ -710,7 +711,7 @@ ro: placeholders: default: "-" subject: "Introduceţi subiectul aici" - selection: "Vă rugăm să selectaţi" + selection: "Te rog selectează" description: "Descriere: Clic pentru a edita..." relation_description: "Clic pentru a adăuga o descriere pentru această relație" project: @@ -854,12 +855,12 @@ ro: scheduling: manual: "Programarea manuală" sort: - sorted_asc: "Sortare ascendentă aplicată " - sorted_dsc: "Sortare descendentă aplicată " + sorted_asc: "Ordonare ascendentă aplicată, " + sorted_dsc: "Ordonare descendentă aplicată, " sorted_no: "Nu a fost selectată nicio sortare " sorting_disabled: "sortarea este dezactivată" - activate_asc: "activați pentru a sorta ascendent" - activate_dsc: "activați pentru a sorta descendent" + activate_asc: "activează pentru a ordona ascendent" + activate_dsc: "activează pentru a ordona descendent" activate_no: "activați pentru a înlătura sortarea" text_work_packages_destroy_confirmation: "Sunteți sigur că doriți ștergerea pachetelor de lucru selectate?" text_query_destroy_confirmation: "Sunteți sigur că doriți să ștergeți vizualizarea selectată?" @@ -958,7 +959,7 @@ ro: children_expanded: "Nivelul ierarhic %{level}, extins. Faceți clic pentru a restrânge copiii filtrați" faulty_query: title: Pachetele de lucru nu au putut fi încărcate. - description: Vizualizarea dvs. este eronată și nu a putut fi procesată. + description: Vederea ta este eronată și nu a putut fi prelucrată. no_results: title: Nu sunt pachete de lucru de afișat. description: Nu a fost creat niciun pachet de lucru, sau toate sunt eliminate prin filtru. @@ -1054,13 +1055,13 @@ ro: configure_button: "Configurarea tabelului pachetului de lucru" summary: "Tabel cu pachete de lucru pe rânduri şi câmpurile pachetelor pe coloane." text_inline_edit: "Majoritatea celulelor din acest tabel sunt butoane care activează editarea \"inline\" a câmpului respectiv." - text_sort_hint: "Cu link-urile din capul de tabel puteți sorta, grupa, reordona, elimina și adăuga coloane la tabel." + text_sort_hint: "Cu link-urile din capul de tabel poți sorta, grupa, reordona, elimina și adăuga coloane la tabel." text_select_hint: "Casetele de selectare ar trebui să fie deschise cu 'ALT' si tastele săgeată." table_configuration: button: "Configurați acest tabel al pachetului de lucru" choose_display_mode: "Afișare pachete de lucru din subproiecte pe pagina proiectului principal" modal_title: "Configurația tabelului pachetului de lucru" - embedded_tab_disabled: "Această filă de configurare nu este disponibilă pentru vizualizarea încorporată pe care o editați." + embedded_tab_disabled: "Această filă de configurare nu este disponibilă pentru vizualizarea încorporată pe care o editezi." default: "implicit" display_settings: "Setări afișare" default_mode: "Listă" @@ -1083,7 +1084,7 @@ ro: automatic: "Automat" manually: "Manual" warning: "La activarea modului de sortare automată, veți pierde sortarea anterioară." - columns_help_text: "Utilizați datele de mai sus pentru a adăuga sau elimina coloane în vizualizarea tabelului. Puteți glisa și plasa coloanele pentru a le reordona." + columns_help_text: "Utilizează datele de mai sus pentru a adăuga sau elimina coloane în vizualizarea tabelului. Poți glisa și plasa coloanele pentru a le reordona." upsale: attribute_highlighting: "Aveți nevoie ca anumite pachete de lucru să iasă în evidență?" relation_columns: "Aveți nevoie să vedeți relațiile din lista pachetelor de lucru?" @@ -1102,7 +1103,7 @@ ro: months: "luni" toolbar: settings: - configure_view: "Configurați vizualizarea" + configure_view: "Configurează vizualizarea" columns: "Coloane" sort_by: "Sortare după" group_by: "Grupare după" @@ -1112,7 +1113,7 @@ ro: hide_sums: "Ascundere totaluri" save: "Salvează" save_as: "Salvează ca" - export: "Exportare" + export: "Exportă" visibility_settings: "Setări vizibilitate" share_calendar: "Subscribe to calendar" page_settings: "Redenumire" @@ -1222,14 +1223,14 @@ ro: invite_principal_to_project: "Invitați %{principal} la %{project}" project: label: "Proiect" - required: "Te rog să selectezi un proiect" - lacking_permission: "Te rog să selectezi un alt proiect, deoarece nu ai permisiuni pentru a atribui utilizatori la cel selectat în prezent." + required: "Te rog selectează un proiect" + lacking_permission: "Te rog selectează un alt proiect, deoarece nu ai permisiuni pentru a atribui utilizatori la cel selectat în prezent." lacking_permission_info: "Nu aveți permisiunea de a atribui utilizatori la proiectul în care vă aflați în prezent. Trebuie să selectați un alt proiect." next_button: "Înainte" no_results: "Nu au fost găsite proiecte" no_invite_rights: "Nu aveți voie să invitați membri în acest proiect" type: - required: "Te rog să selectezi tipul de invitat" + required: "Te rog selectează tipul de invitat" user: title: "Utilizator" description: "Permisiuni bazate pe rolul atribuit în proiectul selectat" @@ -1253,15 +1254,15 @@ ro: no_results_group: "Nu au fost găsite grupuri" next_button: "Înainte" required: - user: "Te rog să selectezi un utilizator" - placeholder: "Te rog să selectezi un substituent" - group: "Te rog să selectezi un grup" + user: "Te rog selectează un utilizator" + placeholder: "Te rog selectează un substituent" + group: "Te rog selectează un grup" role: label: "Rolul în %{project}" no_roles_found: "Nu au fost găsite roluri" description: >- This is the role that the user will receive when they join your project. Rolul definește acțiunile pe care utilizatorul are voie să le întreprindă și informațiile pe care le poate vedea. Aflați mai multe despre roluri și permisiuni. - required: "Te rog să selectezi un rol" + required: "Te rog selectează un rol" next_button: "Înainte" message: label: "Mesaj invitație" diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index 72af88e09bec..a2df51fce925 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -105,6 +105,7 @@ ru: button_update: "Обновление" button_export-pdf: "Скачать PDF" button_export-atom: "Скачать Atom" + button_generate_pdf: "Создать PDF" button_create: "Создать" card: add_new: "Добавить новую карту" @@ -355,10 +356,10 @@ ru: learn_about: "Подробнее о новых функциях" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Подписаться на календарь" inital_setup_error_message: "Произошла ошибка при получении данных." diff --git a/config/locales/crowdin/js-rw.yml b/config/locales/crowdin/js-rw.yml index 7bba3fd311a5..0c608006cb32 100644 --- a/config/locales/crowdin/js-rw.yml +++ b/config/locales/crowdin/js-rw.yml @@ -105,6 +105,7 @@ rw: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ rw: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ rw: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-si.yml b/config/locales/crowdin/js-si.yml index e2c0f71de022..d171399479a5 100644 --- a/config/locales/crowdin/js-si.yml +++ b/config/locales/crowdin/js-si.yml @@ -105,6 +105,7 @@ si: button_update: "යාවත්කාලීන" button_export-pdf: "PDF බාගන්න" button_export-atom: "බාගත කරන්න පරමාණුව" + button_generate_pdf: "Generate PDF" button_create: "සාදන්න" card: add_new: "නව කාඩ් එකතු කරන්න" @@ -356,10 +357,10 @@ si: learn_about: "නව විශේෂාංග ගැන වැඩි විස්තර දැනගන්න" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ si: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "වඩාත්ම ඉගෙන ගැනීමට විනාඩි තුනක් හඳුන්වාදීමේ චාරිකාවක් ගන්න වැදගත් ලක්ෂණ.
අවසානය දක්වා පියවර සම්පූර්ණ කිරීම අපි නිර්දේශ කරමු. ඔබට ඕනෑම වේලාවක සංචාරය නැවත ආරම්භ කළ හැකිය." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-sk.yml b/config/locales/crowdin/js-sk.yml index 3618d2d0405d..d9a1ceab5154 100644 --- a/config/locales/crowdin/js-sk.yml +++ b/config/locales/crowdin/js-sk.yml @@ -105,6 +105,7 @@ sk: button_update: "Aktualizovať" button_export-pdf: "Stiahnuť PDF" button_export-atom: "Stiahnuť Atom" + button_generate_pdf: "Generate PDF" button_create: "Vytvoriť" card: add_new: "Pridať novú kartu" @@ -356,10 +357,10 @@ sk: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ sk: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Urobte si tri minúty čas na úvodnú prehliadku, aby ste sa naučili čo najviac dôležité funkcie.
Doporučujeme dokončiť prehliadku až do konca. Prehliadku môžete kedykoľvek reštartovať." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-sl.yml b/config/locales/crowdin/js-sl.yml index a5169c3cf2a4..fc3107744c86 100644 --- a/config/locales/crowdin/js-sl.yml +++ b/config/locales/crowdin/js-sl.yml @@ -105,6 +105,7 @@ sl: button_update: "Posodobi" button_export-pdf: "Prenesi PDF" button_export-atom: "Prenesi Atom" + button_generate_pdf: "Generate PDF" button_create: "Ustvari" card: add_new: "Dodaj nov card" @@ -355,10 +356,10 @@ sl: learn_about: "Preberite več o novostih" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -574,7 +575,7 @@ sl: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Poglejte si tri minutni ogled, da se naučite čim več pomembne lastnosti.
Priporočamo, da ogled dokončat. Ogled lahko ponovno začnete kadar koli. " + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-sr.yml b/config/locales/crowdin/js-sr.yml index d769518db554..0cc01275c54e 100644 --- a/config/locales/crowdin/js-sr.yml +++ b/config/locales/crowdin/js-sr.yml @@ -105,6 +105,7 @@ sr: button_update: "Ažuriraj" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ sr: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ sr: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-sv.yml b/config/locales/crowdin/js-sv.yml index 5cbb7a54465f..ad3d5a52bcf0 100644 --- a/config/locales/crowdin/js-sv.yml +++ b/config/locales/crowdin/js-sv.yml @@ -105,6 +105,7 @@ sv: button_update: "Uppdatera" button_export-pdf: "Ladda ner PDF" button_export-atom: "Ladda ner Atom" + button_generate_pdf: "Generate PDF" button_create: "Skapa" card: add_new: "Lägg till kort" @@ -355,10 +356,10 @@ sv: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -574,7 +575,7 @@ sv: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Ta en tre minuters introduktionstur för att lära dig de viktigaste funktionerna.
Vi rekommenderar att du slutför stegen till slutet. Du kan starta om turen när som helst." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-th.yml b/config/locales/crowdin/js-th.yml index feec1d35ecfd..67cb2ae5a9ff 100644 --- a/config/locales/crowdin/js-th.yml +++ b/config/locales/crowdin/js-th.yml @@ -105,6 +105,7 @@ th: button_update: "ปรับปรุง" button_export-pdf: "ดาวน์โหลดไฟล์ PDF" button_export-atom: "ดาวน์โหลดไฟล์ Atom" + button_generate_pdf: "Generate PDF" button_create: "สร้าง" card: add_new: "Add new card" @@ -356,10 +357,10 @@ th: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ th: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-tr.yml b/config/locales/crowdin/js-tr.yml index e30c0e9362fc..e6aa0cfac3ce 100644 --- a/config/locales/crowdin/js-tr.yml +++ b/config/locales/crowdin/js-tr.yml @@ -105,6 +105,7 @@ tr: button_update: "Güncelleştirme" button_export-pdf: "PDF indir" button_export-atom: "Atom İndir" + button_generate_pdf: "Generate PDF" button_create: "Oluştur" card: add_new: "Yeni kart ekleyin" @@ -355,10 +356,10 @@ tr: learn_about: "Yeni özellikler hakkında daha fazla bilgi edinin" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -574,7 +575,7 @@ tr: members: "Projenize katılmak için yeni üyeler davet edin." quick_add_button: "Yeni bir proje oluşturmak veya iş arkadaşlarınızı davet etmek için başlık bölümündeki artı (+) simgesini tıklayın." sidebar_arrow: "Projenin ana menüsüne dönmek için sol üst köşedeki dönüş okunu kullanın." - welcome: "En önemli özellikleri öğrenmek için üç dakikalık bir tanıtım gezintisine çıkın.
Tüm adımları tamamlamanızı öneririz. Turu istediğiniz zaman yeniden başlatabilirsiniz." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "wiki içinde belgeleyebilir ve ekibinizle birlikte bilgi paylaşabilirsiniz." backlogs: overview: "İşinizi birikimler görünümünde yönetin." @@ -728,7 +729,7 @@ tr: settings: daily: add_time: "Süre ekle" - enable: "Günlük email hatırlatıcılarını etkinleştir" + enable: "Günlük e-posta hatırlatıcılarını etkinleştir" explanation: "Bu hatırlatıcıları yalnızca okunmamış bildirimler için ve yalnızca sizin belirlediğiniz saatlerde alacaksınız. %{no_time_zone}" no_time_zone: "Hesabınız için bir saat dilimi yapılandırana kadar, saatler UTC olarak yorumlanacaktır." time_label: "Zaman %{counter}:" @@ -750,9 +751,9 @@ tr: wiki_page_updated: "Viki sayfası güncellendi" membership_added: "Üyelik eklendi" membership_updated: "Üyelik güncellendi" - title: "Email hatırlatıcıları" + title: "E-posta hatırlatıcıları" pause: - label: "Email hatırlatıcılarını geçici olarak durdur" + label: "E-posta hatırlatıcılarını geçici olarak durdur" first_day: "İlk gün" last_day: "Son gün" text_are_you_sure: "Emin misiniz?" diff --git a/config/locales/crowdin/js-uk.yml b/config/locales/crowdin/js-uk.yml index 6d0041718cef..1e351902fcd1 100644 --- a/config/locales/crowdin/js-uk.yml +++ b/config/locales/crowdin/js-uk.yml @@ -105,6 +105,7 @@ uk: button_update: "Оновити" button_export-pdf: "Завантажити PDF" button_export-atom: "Завантажити Atom" + button_generate_pdf: "Згенерувати PDF" button_create: "Створити" card: add_new: "Додати нову картку" @@ -356,10 +357,10 @@ uk: learn_about: "Дізнатися більше про нові функції" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - Цей випуск містить багато функцій і покращень, наприклад:
  • Спілкуйтесь ефективніше за допомогою краще структурованої вкладки «Дії», завантаження повідомлень і сповіщень у реальному часі, реакцій за допомогою емодзі тощо.
  • Скористайтеся простими налаштуваннями автентифікації SSO за допомогою протоколів SAML і OIDC на панелі адміністрування Enterprise Cloud.
  • Використовуйте нову роль «Стандартна глобальна роль» і надавайте дозволи на перегляд електронних адрес.
  • Насолоджуйтеся простішою навігацією списками проєктів із заголовками таблиці швидких дій.
  • Полегшіть налаштування завдяки меншій кількості змінних оформлення бічної панелі.
  • Заощаджуйте час на очищення, визначивши тип користувацького поля. Типи більше не визначаються автоматично для всіх проєктів.
  • Скористайтеся перевагами чіткішої навігації — розділ «Мій обліковий запис» тепер має назву «Налаштування облікового запису».
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Підписатися на календар" inital_setup_error_message: "Під час отримання даних сталася помилка." @@ -575,7 +576,7 @@ uk: members: "Запросіть нових учасників до свого проєкту." quick_add_button: "Натисніть на значок плюса (+) на панелі заголовків, щоб створити новий проєкт або запросити колег." sidebar_arrow: "Використовуйте стрілку повернення у верхньому лівому куті, щоб повернутися в головне меню проєкту." - welcome: "Здійсніть трихвилинний ознайомчий огляд для вивчення найважливішого функціоналу.
Ми рекомендуємо пройти всі кроки до завершення огляду. Ви можете повернутися до цього огляду повторно в будь-який час." + welcome: "Пройдіть трихвилинний вступний тур, щоб дізнатися про найважливіші функції.
Ми рекомендуємо завершити всі етапи до кінця. Ви можете перезапустити тур у будь-який час." wiki: "У межах Wiki ви можете документувати знання та обмінюватися ними зі своєю командою." backlogs: overview: "Керуйте своєю роботою в поданні Backlogs." diff --git a/config/locales/crowdin/js-uz.yml b/config/locales/crowdin/js-uz.yml index 1a005a46e472..a35f5a7117ca 100644 --- a/config/locales/crowdin/js-uz.yml +++ b/config/locales/crowdin/js-uz.yml @@ -105,6 +105,7 @@ uz: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: add_new: "Add new card" @@ -356,10 +357,10 @@ uz: learn_about: "Learn more about the new features" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Subscribe to calendar" inital_setup_error_message: "An error occured while fetching data." @@ -575,7 +576,7 @@ uz: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/locales/crowdin/js-vi.yml b/config/locales/crowdin/js-vi.yml index 3d2b36b9122d..8111aee623c7 100644 --- a/config/locales/crowdin/js-vi.yml +++ b/config/locales/crowdin/js-vi.yml @@ -105,6 +105,7 @@ vi: button_update: "Cập Nhật" button_export-pdf: "Tải xuống PDF" button_export-atom: "Tải xuống Atom" + button_generate_pdf: "Generate PDF" button_create: "Tạo" card: add_new: "Thêm thẻ mới" @@ -356,10 +357,10 @@ vi: learn_about: "Tìm hiểu thêm về các tính năng mới" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - The release brings various features and improvements for you, e.g.
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • Enjoy easier navigation in project lists with quick action table headers.
  • Experience simplified design settings with fewer sidebar design variables needed.
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
+ The release brings various features and improvements for you, e.g.
  • Custom fields of type hierarchy (Enterprise add-on).
  • Redesign of the Relations tab in work packages.
  • Redesign of the Meetings index page.
  • Manual page breaks in PDF work package exports.
  • Zen mode for project lists.
ical_sharing_modal: title: "Đăng ký lịch" inital_setup_error_message: "Đã xảy ra lỗi khi lấy dữ liệu." @@ -575,7 +576,7 @@ vi: members: "Mời thành viên mới tham gia dự án của bạn." quick_add_button: "Nhấp vào biểu tượng cộng (+) trong thanh điều hướng tiêu đề để tạo một dự án mới hoặc mời đồng nghiệp." sidebar_arrow: "Sử dụng mũi tên trở lại ở góc trên bên trái để quay lại menu chính của dự án." - welcome: "Tham gia tour giới thiệu ba phút để tìm hiểu những tính năng quan trọng nhất.
Chúng tôi khuyến nghị bạn hoàn thành các bước cho đến cuối. Bạn có thể khởi động lại tour bất kỳ lúc nào." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Trong wiki, bạn có thể tài liệu hóa và chia sẻ kiến thức cùng với nhóm của bạn." backlogs: overview: "Quản lý công việc của bạn trong chế độ xem backlogs." diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index 4ca865a5ecb0..d1c4b79d83af 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -105,6 +105,7 @@ zh-CN: button_update: "更新" button_export-pdf: "下载 PDF" button_export-atom: "下载 Atom" + button_generate_pdf: "生成 PDF" button_create: "创建" card: add_new: "添加新卡" @@ -355,10 +356,10 @@ zh-CN: learn_about: "详细了解新功能" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - 该版本带来了各种功能和改进,例如
  • 通过结构更合理的 "活动 "选项卡、实时加载消息和通知、表情符号回复等功能促进沟通。
  • 在企业云管理中更容易的对 SAML 和 OIDC 进行单点登录身份验证设置。
  • 使用新的 "标准全局角色 "并启用查看电子邮件地址的权限。
  • 使用快速操作表头,在项目列表中享受更便捷的导航。
  • 简化设计设置,减少侧边栏设计变量。
  • 在类型中添加自定义字段时减少手动清理,不再自动应用于所有项目。
  • 导航更清晰--"我的账户 "更名为 "账户设置"。
+ 该版本为您带来了多种新功能和改进,例如
  • 分层类型的自定义字段(企业附加组件)。
  • 重新设计工作包中的关系选项卡。
  • 重新设计会议索引页。
  • 在导出 PDF 工作包时手动分页。
  • 项目列表的禅模式。
ical_sharing_modal: title: "订阅日历" inital_setup_error_message: "获取数据时发生错误。" diff --git a/config/locales/crowdin/js-zh-TW.yml b/config/locales/crowdin/js-zh-TW.yml index 07ca88c02664..4313803c0d73 100644 --- a/config/locales/crowdin/js-zh-TW.yml +++ b/config/locales/crowdin/js-zh-TW.yml @@ -105,6 +105,7 @@ zh-TW: button_update: "更新" button_export-pdf: "下載 PDF" button_export-atom: "下載 Atom" + button_generate_pdf: "產生PDF檔案" button_create: "建立" card: add_new: "新增卡片" @@ -354,10 +355,10 @@ zh-TW: learn_about: "瞭解更多新功能的資訊" #Include the version to invalidate outdated translations in other locales. #Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > - 此版本為您帶來各種功能與改進,例如
  • 透過結構更完善的活動標籤、即時載入訊息與通知、表情符號反應等功能,提升您的溝通品質。
  • 在企業雲端管理中使用 SAML 和 OIDC 進行簡易的單一登入驗證設定,讓您獲益良多。
  • 使用新的「標準全局角色」並啟用檢視電子郵件地址的權限。
  • 使用快速行動表頭,享受專案清單中更簡易的導覽功能。
  • 使用更少的側邊欄設計變數,體驗簡化的設計設定。
  • 在類型中加入自訂欄位時減少手動清理 - 不再自動套用至所有專案。
  • 受益於更清晰的導覽 -「我的帳戶」更名為「帳戶設定」。
+ 該版本為您帶來了各種功能和改進,例如
  • 階層類型的自訂欄位 (企業附加元件)。
  • 重新設計工作套件中的「關係」標籤。
  • 重新設計會議索引頁。
  • PDF 工作套件匯出中的手動分頁。
  • 專案清單的 Zen 模式。
ical_sharing_modal: title: "訂閱日曆" inital_setup_error_message: "更新資料時發生錯誤" @@ -387,7 +388,7 @@ zh-TW: label_all_work_packages: "所有工作項目" label_and: "和" label_ascending: "昇冪" - label_author: "作者: %{user}" + label_author: "工作項目發起者: %{user}" label_avatar: "大頭貼" label_between: "介於" label_board: "面板" @@ -967,7 +968,7 @@ zh-TW: other: "其他" properties: assignee: "執行者" - author: "作者" + author: "工作項目發起者" createdAt: "建立於" description: "敘述" date: "日期" diff --git a/config/locales/crowdin/ka.seeders.yml b/config/locales/crowdin/ka.seeders.yml index 21ea4582482a..d848d0609e87 100644 --- a/config/locales/crowdin/ka.seeders.yml +++ b/config/locales/crowdin/ka.seeders.yml @@ -34,6 +34,17 @@ ka: name: ნაცრისფერი (მუქი) item_13: name: შავები + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: დოკუმენტაცია @@ -70,6 +81,21 @@ ka: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: დაბალი diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml index 3a74bd245536..e31b6704f3da 100644 --- a/config/locales/crowdin/ka.yml +++ b/config/locales/crowdin/ka.yml @@ -33,7 +33,7 @@ ka: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ ka: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ ka: single: "ან" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ ka: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: მოსაწვევი account: delete: "ანგარიშის წაშლა" @@ -1028,6 +1090,20 @@ ka: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ ka: units: hours: სთ days: დ + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ ka: label_environment: "გარემო" label_estimates_and_progress: "Estimates and progress" label_equals: "არის" + label_equals_with_descendants: "is any with descendants" label_everywhere: "ყველგან" label_example: "მაგალითი" label_experimental: "ექსპერიმენტული" @@ -2445,6 +2539,8 @@ ka: label_related_work_packages: "Related work packages" label_relates: "მიეკუთვნება" label_relates_to: "მიეკუთვნება" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "ახალი ურთიერთობა" label_release_notes: "გამოშვების შენიშვნები" diff --git a/config/locales/crowdin/kk.seeders.yml b/config/locales/crowdin/kk.seeders.yml index 6db09170f303..2937c2ed5f9e 100644 --- a/config/locales/crowdin/kk.seeders.yml +++ b/config/locales/crowdin/kk.seeders.yml @@ -34,6 +34,17 @@ kk: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ kk: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml index 2ee13bfaaf8c..99d7085f6daa 100644 --- a/config/locales/crowdin/kk.yml +++ b/config/locales/crowdin/kk.yml @@ -33,7 +33,7 @@ kk: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ kk: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ kk: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ kk: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ kk: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ kk: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ kk: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ kk: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/ko.seeders.yml b/config/locales/crowdin/ko.seeders.yml index 68e33e5764a9..1028675c3618 100644 --- a/config/locales/crowdin/ko.seeders.yml +++ b/config/locales/crowdin/ko.seeders.yml @@ -34,6 +34,17 @@ ko: name: 회색(진함) item_13: name: 검은색 + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: 설명서 @@ -70,6 +81,21 @@ ko: item_1: name: 표준 글로벌 역할 standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: 낮음 diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml index 2cd77ddabdda..176131f118b0 100644 --- a/config/locales/crowdin/ko.yml +++ b/config/locales/crowdin/ko.yml @@ -26,20 +26,20 @@ ko: no_results_title_text: 이 시간 프레임 내에서 프로젝트에 대한 활동이 없습니다. work_packages: activity_tab: - no_results_title_text: No activity to display - no_results_description_text: "Choose \"Show everything\" to show all activity and comments" - label_activity_show_all: "Show everything" - label_activity_show_only_comments: "Show comments only" - label_activity_show_only_changes: "Show changes only" - label_sort_asc: "Newest at the bottom" - label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" - label_submit_comment: "Submit comment" - changed_on: "changed on" - created_on: "created this on" - changed: "changed" - created: "created" - commented: "commented" + no_results_title_text: 표시할 활동 없음 + no_results_description_text: "모든 활동과 코멘트를 표시하려면 '모두 표시'를 선택합니다" + label_activity_show_all: "모두 표시" + label_activity_show_only_comments: "코멘트만 표시" + label_activity_show_only_changes: "변경 사항만 표시" + label_sort_asc: "오래된 순" + label_sort_desc: "최신 순" + label_type_to_comment: "Add a comment. Type @ to notify people." + label_submit_comment: "코멘트 제출" + changed_on: "- 변경함:" + created_on: "- 이 패키지를 생성함:" + changed: "- 변경함" + created: "- 생성함" + commented: "- 코멘트 작성함" admin: plugins: no_results_title_text: 현재 설치된 플러그인이 없습니다. @@ -221,24 +221,26 @@ ko: heading: 모든 프로젝트용 description: '"모든 프로젝트용" 옵션이 선택되었으므로 모든 프로젝트에서 이 사용자 지정 필드가 활성화되었습니다. 개별 프로젝트에 대해 비활성화할 수 없습니다.' items: - actions: "Item actions" + actions: "항목 작업" blankslate: root: - title: "Your list of items is empty" - description: "Start by adding items to the custom field of type hierarchy. Each item can be used to create a hierarchy bellow it. To navigate and create sub-items inside a hierarchy click on the created item." + title: "항목 목록이 비어 있습니다" + description: "먼저 유형 계층의 사용자 지정 필드에 항목을 추가하여 시작하세요. 각 항목을 사용하여 그 아래에 계층을 만들 수 있습니다. 계층 내에서 탐색하고 하위 항목을 만들려면 생성된 항목을 클릭하세요." item: - title: This item doesn't have any hierarchy level below - description: Add items to this list to create sub-items inside another one + title: 이 항목에는 아래 계층 수준이 없습니다 + description: 이 목록에 항목을 추가하여 다른 목록 내에서 하위 항목을 만듭니다 placeholder: - label: "Item label" - short: "Short name" + label: "항목 레이블" + short: "짧은 이름" notice: remember_items_and_projects: "이 사용자 지정 필드의 각 탭에서 항목과 프로젝트를 설정해야 합니다." hierarchy: subitems: - zero: no sub-items - one: 1 sub-item - other: "%{count} sub-items" + zero: 하위 항목 없음 + one: 하위 항목 1개 + other: "하위 항목 %{count}개" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > 프로젝트에 새 사용자 지정 필드를 추가하려면 먼저 해당 필드를 만들어야 합니다. 그래야 이 프로젝트에 해당 필드를 추가할 수 있습니다. is_enabled_globally: "는 세계적으로 사용 가능합니다." @@ -251,7 +253,7 @@ ko: is_required: "사용자 지정 필드를 필수로 표시합니다. 이렇게 하면 새 리소스를 생성하거나 기존 리소스를 업데이트할 때 이 필드를 반드시 입력해야 합니다." is_required_for_project: "이 특성을 활성화하려면 선택하고 모든 프로젝트에서 필수로 지정하세요. 개별 프로젝트에 대해 비활성화할 수는 없습니다." is_for_all: "모든 기존 프로젝트와 새 프로젝트에서 사용자 지정 필드를 사용 가능으로 표시합니다." - multi_select: "Allows the user to assign multiple values to this custom field." + multi_select: "사용자가 이 사용자 지정 필드에 여러 값을 할당할 수 있도록 허용합니다." searchable: "글로벌 검색 기능을 사용할 때 필드 값을 포함합니다." searchable_for_project: "프로젝트 목록에서 이 특성을 필터로 사용 가능하게 설정하려면 선택하세요." editable: "사용자가 필드를 편집할 수 있도록 허용합니다." @@ -265,20 +267,20 @@ ko: single: "또는" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "깊이" item: "항목" @@ -513,13 +515,13 @@ ko: 이 우선 순위 색상을 할당하거나 변경하려면 클릭하세요. 테이블의 작업 패키지를 강조 표시하는 데 사용할 수 있습니다. reactions: - action_title: "React" - add_reaction: "Add reaction" - react_with: "React with %{reaction}" - and_user: "and %{user}" + action_title: "반응" + add_reaction: "반응 추가" + react_with: "%{reaction}(으)로 반응" + and_user: "및 %{user}" and_others: - other: and %{count} others - reaction_by: "%{reaction} by" + other: 외 %{count}건 + reaction_by: "%{reaction} -" reportings: index: no_results_title_text: 상태 보고가 없습니다. @@ -530,14 +532,14 @@ ko: 이 상태 색상을 할당하거나 변경하려면 클릭하세요. 상태 버튼에 표시되고 테이블의 작업 패키지를 강조 표시하는 데 사용할 수 있습니다. status_default_text: |- - New work packages are by default set to this type. They cannot be read-only. + 새 작업 패키지는 기본적으로 이 유형으로 설정됩니다. 읽기 전용으로 설정할 수 없습니다. status_excluded_from_totals_text: |- 계층의 총 작업, 남은 작업 및 완료 %에서 이 상태의 작업 패키지를 제외하려면 이 옵션을 선택하세요. status_percent_complete_text: |- - In status-based progress calculation mode, the % Complete of a work - package is automatically set to this value when this status is selected. - Ignored in work-based mode. + 상태 기반 진행률 계산 모드에서, 이 상태를 선택하면 작업 + 패키지의 완료 %가 자동으로 이 값으로 설정됩니다. + 작업 기반 모드에서는 무시됩니다. status_readonly_html: | 이 상태를 읽기 전용으로 작업 패키지에 표시하려면 이 옵션을 선택합니다. 상태를 제외하고 특성은 변경할 수 없습니다.
@@ -623,6 +625,66 @@ ko: no_results_title_text: 사용 가능한 타입이 없습니다. version: no_results_title_text: 현재 사용가능한 버전이 없습니다. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: 초대 account: delete: "계정 삭제" @@ -901,12 +963,12 @@ ko: not_available: "- 시스템 구성으로 인해 사용 가능하지 않습니다." not_deletable: "- 삭제할 수 없습니다." not_current_user: "은(는) 현재 유효한 사용자가 아닙니다." - not_found: "not found." + not_found: "- 찾을 수 없습니다." not_a_date: "은(는) 유효한 날짜가 아닙니다." not_a_datetime: "은(는) 유효한 날짜가 아닙니다." not_a_number: "은(는) 숫자가 아닙니다." not_allowed: "- 사용 권한이 없어 유효하지 않습니다." - not_json: "is not a valid JSON object." + not_json: "- 유효한 JSON 개체가 아닙니다." not_an_integer: "은(는) 정수가 아닙니다." not_an_iso_date: "은(는) 유효한 날짜가 아닙니다. 필요한 형식: YYYY-MM-DD." not_same_project: "은(는) 동일한 프로젝트에 속하지 않습니다." @@ -1019,6 +1081,20 @@ ko: attributes: project_ids: blank: "프로젝트를 선택하세요." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1786,6 +1862,23 @@ ko: units: hours: 시간 days: 일 + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext 사용 가능(선택적)" @@ -2144,6 +2237,7 @@ ko: label_environment: "환경" label_estimates_and_progress: "견적 및 진행률" label_equals: "일치함" + label_equals_with_descendants: "is any with descendants" label_everywhere: "어디에 있든지" label_example: "예" label_experimental: "실험" @@ -2408,11 +2502,13 @@ ko: label_related_work_packages: "관련 작업 패키지" label_relates: "관련 항목" label_relates_to: "관련 항목" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "관계 삭제" label_relation_new: "새 관계" label_release_notes: "릴리스 노트" label_remaining_work: "남은 작업" - label_remove_column: "Remove column" + label_remove_column: "열 제거" label_remove_columns: "선택된 열 제거" label_renamed: "이름 변경됨" label_reply_plural: "회신" @@ -2453,10 +2549,10 @@ ko: label_show_completed_versions: "완료된 버전 표시" label_columns: "열" label_sort: "분류" - label_sort_ascending: "Sort ascending" + label_sort_ascending: "오름차순 정렬" label_sort_by: "%{value}(으)로 정렬" label_sorted_by: "%{value}(으)로 정렬됨" - label_sort_descending: "Sort descending" + label_sort_descending: "내림차순 정렬" label_sort_higher: "위로 이동" label_sort_highest: "맨 위로 이동" label_sort_lower: "아래로 이동" @@ -2805,9 +2901,9 @@ ko: notice_locking_conflict: "그 사이에 정보가 한 명 이상의 다른 사용자에 의해 업데이트되었습니다." notice_locking_conflict_additional_information: "%{users}의 업데이트입니다." notice_locking_conflict_reload_page: "페이지를 다시 로드하고, 변경 사항을 검토하고, 업데이트를 다시 적용하세요." - notice_locking_conflict_warning: "This page has been updated by someone else. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_danger: "Could not save your changes because of conflicting modifications. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_action_button: "Discard changes and reload" + notice_locking_conflict_warning: "이 페이지는 다른 사용자에 의해 업데이트되었습니다. 편집 사항을 손실하지 않으려면 로컬로 복사한 후 다시 로드하여 업데이트된 버전을 보세요." + notice_locking_conflict_danger: "수정 사항이 충돌하므로 변경 사항을 저장할 수 없습니다. 편집 사항이 손실되지 않게 하려면 로컬로 복사한 후 다시 로드하여 업데이트된 버전을 보세요." + notice_locking_conflict_action_button: "변경 사항 취소 및 다시 로드" notice_member_added: '%{name} 이(가) 프로젝트에 추가 됨' notice_members_added: '%{number}명의 사용자가 프로젝트에 추가되었습니다.' notice_member_removed: "프로젝트에서 %{user} 사용자가 제거됨." @@ -3274,7 +3370,7 @@ ko: authentication: single_sign_on: "Single Sign-On" omniauth_direct_login_hint_html: > - If this option is active, login requests will redirect to the configured omniauth provider. The login dropdown and sign-in page will be disabled.
Note: Unless you also disable password logins, with this option enabled, users can still log in internally by visiting the %{internal_path} login page. + 이 옵션이 활성화된 경우, 로그인 요청은 구성된 omniauth 공급자로 리디렉션됩니다. 로그인 드롭다운 및 로그인 페이지가 비활성화됩니다.
참고: 또한 암호 로그인을 비활성화하지 않는 경우에는 이 옵션이 활성화된 상태에서 사용자가 %{internal_path} 로그인 페이지를 방문하여 내부에서 계속 로그인할 수 있습니다. attachments: whitelist_text_html: > 업로드된 파일의 유효한 파일 확장명 및/또는 MIME 형식 목록을 정의합니다.
파일 확장명(예: %{ext_example}) 또는 MIME 형식(예: %{mime_example})을 입력합니다.
모든 파일 형식을 업로드할 수 있도록 허용하려면 비워 둡니다. 여러 값이 허용됩니다(각 값에 대해 한 줄). diff --git a/config/locales/crowdin/lt.seeders.yml b/config/locales/crowdin/lt.seeders.yml index a21872ddcdea..81b315dc4387 100644 --- a/config/locales/crowdin/lt.seeders.yml +++ b/config/locales/crowdin/lt.seeders.yml @@ -34,6 +34,17 @@ lt: name: Pilka (tamsi) item_13: name: Juoda + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentacija @@ -70,6 +81,21 @@ lt: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Žemas diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml index c4a3681c53ac..8002db4323ce 100644 --- a/config/locales/crowdin/lt.yml +++ b/config/locales/crowdin/lt.yml @@ -33,7 +33,7 @@ lt: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -236,6 +236,8 @@ lt: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Norėdami pridėti naujus pritaikytus laukelius prie projekto, pirmiausia reikia juos sukurti. Tik tada yra galimybė juos pridėti prie šio projekto. is_enabled_globally: "Yra įgalintas globaliai" @@ -262,20 +264,20 @@ lt: single: "arba" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -645,6 +647,66 @@ lt: no_results_title_text: Nėra prieinamų tipų. version: no_results_title_text: Šiuo metu nėra prieinamų versijų. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Pakvietimas account: delete: "Pašaslinti paskyrą" @@ -1041,6 +1103,20 @@ lt: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1892,6 +1968,23 @@ lt: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdf-į-tekstą pasiekiamas (pasirinktinai)" @@ -2250,6 +2343,7 @@ lt: label_environment: "Aplinka" label_estimates_and_progress: "Įvertinimai ir eiga" label_equals: "yra" + label_equals_with_descendants: "is any with descendants" label_everywhere: "visur" label_example: "Pavyzdys" label_experimental: "Eksperimentinis" @@ -2514,6 +2608,8 @@ lt: label_related_work_packages: "Susiję darbų paketai" label_relates: "susieta su" label_relates_to: "susieta su" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Pašalinti ryšį" label_relation_new: "Naujas ryšys" label_release_notes: "Išleidimo informacija" diff --git a/config/locales/crowdin/lv.seeders.yml b/config/locales/crowdin/lv.seeders.yml index d69df5f6dabe..357a7ce5aa54 100644 --- a/config/locales/crowdin/lv.seeders.yml +++ b/config/locales/crowdin/lv.seeders.yml @@ -34,6 +34,17 @@ lv: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentācija @@ -70,6 +81,21 @@ lv: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml index f0bc4949caa4..b83d690da202 100644 --- a/config/locales/crowdin/lv.yml +++ b/config/locales/crowdin/lv.yml @@ -33,7 +33,7 @@ lv: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ lv: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ lv: single: "vai" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -640,6 +642,66 @@ lv: no_results_title_text: Pašlaik nav pieejams neviens veids. version: no_results_title_text: Pašlaik nav pieejamu versiju. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Ielūgums account: delete: "Dzēst kontu" @@ -1036,6 +1098,20 @@ lv: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1859,6 +1935,23 @@ lv: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2217,6 +2310,7 @@ lv: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2481,6 +2575,8 @@ lv: label_related_work_packages: "Saistītie pieteikumi" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Informācija par laidienu" diff --git a/config/locales/crowdin/mn.seeders.yml b/config/locales/crowdin/mn.seeders.yml index e85b96d19d25..95abf55c43d1 100644 --- a/config/locales/crowdin/mn.seeders.yml +++ b/config/locales/crowdin/mn.seeders.yml @@ -34,6 +34,17 @@ mn: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ mn: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml index 579fc00925ea..2b79c35c23f1 100644 --- a/config/locales/crowdin/mn.yml +++ b/config/locales/crowdin/mn.yml @@ -33,7 +33,7 @@ mn: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ mn: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ mn: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ mn: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ mn: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ mn: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ mn: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ mn: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/ms.seeders.yml b/config/locales/crowdin/ms.seeders.yml index 0fa810b54311..8db31111b232 100644 --- a/config/locales/crowdin/ms.seeders.yml +++ b/config/locales/crowdin/ms.seeders.yml @@ -34,6 +34,17 @@ ms: name: Kelabu (tua) item_13: name: Hitam + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentasi @@ -70,6 +81,21 @@ ms: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Rendah diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index 6fd42aec6e8e..e0357345ae75 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -33,7 +33,7 @@ ms: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -238,6 +238,8 @@ ms: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Untuk menambah ruang tersuai ke projek, anda perlu menciptanya terlebih dahulu sebelum anda boleh menambahnya ke projek ini. is_enabled_globally: "Adalah diaktifkan secara global" @@ -264,20 +266,20 @@ ms: single: "atau" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -622,6 +624,66 @@ ms: no_results_title_text: Tiada jenis yang tersedia buat masa ini. version: no_results_title_text: Tiada versi yang tersedia buat masa ini. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Jemputan account: delete: "Padam akaun" @@ -1018,6 +1080,20 @@ ms: attributes: project_ids: blank: "Sila pilih projek." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1785,6 +1861,23 @@ ms: units: hours: j days: h + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "PdfkeTeks tersedia (pilihan)" @@ -2143,6 +2236,7 @@ ms: label_environment: "Persekitaran" label_estimates_and_progress: "Anggaran dan perkembangan" label_equals: "ialah" + label_equals_with_descendants: "is any with descendants" label_everywhere: "di mana-mana sahaja" label_example: "Contoh" label_experimental: "Eksperimental" @@ -2407,6 +2501,8 @@ ms: label_related_work_packages: "Pakej kerja yang berkaitan" label_relates: "berkait dengan" label_relates_to: "berkait dengan" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Hubungan terpadam" label_relation_new: "Hubungan baharu" label_release_notes: "Nota keluaran" diff --git a/config/locales/crowdin/ne.seeders.yml b/config/locales/crowdin/ne.seeders.yml index 08f81a62cc66..da3d524dd5a3 100644 --- a/config/locales/crowdin/ne.seeders.yml +++ b/config/locales/crowdin/ne.seeders.yml @@ -34,6 +34,17 @@ ne: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ ne: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml index 5f8eb0acf17e..f7b27f78b405 100644 --- a/config/locales/crowdin/ne.yml +++ b/config/locales/crowdin/ne.yml @@ -33,7 +33,7 @@ ne: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ ne: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ ne: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ ne: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "खाता मेटाउनुहोस्" @@ -1028,6 +1090,20 @@ ne: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ ne: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ ne: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "सबैतिर" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ ne: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/nl.seeders.yml b/config/locales/crowdin/nl.seeders.yml index 31cdb02e1bd1..02f53179daf8 100644 --- a/config/locales/crowdin/nl.seeders.yml +++ b/config/locales/crowdin/nl.seeders.yml @@ -34,6 +34,17 @@ nl: name: Grijs (donker) item_13: name: Zwart + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentatie @@ -70,6 +81,21 @@ nl: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Laag diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml index e39aa1f55718..2978b0cbc53d 100644 --- a/config/locales/crowdin/nl.yml +++ b/config/locales/crowdin/nl.yml @@ -27,31 +27,31 @@ nl: work_packages: activity_tab: no_results_title_text: No activity to display - no_results_description_text: "Choose \"Show everything\" to show all activity and comments" - label_activity_show_all: "Show everything" - label_activity_show_only_comments: "Show comments only" - label_activity_show_only_changes: "Show changes only" - label_sort_asc: "Newest at the bottom" - label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" - label_submit_comment: "Submit comment" - changed_on: "changed on" - created_on: "created this on" - changed: "changed" - created: "created" - commented: "commented" + no_results_description_text: "Kies \"Alles tonen\" om alle activiteiten en opmerkingen te tonen" + label_activity_show_all: "Alles tonen" + label_activity_show_only_comments: "Alleen opmerkingen tonen" + label_activity_show_only_changes: "Alleen wijzigingen weergeven" + label_sort_asc: "Nieuwste onderaan" + label_sort_desc: "Nieuwste bovenaan" + label_type_to_comment: "Add a comment. Type @ to notify people." + label_submit_comment: "Verstuur reactie" + changed_on: "gewijzigd op" + created_on: "creëerde dit op" + changed: "gewijzigd" + created: "aangemaakt" + commented: "gaf commentaar op" admin: plugins: - no_results_title_text: There are currently no plugins installed. - no_results_content_text: See our integrations and plugins page for more information. + no_results_title_text: Er zijn momenteel geen plugins geïnstalleerd. + no_results_content_text: Zie onze pagina met integraties en plugins voor meer informatie. custom_styles: color_theme: "Kleurenschema" color_theme_custom: "(Custom)" tab_interface: "Interface" - tab_branding: "Branding" - tab_pdf_export_styles: "PDF export styles" + tab_branding: "Huisstijl" + tab_pdf_export_styles: "PDF-exportstijlen" colors: - primary-button-color: "Primary button" + primary-button-color: "Primaire knop" accent-color: "Accent" header-bg-color: "Koptekst achtergrond" header-item-bg-hover-color: "Header background on hover" @@ -91,7 +91,7 @@ nl: contact: "Neem contact met ons op voor een demo" enterprise_info_html: "is een Enterprise add-on." upgrade_info: "Gelieve te upgraden naar een betaald abonnement om het te activeren en te beginnen met het gebruik ervan in uw team." - jemalloc_allocator: Jemalloc memory allocator + jemalloc_allocator: Jemalloc geheugentoewijzer journal_aggregation: explanation: text: "Individuele acties van een gebruiker (bijv. het bijwerken van een werkpakket twee keer) wordt samengevoegd tot een enkele actie als hun leeftijdverschil minder is dan de aangegeven timespat. Ze worden weergegeven als een enkele actie binnen de applicatie. Dit zal ook meldingen vertragen met dezelfde tijd die het aantal verstuurde e-mails vermindert en zal ook %{webhook_link} vertraging beïnvloeden." @@ -102,15 +102,15 @@ nl: is_inactive: momenteel niet getoond antivirus_scan: not_processed_yet_message: "Downloaden is geblokkeerd, omdat het bestand nog niet op virussen is gescand. Probeer het later nog eens." - quarantined_message: "A virus was detected in file '%{filename}'. It has been quarantined and is not available for download." + quarantined_message: "Er is een virus gedetecteerd in bestand '%{filename}'. Het is in quarantaine geplaatst en kan niet worden gedownload." deleted_message: "Er is een virus gedetecteerd in bestand '%{filename}'. Het bestand is verwijderd." deleted_by_admin: "Het in quarantaine geplaatste bestand '%{filename}' is verwijderd door een beheerder." - overridden_by_admin: "The quarantine for file '%{filename}' has been removed by %{user}. The file can now be acccessed." + overridden_by_admin: "De quarantaine voor bestand '%{filename}' is verwijderd door %{user}. Het bestand kan nu worden geopend." quarantined_attachments: container: "Container" - delete: "Delete the quarantined file" - title: "Quarantined attachments" - error_cannot_act_self: "Cannot perform actions on your own uploaded files." + delete: "Verwijder het quarantaine bestand" + title: "In quarantaine geplaatste bijlagen" + error_cannot_act_self: "Kan geen acties uitvoeren op uw eigen geüploade bestanden." attribute_help_texts: note_public: "Alle tekst en afbeeldingen die u toevoegt aan dit veld zijn openbaar zichtbaar voor alle ingelogde gebruikers!" text_overview: "In deze weergave kunt u aangepaste helpteksten voor kenmerken weergave. Wanneer gedefinieerd, worden deze teksten door te klikken op het help-pictogram naast het behoren kenmerk weergegeven." @@ -125,8 +125,8 @@ nl: ldap_auth_sources: ldap_error: "LDAP-fout: %{error_message}" ldap_auth_failed: "Kon niet authenticeren met LDAP-server." - sync_failed: "Failed to synchronize from LDAP: %{message}." - back_to_index: "Click here to go back to the list of connection." + sync_failed: "Synchronisatie met LDAP mislukt: %{message}." + back_to_index: "Klik hier om terug te gaan naar de connectielijst." technical_warning_html: | Dit LDAP-formulier vereist technische kennis van uw LDAP / Active Directory-configuratie.
@@ -215,16 +215,16 @@ nl: admin: custom_field_projects: is_for_all_blank_slate: - heading: For all projects - description: This custom field is enabled in all projects since the "For all projects" option is checked. It cannot be deactivated for individual projects. + heading: Voor alle projecten + description: Dit aangepaste veld is ingeschakeld in alle projecten omdat de optie "Voor alle projecten" is aangevinkt. Het kan niet worden uitgeschakeld voor individuele projecten. items: - actions: "Item actions" + actions: "Item acties" blankslate: root: - title: "Your list of items is empty" - description: "Start by adding items to the custom field of type hierarchy. Each item can be used to create a hierarchy bellow it. To navigate and create sub-items inside a hierarchy click on the created item." + title: "Uw lijst met items is leeg" + description: "Begin met het toevoegen van items aan het aangepaste veld van het type hiërarchie. Elk item kan gebruikt worden om een hiërarchie eronder te maken. Om te navigeren en subitems aan te maken binnen een hiërarchie klikt u op het aangemaakte item." item: - title: This item doesn't have any hierarchy level below + title: Dit item heeft geen onderstaand hiërarchie niveau description: Add items to this list to create sub-items inside another one placeholder: label: "Item label" @@ -236,6 +236,8 @@ nl: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Om de nieuwe aangepaste velden toevoegen aan een project moet u deze eerst maken voordat u ze aan dit project toevoegen kunt. is_enabled_globally: "Is ingeschakeld Op het hoofdniveau" @@ -262,20 +264,20 @@ nl: single: "of" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -629,6 +631,66 @@ nl: no_results_title_text: Er zijn momenteel geen types beschikbaar. version: no_results_title_text: Er zijn momenteel geen versies beschikbaar. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Uitnodiging account: delete: "Account Verwijderen" @@ -1025,6 +1087,20 @@ nl: attributes: project_ids: blank: "Selecteer een project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1820,6 +1896,23 @@ nl: units: hours: u days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext beschikbaar (optioneel)" @@ -2178,6 +2271,7 @@ nl: label_environment: "Omgeving" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "overal" label_example: "Voorbeeld" label_experimental: "Experimenteel" @@ -2442,6 +2536,8 @@ nl: label_related_work_packages: "Verwante werkpakketten" label_relates: "Gerelateerd aan" label_relates_to: "Gerelateerd aan" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Relatie verwijderen" label_relation_new: "Nieuwe relatie" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/no.seeders.yml b/config/locales/crowdin/no.seeders.yml index 0bdaa2a1ce16..f10feaa8a7e4 100644 --- a/config/locales/crowdin/no.seeders.yml +++ b/config/locales/crowdin/no.seeders.yml @@ -34,6 +34,17 @@ name: Grå (mørk) item_13: name: Sort + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentasjon @@ -70,6 +81,21 @@ item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Lav diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml index 0234793f571a..9349a3d50ae5 100644 --- a/config/locales/crowdin/no.yml +++ b/config/locales/crowdin/no.yml @@ -33,7 +33,7 @@ label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > For å legge til nye egendefinerte felt i et prosjekt må du først opprette dem før du kan legge dem til i dette prosjektet. is_enabled_globally: "Er aktivert globalt" @@ -265,20 +267,20 @@ single: "eller" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -631,6 +633,66 @@ no_results_title_text: Det finnes ingen tilgjengelige typer. version: no_results_title_text: Det finnes ingen versjoner tilgjengelige. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitasjon account: delete: "Slett konto" @@ -1027,6 +1089,20 @@ attributes: project_ids: blank: "Velg et prosjekt." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1822,6 +1898,23 @@ units: hours: t days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext tilgjengelig (valgfritt)" @@ -2180,6 +2273,7 @@ label_environment: "Miljø" label_estimates_and_progress: "Estimater og fremdrift" label_equals: "er" + label_equals_with_descendants: "is any with descendants" label_everywhere: "overalt" label_example: "Eksempel" label_experimental: "Eksperimentell" @@ -2444,6 +2538,8 @@ label_related_work_packages: "Relaterte arbeidspakker" label_relates: "relatert til" label_relates_to: "relatert til" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Slett relasjon" label_relation_new: "Ny relasjon" label_release_notes: "Utgivelsesnotater" diff --git a/config/locales/crowdin/pl.seeders.yml b/config/locales/crowdin/pl.seeders.yml index 6f9a9115b548..604e3aa630ef 100644 --- a/config/locales/crowdin/pl.seeders.yml +++ b/config/locales/crowdin/pl.seeders.yml @@ -34,6 +34,17 @@ pl: name: Szary (ciemny) item_13: name: Czarny + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentacja @@ -70,6 +81,21 @@ pl: item_1: name: Standardowa rola globalna standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Niski diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml index 97f06122e899..2dd618a52553 100644 --- a/config/locales/crowdin/pl.yml +++ b/config/locales/crowdin/pl.yml @@ -33,7 +33,7 @@ pl: label_activity_show_only_changes: "Pokaż tylko zmiany" label_sort_asc: "Najnowsze na końcu" label_sort_desc: "Najnowsze na początku" - label_type_to_comment: "Wpisz tutaj, aby skomentować" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Prześlij komentarz" changed_on: "zmieniono" created_on: "utworzono to" @@ -236,6 +236,8 @@ pl: zero: brak podelementów one: 1 podelement other: "Liczba podelementów: %{count}" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Aby dodać do projektu nowe pola niestandardowe, najpierw należy je utworzyć. is_enabled_globally: "Jest włączony globalnie" @@ -262,20 +264,20 @@ pl: single: "lub" dry_validation: errors: - integer?: "musi być liczbą całkowitą" - filled?: "musi być wypełnione" - greater_or_equal_zero: "musi mieć wartość większą lub równą 0" - not_found: "nie znaleziono" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "nie może być elementem głównym" - not_persisted: "musi być już istniejącym elementem" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "muszą być unikalne na tym samym poziomie hierarchii" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "muszą być unikalne na tym samym poziomie hierarchii" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "musi być potomkiem katalogu głównego hierarchii" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Głębokość" item: "Element" @@ -645,6 +647,66 @@ pl: no_results_title_text: Nie ma dostępnych typów. version: no_results_title_text: Obecnie żadne wersje nie są dostępne. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Zaproszenie account: delete: "Usuń konto" @@ -1041,6 +1103,20 @@ pl: attributes: project_ids: blank: "Wybierz projekt." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1892,6 +1968,23 @@ pl: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Dostępny konwerter Pdftotext (opcjonalny)" @@ -2250,6 +2343,7 @@ pl: label_environment: "Środowisko" label_estimates_and_progress: "Szacunki i postęp" label_equals: "jest" + label_equals_with_descendants: "is any with descendants" label_everywhere: "wszędzie" label_example: "Przykład" label_experimental: "Eksperymentalny" @@ -2514,6 +2608,8 @@ pl: label_related_work_packages: "Powiązanie pakiety robocze" label_relates: "Powiązane z" label_relates_to: "Powiązane z" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Usuń powiązanie" label_relation_new: "Nowe powiązanie" label_release_notes: "Dziennik zamian" diff --git a/config/locales/crowdin/pt-BR.seeders.yml b/config/locales/crowdin/pt-BR.seeders.yml index a6c34b79ba19..53dab48ca250 100644 --- a/config/locales/crowdin/pt-BR.seeders.yml +++ b/config/locales/crowdin/pt-BR.seeders.yml @@ -34,6 +34,17 @@ pt-BR: name: Cinza (escuro) item_13: name: Preto + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentação @@ -70,6 +81,21 @@ pt-BR: item_1: name: Função global padrão standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Baixa @@ -109,7 +135,7 @@ pt-BR: name: Painel básico lists: item_0: - name: Lista de Desejo + name: Lista de desejos item_1: name: Lista curta item_2: @@ -122,26 +148,26 @@ pt-BR: widgets: item_0: options: - name: Bem-vindo + name: Boas-vindas item_1: options: - name: Primeiros passos + name: Guia de introdução text: | - Estamos felizes por você ter se juntado a nós! Sugerimos que você experimente algumas coisas para começar a usar o OpenProject. + Estamos felizes que você tenha se juntado a nós! Aqui estão algumas sugestões para começar a usar o OpenProject. - Descubra os recursos mais importantes com nosso [Guided Tour] ({{opSetting:base_url}}/projects/demo-project/work_packages/?start_onboarding_tour=true). + Descubra os principais recursos com o nosso [Tour Guiado]({{opSetting:base_url}}/projects/demo-project/work_packages/?start_onboarding_tour=true). - _Tente as seguintes etapas:_ + Tente as seguintes etapas: - 1. *Convide novos membros para seu projeto*: → Vá para [Members]({{opSetting:base_url}}/projects/demo-project/members) na navegação do projeto. - 2. *Ver o trabalho em seu projeto*: → Vá para [Work packages]({{opSetting:base_url}}/projects/demo-project/work_packages) na navegação do projeto. - 3. *Crie um novo pacote de trabalho*: → Vá para [Work packages → Create]({{opSetting:base_url}}/projects/demo-project/work_packages/new). - 4. *Crie e atualize um plano de projeto*: → Vá para [Plano de projeto]({{opSetting:base_url}}/projects/demo-project/work_packages?query_id=##query.id:demo_project__query__project_plan) na navegação do projeto. - 5. *Ativar outros módulos*: → Vá para [Project settings → Modules]({{opSetting:base_url}}}/projects/demo-project/settings/modules). - 6. *Conclua suas tarefas no projeto*: → Vá para [Work packages → Tasks]({{opSetting:base_url}}/projects/demo-project/work_packages/details/##wp.id:set_date_and_location_of_conference/overview?query_id=##query.id:demo_project__query__tasks). + 1. *Convide novos membros para o seu projeto*: → Vá para [Membros]({{opSetting:base_url}}/projects/demo-project/members) na navegação do projeto. + 2. *Veja as tarefas do seu projeto*: → Vá para [Pacotes de trabalho]({{opSetting:base_url}}/projects/demo-project/work_packages) na navegação do projeto. + 3. *Crie um novo pacote de trabalho*: → Vá para [Pacotes de trabalho → Criar]({{opSetting:base_url}}/projects/demo-project/work_packages/new). + 4. *Crie e atualize o plano do projeto*: → Vá para [Plano de projeto]({{opSetting:base_url}}/projects/demo-project/work_packages?query_id=##query.id:demo_project__query__project_plan) na navegação do projeto. + 5. *Ative módulos adicionais*: → Vá para [Configurações do projeto → Módulos]({{opSetting:base_url}}/projects/demo-project/settings/modules). + 6. *Conclua suas tarefas no projeto*: → Vá para [Pacotes de trabalho → Tarefas]({{opSetting:base_url}}/projects/demo-project/work_packages/details/##wp.id:set_date_and_location_of_conference/overview?query_id=##query.id:demo_project__query__tasks). - Aqui você encontrará nossos [User Guides] (https://www.openproject.org/docs/user-guide/). - Entre em contato conosco se tiver alguma dúvida ou precisar de suporte. Entre em contato conosco: [support[at]openproject.com](mailto:support@openproject.com). + Aqui você encontra nossos Guias do usuário. + Se tiver alguma dúvida ou precisar de ajuda, entre em contato conosco: [support[at]openproject.com](mailto:support@openproject.com). item_5: options: name: Pacotes de trabalho @@ -170,7 +196,7 @@ pt-BR: item_2: subject: Conferência item_3: - subject: Acompanhamento das tarefas + subject: Tarefas de acompanhamento children: item_0: subject: Fazer upload de apresentações para o site @@ -200,76 +226,74 @@ pt-BR: Mais informações: [https://www.openproject.org/docs/user-guide/wiki/](https://www.openproject.org/docs/user-guide/wiki/) scrum-project: name: Projeto Scrum - status_explanation: Todas as tarefas estão dentro do cronograma. As pessoas envolvidas conhecem suas tarefas. O sistema está completamente configurado. - description: Este é um breve resumo dos objetivos deste projeto de demonstração do Scrum. + status_explanation: Todas as tarefas estão dentro do cronograma, e os envolvidos conhecem suas atribuições. O sistema está completamente configurado. + description: Este é um resumo dos objetivos deste projeto Scrum de demonstração. news: item_0: - title: Bem-vindo ao seu projeto de demonstração do Scrum + title: Boas-vindas ao seu projeto de demonstração do Scrum summary: | - Estamos felizes por você ter se juntado a nós. - Neste módulo, você pode comunicar as novidades do projeto aos membros da sua equipe. + Estamos felizes que você tenha se juntado a nós. + Neste módulo, você pode compartilhar as atualizações do projeto com os membros da sua equipe. versions: item_0: - name: Registro de erros e pendências + name: Backlog de Bugs item_1: - name: Erros e Pendências do Produto + name: Backlog de produtos item_2: name: Sprint 1 wiki: title: Sprint 1 content: | - ### A reunião de planejamento do Sprint - - _Por favor, documente aqui tópicos para a reunião de planejamento do Sprint_ + Reunião de Planejamento da Sprint - * Caixa de Tempo (8 h) - * Entrada: Backlog do Produto - * Saída: Rendimento da Sprint + _Documente aqui os tópicos para a reunião de planejamento da Sprint - * Divida em duas caixas de tempo adicionais de 4 h: + * Tempo limitado (8 h) + * Entrada: Backlog do produto + * Saída: Backlog da Sprint - * O proprietário do produto apresenta o [Backlog]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e as prioridades da equipe e explica a meta do Sprint, com o qual a equipa deve concordar. Juntos, eles priorizam os tópicos do Backlog do produto que a equipe cuidará no próximo sprint. A equipe se compromete com a entrega discutida. - * A equipe planeja autonomamente (sem o Proprietário do Produto) em detalhes e divide as tarefas dos requisitos discutidos para consolidar um [Backlog do Sprint]({{opSetting:base_url}}/projects/your-scrum-project/backlogs). + * Dividido em dois blocos de tempo adicionais de 4 h: + * O proprietário do produto apresenta o [Backlog do produto]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e as prioridades para a equipe, explicando o Objetivo da Sprint, ao qual a equipe deve concordar. Juntos, priorizam os tópicos do Backlog do produto que a equipe irá cuidar na próxima sprint. A equipe se compromete com a entrega discutida. + * A equipe planeja de forma autônoma (sem o proprietário do produto) em detalhes e divide as tarefas dos requisitos discutidos para consolidar um [Backlog da sprint]({{opSetting:base_url}}/projects/your-scrum-project/backlogs). - ### Reunião diária do Scrum + Reunião do Daily Scrum - _Por favor, documente aqui tópicos para a reunião do Scrum Diário_ + _Documente aqui os tópicos para a reunião diária de Scrum - * Reunião de status curta e diária da equipe. - * Tempo em caixa de tempo (máx. 15 min). - * Realização para discutir os seguintes tópicos do [Quadro de tarefas](##sprint:scrum_project__version__sprint_1). - * O que pretendo fazer até o próximo Scrone Diário? - * O que bloqueou o meu trabalho (pedimentos)? - * Moderados e notas do Scrum Master [Impedimentos](##sprint:scrum_project__version__sprint_1). - * O Proprietário do Produto pode participar a fim de se manter informado. + * Reunião curta de status diário da equipe. + * Tempo limitado (máx. 15 min). + * Reunião diária para discutir os seguintes tópicos do [Quadro de tarefas](##sprint:scrum_project__version__sprint_1). + *O que planejo fazer até o próximo Daily Scrum? + *O que bloqueou meu trabalho (Impedimentos)? + * O Scrum Master modera e anota os [Impedimentos da Sprint](##sprint:scrum_project__version__sprint_1). + * O proprietário do produto pode participar para se manter informado. - ### Reunião de Revisão do Sprint + Reunião de Revisão da Sprint - _Por favor, dê aqui tópicos para a reunião de Revisão do Sprint_ + _Documente aqui os tópicos para a reunião de revisão da Sprint - * Tempo embalado (4 h). - * O máximo de uma hora de preparação por pessoa. - * A equipe mostra ao proprietário do produto e às pessoas interessadas o que foi alcançado nesta sprint. - * Importante: sem dummies e nenhum PowerPoint! Funcionalidade de produto finalizado (Incrementos) deve ser demonstrada. - * Feedback do Proprietário do Produto, partes interessadas e outros é desejado e será incluído no trabalho futuro. - * Com base nas funcionalidades demonstradas, o proprietário do produto decide viver com esse incremento ou desenvolvê-lo ainda mais. Esta possibilidade permite uma ROI precoce. + * Tempo limitado (4 h). + * Máximo de uma hora de preparação por pessoa. + * A equipe mostra ao proprietário do produto e a outras partes interessadas o que foi alcançado nesta sprint. + * Importante: nada de protótipos e PowerPoint! Apenas a funcionalidade do produto finalizada (Incrementos) deve ser demonstrada. + * Feedback do proprietário do produto, partes interessadas e outros é desejado e será incluído no trabalho futuro. + * Com base nas funcionalidades demonstradas, o proprietário do produto decide se o incremento será colocado em produção ou se será desenvolvido mais. Esta possibilidade permite um ROI antecipado. + Retrospectiva da Sprint - ### Retrospectiva de Sprint + _Documente aqui os tópicos para a reunião de retrospectiva da Sprint - _Por favor, coloque aqui tópicos para a reunião Retrospectiva do Sprint_ - - * Caixa de Tempo (3 h). - * Após o Sprint Review, será moderado pelo Scrum Master. - * A equipe discute o sprint: o que correu bem, o que precisa de ser melhorado para ser mais produtivo para a próxima corrida, ou até mesmo mais divertido. + * Tempo limitado (3 h). + * Após a Revisão da Sprint, será moderada pelo Scrum Master. + * A equipe discute a sprint: o que deu certo, o que precisa ser melhorado para ser mais produtivo na próxima sprint ou até mesmo para se divertir mais. item_3: name: Sprint 2 categories: item_0: Categoria 1 (a ser alterada nas configurações do projeto) queries: item_0: - name: 'Plano do Projeto:' + name: Plano do projeto item_1: name: Backlog do produto item_2: @@ -278,12 +302,12 @@ pt-BR: name: Tarefas boards: kanban: - name: Painel Kanban + name: Quadro Kanban basic: name: Quadro de tarefas lists: item_0: - name: Lista de Desejo + name: Lista de desejos item_1: name: Lista curta item_2: @@ -294,7 +318,7 @@ pt-BR: widgets: item_0: options: - name: Bem-vindo + name: Boas-vindas item_1: options: name: Guia de introdução @@ -304,11 +328,11 @@ pt-BR: _Tente as seguintes etapas:_ 1. *Convide novos membros para o seu projeto*: → Vá para [Membros]({{opSetting:base_url}}/projects/your-scrum-project/members) na navegação do projeto. - 2. *Veja seu backlog de Produto e backlogs do Sprint*: → Vá para [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) na navegação do projeto. + 2. *Veja seu backlog de Produto e backlogs da Sprint*: → Vá para [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) na navegação do projeto. 3. *Veja seu quadro de tarefas*: → Vá para [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) → Clique na seta para a direita em Sprint → Selecione [Quadro de tarefas](##sprint:scrum_project__version__sprint_1). 4. *Crie um novo pacote de trabalho*: → Vá para [Pacotes de trabalho → Criar]({{opSetting:base_url}}/projects/your-scrum-project/work_packages/new). 5. *Crie e atualize um plano de projeto*: → Vá para [Plano de projeto](##query:scrum_project__query__project_plan) na navegação do projeto. - 6. *Crie um wiki de Sprint*: → Vá para [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e abra o wiki de sprint no menu suspenso direito em um sprint. Você pode editar o [modelo wiki]({{opSetting:base_url}}/projects/your-scrum-project/wiki/) com base em suas necessidades. + 6. *Crie um wiki da Sprint*: → Vá para [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e abra o wiki da sprint no menu suspenso direito em uma sprint. Você pode editar o [modelo wiki]({{opSetting:base_url}}/projects/your-scrum-project/wiki/) com base em suas necessidades. 7. *Ative mais módulos*: → Vá para [Configurações do projeto → Módulos]({{opSetting:base_url}}/projects/your-scrum-project/settings/modules). Aqui você encontrará nossos [Guias do Usuário] (https://www.openproject.org/docs/user-guide/). @@ -319,7 +343,7 @@ pt-BR: name: Pacotes de trabalho item_6: options: - name: 'Plano do Projeto:' + name: Plano do projeto work_packages: item_0: subject: Nova tela de login @@ -372,18 +396,18 @@ pt-BR: item_16: subject: Versão v2.0 wiki: | - ### Reunião de planejamento do sprint + ### Reunião de planejamento da sprint - _Documente aqui os tópicos para a reunião de planejamento do Sprint_ + _Documente aqui os tópicos para a reunião de planejamento da Sprint_ * Intervalo de tempo fixo (8 h) * Entrada: Backlog de produto - * Saída: Backlog de sprint + * Saída: Backlog da sprint * Dividido em dois intervalos de tempo fixos adicionais de 4 h: - * O proprietário do produto apresenta o [Backlog do produto]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e as prioridades para a equipe e explica o Sprint objetivo, com o qual a equipe deve concordar. Juntos, eles priorizam os tópicos do Backlog de produto que a equipe cuidará no próximo sprint. A equipe se compromete com a entrega discutida. - * A equipe planeja de forma autônoma (sem o proprietário do produto) em detalhes e divide as tarefas dos requisitos discutidos para consolidar um [Backlog de sprint]({{opSetting:base_url}}/projects/your-scrum-project/backlogs). + * O proprietário do produto apresenta o [Backlog do produto]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) e as prioridades para a equipe e explica a Sprint objetivo, com o qual a equipe deve concordar. Juntos, eles priorizam os tópicos do Backlog de produto que a equipe cuidará no próxima sprint. A equipe se compromete com a entrega discutida. + * A equipe planeja de forma autônoma (sem o proprietário do produto) em detalhes e divide as tarefas dos requisitos discutidos para consolidar um [Backlog da sprint]({{opSetting:base_url}}/projects/your-scrum-project/backlogs). ### Reunião diária do Scrum @@ -392,31 +416,31 @@ pt-BR: * Reunião curta e diária de status da equipe. * Intervalo de tempo fixo (máx. 15 min). - * Reunião stand-up para discutir os seguintes tópicos do quadro de tarefas. + * Reunião diária para discutir os seguintes tópicos do quadro de tarefas. * O que pretendo fazer até o próximo Scrum diário? * O que tem bloqueado meu trabalho (impedimentos)? - * O Scrum Master modera e anota os Impedimentos do Sprint. + * O Scrum Master modera e anota os Impedimentos da Sprint. * O proprietário do produto pode participar para se manter informado. - ### Reunião de revisão do Sprint + ### Reunião de revisão da Sprint - _Documente aqui os tópicos para a reunião de Revisão do Sprint_ + _Documente aqui os tópicos para a reunião de Revisão da Sprint_ * Intervalo de tempo fixo (4h). * Máximo de uma hora de preparo por pessoa. - * A equipe mostra ao proprietário do produto e outras pessoas interessadas o que foi alcançado neste sprint. + * A equipe mostra ao proprietário do produto e outras pessoas interessadas o que foi alcançado nesta sprint. * Importante: sem manequins e sem PowerPoint! A funcionalidade do produto recém-acabado (incrementos) deve ser demonstrada. * Comentários do proprietário do produto, partes interessadas e outros são desejados e serão incluídos em trabalhos futuros. * Com base nas funcionalidades demonstradas, o proprietário do produto decide ativar esse incremento ou desenvolvê-lo ainda mais. Esta possibilidade permite um ROI antecipado. - ### Retrospectiva do Sprint + ### Retrospectiva da Sprint - _Documente aqui os tópicos para a reunião de Retrospectiva do Sprint_ + _Documente aqui os tópicos para a reunião de Retrospectiva da Sprint_ * Intervalo de tempo fixo (3h). - * Após a revisão do Sprint, será moderado pelo Scrum Master. - * A equipe discute o sprint: o que deu certo, o que precisa ser melhorado para ser mais produtivo para o próximo sprint ou até mesmo se divertir mais. + * Após a revisão da Sprint, será moderado pelo Scrum Master. + * A equipe discute a sprint: o que deu certo, o que precisa ser melhorado para ser mais produtivo para a próxima sprint ou até mesmo se divertir mais. statuses: item_0: name: Novo @@ -439,7 +463,7 @@ pt-BR: item_9: name: Testado item_10: - name: Falha no teste + name: O teste falhou item_11: name: Fechado item_12: @@ -467,15 +491,15 @@ pt-BR: item_2: name: Fase item_3: - name: Funcionalidade + name: Recurso item_4: name: Épico item_5: - name: História de usuário + name: Histórico de usuário item_6: name: Bug welcome: - title: Bem-vindo ao OpenProject! + title: Boas-vindas ao OpenProject! text: | O OpenProject é o principal software de gestão de projetos de código aberto. Ele dá suporte à gestão de projetos clássica, ágil e híbrida e dá a você o controlo total sobre os seus dados. diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml index ac59c9974729..af4d02fe073d 100644 --- a/config/locales/crowdin/pt-BR.yml +++ b/config/locales/crowdin/pt-BR.yml @@ -33,7 +33,7 @@ pt-BR: label_activity_show_only_changes: "Exibir apenas alterações" label_sort_asc: "Mais recentes embaixo" label_sort_desc: "Mais recentes em cima" - label_type_to_comment: "Digite aqui para comentar" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Enviar comentário" changed_on: "alterado em" created_on: "criou em" @@ -238,6 +238,8 @@ pt-BR: zero: sem subitens one: 1 subitem other: "%{count} subitens" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Para adicionar campos personalizados a um projeto é necessário criá-los primeiro para depois adicioná-los a este projeto. is_enabled_globally: "Está habilitado globalmente" @@ -264,20 +266,20 @@ pt-BR: single: "ou" dry_validation: errors: - integer?: "deve ser um número inteiro" - filled?: "deve ser preenchido" - greater_or_equal_zero: "deve ser maior ou igual a 0" - not_found: "não encontrado" + int?: "deve ser um número inteiro." + filled?: "deve ser preenchido." + greater_or_equal_zero: "deve ser maior ou igual a 0." + not_found: "não encontrado." rules: item: - root_item: "não pode ser um item raiz" - not_persisted: "deve ser um item já existente" + root_item: "não pode ser um item raiz." + not_persisted: "deve ser um item já existente." label: - not_unique: "deve ser único dentro do mesmo nível hierárquico" + not_unique: "deve ser único dentro do mesmo nível hierárquico." short: - not_unique: "deve ser único dentro do mesmo nível hierárquico" + not_unique: "deve ser único dentro do mesmo nível hierárquico." parent: - not_descendant: "deve ser um descendente da raiz da hierarquia" + not_descendant: "deve ser um descendente da raiz da hierarquia." rules: depth: "Profundidade" item: "Item" @@ -629,6 +631,66 @@ pt-BR: no_results_title_text: Atualmente, não há tipos disponíveis. version: no_results_title_text: Atualmente, não há versões disponíveis. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Convite account: delete: "Excluir conta" @@ -1025,6 +1087,20 @@ pt-BR: attributes: project_ids: blank: "Selecione um projeto." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1820,6 +1896,23 @@ pt-BR: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponível (opcional)" @@ -2178,6 +2271,7 @@ pt-BR: label_environment: "Ambiente" label_estimates_and_progress: "Estimativas e progresso" label_equals: "é" + label_equals_with_descendants: "is any with descendants" label_everywhere: "em todos os lugares" label_example: "Exemplo" label_experimental: "Experimental" @@ -2442,6 +2536,8 @@ pt-BR: label_related_work_packages: "Pacotes de trabalho relacionados" label_relates: "relacionado a" label_relates_to: "relacionado a" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Excluir relação" label_relation_new: "Nova relação" label_release_notes: "Notas da versão" diff --git a/config/locales/crowdin/pt-PT.seeders.yml b/config/locales/crowdin/pt-PT.seeders.yml index 42f975a3ebe1..9763deec66c7 100644 --- a/config/locales/crowdin/pt-PT.seeders.yml +++ b/config/locales/crowdin/pt-PT.seeders.yml @@ -34,6 +34,17 @@ pt-PT: name: Cinza (escuro) item_13: name: Preto + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentação @@ -70,6 +81,21 @@ pt-PT: item_1: name: Função global padrão standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Baixo diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml index fbe821222d9a..446b9a79fc98 100644 --- a/config/locales/crowdin/pt-PT.yml +++ b/config/locales/crowdin/pt-PT.yml @@ -33,7 +33,7 @@ pt-PT: label_activity_show_only_changes: "Mostrar apenas alterações" label_sort_asc: "Mais recente em baixo" label_sort_desc: "Mais recente no topo" - label_type_to_comment: "Escreva aqui para comentar" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submeter comentário" changed_on: "alterou a" created_on: "criou isto a" @@ -237,6 +237,8 @@ pt-PT: zero: sem sub-itens one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Para adicionar novos campos personalizados a um projeto, primeiro precisa de criá-los para depois adicioná-los a este projeto. is_enabled_globally: "Ativado a nível global" @@ -263,20 +265,20 @@ pt-PT: single: "ou" dry_validation: errors: - integer?: "tem de ser um número inteiro" - filled?: "tem de ser preenchido" - greater_or_equal_zero: "tem de ser maior ou igual a 0" - not_found: "não encontrado" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "não pode ser um item de raiz" - not_persisted: "tem de ser um item já existente" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "tem de ser único dentro do mesmo nível hierárquico" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "tem de ser único dentro do mesmo nível hierárquico" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "tem de ser um descendente da raiz da hierarquia" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Profundidade" item: "Item" @@ -629,6 +631,66 @@ pt-PT: no_results_title_text: Atualmente, não existem tipos disponíveis. version: no_results_title_text: Atualmente, não existem versões disponíveis. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Convite account: delete: "Eliminar conta" @@ -1025,6 +1087,20 @@ pt-PT: attributes: project_ids: blank: "Selecione um projeto." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1820,6 +1896,23 @@ pt-PT: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponível (opcional)" @@ -2178,6 +2271,7 @@ pt-PT: label_environment: "Ambiente" label_estimates_and_progress: "Estimativas e progresso" label_equals: "é" + label_equals_with_descendants: "is any with descendants" label_everywhere: "em todo o lado" label_example: "Exemplo" label_experimental: "Experimental" @@ -2442,6 +2536,8 @@ pt-PT: label_related_work_packages: "Tarefas relacionados" label_relates: "relacionado com" label_relates_to: "relacionado com" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Eliminar relação" label_relation_new: "Nova relação" label_release_notes: "Notas de lançamento" diff --git a/config/locales/crowdin/ro.seeders.yml b/config/locales/crowdin/ro.seeders.yml index afcfae35165e..202b79f69592 100644 --- a/config/locales/crowdin/ro.seeders.yml +++ b/config/locales/crowdin/ro.seeders.yml @@ -34,6 +34,17 @@ ro: name: Gri închis item_13: name: Negru + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentație @@ -70,6 +81,21 @@ ro: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Scăzută diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml index a604f5874ee0..a5e1f0222df1 100644 --- a/config/locales/crowdin/ro.yml +++ b/config/locales/crowdin/ro.yml @@ -26,17 +26,17 @@ ro: no_results_title_text: Nu s-a înregistrat nicio activitate pentru acest proiect în această perioadă de timp. work_packages: activity_tab: - no_results_title_text: No activity to display - no_results_description_text: "Choose \"Show everything\" to show all activity and comments" - label_activity_show_all: "Show everything" - label_activity_show_only_comments: "Show comments only" - label_activity_show_only_changes: "Show changes only" - label_sort_asc: "Newest at the bottom" - label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + no_results_title_text: Nicio activitate de afișat + no_results_description_text: "Alege \"Arată tot\" pentru a afișa toată activitatea și comentariile" + label_activity_show_all: "Afișează tot" + label_activity_show_only_comments: "Arată doar comentariile" + label_activity_show_only_changes: "Arată doar modificările" + label_sort_asc: "Cele mai noi jos" + label_sort_desc: "Cele mai noi sus" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" - created_on: "created this on" + created_on: "a creat-o pe" changed: "changed" created: "created" commented: "commented" @@ -88,7 +88,7 @@ ro: get_quote: "Obțineți o ofertă" buttons: upgrade: "Actualizează acum" - contact: "Contactați-ne pentru o demonstrație" + contact: "Contactați-ne pentru un demo" enterprise_info_html: "is an Enterprise add-on." upgrade_info: "Vă rugăm să treceți la un plan plătit pentru a-l activa și a începe să îl utilizați în echipa dumneavoastră." jemalloc_allocator: Jemalloc memory allocator @@ -101,7 +101,7 @@ ro: is_active: afișat acum is_inactive: neafișat acum antivirus_scan: - not_processed_yet_message: "Downloading is blocked, as file was not scanned for viruses yet. Please try again later." + not_processed_yet_message: "Descărcarea este blocată deoarece fișierul nu a fost încă scanat pentru virusuri. Te rog să încerci din nou mai târziu." quarantined_message: "A virus was detected in file '%{filename}'. It has been quarantined and is not available for download." deleted_message: "A virus was detected in file '%{filename}'. The file has been deleted." deleted_by_admin: "The quarantined file '%{filename}' has been deleted by an administrator." @@ -239,6 +239,8 @@ ro: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Dacă vrei să adaugi noi câmpuri personalizate în cadrul unui proiect va trebui, mai întâi, să le creezi. is_enabled_globally: "Este activat/ă la nivel global" @@ -265,20 +267,20 @@ ro: single: "sau" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -321,12 +323,12 @@ ro: completed_text: "Cererea de ștergere a proiectului \"%{name}\" a fost finalizată." completed_text_children: "Additionally, the following subprojects have been deleted:" index: - open_as_gantt: "Deschideți ca vizualizare Gantt" + open_as_gantt: "Deschide ca vizualizare Gantt" no_results_title_text: În acest moment nu există proiecte no_results_content_text: Creează proiect nou search: label: Project name filter - placeholder: Search by project name + placeholder: Caută după numele proiectului lists: active: "Proiecte active" my: "Proiectele mele" @@ -374,7 +376,7 @@ ro: no_results_title_text: În acest moment nu există versiuni pentru acest proiect. no_results_content_text: Creează versiune nouă storage: - no_results_title_text: Acest proiect nu consumă spațiu suplimentar pe disc înregistrat. + no_results_title_text: Acest proiect nu consumă spațiu suplimentar pe disc. lists: create: success: "The modified list has been saved as a new list" @@ -516,7 +518,7 @@ ro: irreversible: "Această acțiune este ireversibilă" confirmation: "Introduceți numele de utilizator de tip placeholder %{name} pentru a confirma ștergerea." upsale: - title: Utilizatori de tip Placeholder + title: Utilizatori Placeholder description: > Utilizatorii de tip substituție sunt o modalitate de a atribui pachete de lucru utilizatorilor care nu fac parte din proiectul tău. Acesta poate fi utilă într-o serie de scenarii; de exemplu, dacă trebuie să urmărești sarcinile pentru o resursă care nu este încă numită sau disponibilă, sau dacă nu vrei să acorzi acestei persoane acces la OpenProject dar totuși vrei să urmărești sarcinile care le-au fost atribuite. prioritiies: @@ -605,11 +607,11 @@ ro: few: "%{count} descendenți ai pachetului de lucru" other: "%{count} pachete de lucru descendente" bulk: - copy_failed: "Pachetele de lucru nu au putut fi copiate." - move_failed: "Pachetele de lucru nu au putut fi mutate." + copy_failed: "Pachetele de lucru nu pot fi copiate." + move_failed: "Pachetele de lucru nu pot fi mutate." could_not_be_saved: "Următoarele pachete de lucru nu au putut fi salvate:" - none_could_be_saved: "Niciunul dintre pachetele de lucru %{total} nu a putut fi actualizat." - x_out_of_y_could_be_saved: "%{failing} din %{total} pachete de lucru nu au putut fi actualizate în timp ce %{success} ar putea fi actualizat." + none_could_be_saved: "Niciunul dintre pachetele de lucru %{total} nu poate fi actualizat." + x_out_of_y_could_be_saved: "%{failing} din %{total} pachete de lucru nu pot fi actualizate în timp ce %{success} poate fi actualizat." selected_because_descendants: "While %{selected} work packages were selected, in total %{total} work packages are affected which includes descendants." descendant: "descendent de selectat" move: @@ -640,11 +642,71 @@ ro: no_results_title_text: În acest moment nu există tipuri disponibile. version: no_results_title_text: În acest moment nu există versiuni disponibile. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitație account: delete: "Ştergere cont" delete_confirmation: "Sunteţi sigur că doriţi să ştergeţi contul?" - deletion_pending: "Contul a fost blocat și a fost programat pentru ștergere. Rețineți că acest proces are loc în fundal. Poate dura câteva momente până când utilizatorul este complet șters." + deletion_pending: "Contul a fost blocat și a fost programat pentru ștergere. Reține că acest proces are loc în fundal. Poate dura câteva momente până când utilizatorul este complet șters." deletion_info: data_consequences: other: 'Vor fi șterse cât mai multe din datele create de utilizator (e.g. email, preferințe, pachete de lucru, contribuții wiki). De reținut, totuși, că date precum pachete de lucru și contribuții wiki nu pot fi șterse fără a afecta activitatea altor utilizatori. Prin urmare, astfel de date sunt realocate la un cont numit "Utilizator șters". Deoarece datele fiecărui cont șters sunt realocate acestui cont, nu va mai fi posibil să se facă distincția între datele create de utilizator și datele altui cont șters.' @@ -931,7 +993,7 @@ ro: regex_match_failed: "does not match the regular expression %{expression}." regex_invalid: "nu a putut fi validată cu expresia regulată asociată." smaller_than_or_equal_to_max_length: "trebuie să fie mai mic sau egal cu lungimea maximă." - taken: "a fost luat deja." + taken: "este deja utilizat" too_long: "este prea lung (maximul admis este de %{count} caractere)." too_short: "este prea scurt (minimum admis este de %{count} caractere)." type_mismatch: "nu este de tipul '%{type}'" @@ -1026,7 +1088,7 @@ ro: foreign_wps_reference_version: "Pachetele de lucru din proiectele care nu sunt descendente fac trimitere la versiuni ale proiectului sau la descendenți ai acestuia." attributes: base: - archive_permission_missing_on_subprojects: "Nu aveţi permisiunile necesare pentru a arhiva toate sub-proiectele. Vă rugăm să contactaţi un administrator." + archive_permission_missing_on_subprojects: "Nu ai permisiunile necesare pentru a arhiva toate sub-proiectele. Te rog să contactezi un administrator." types: in_use_by_work_packages: "încă în uz în pachetele de lucru: %{types}" enabled_modules: @@ -1036,6 +1098,20 @@ ro: attributes: project_ids: blank: "Selectează un proiect." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1278,9 +1354,9 @@ ro: wiki_page: "Pagină wiki" errors: header_invalid_fields: - one: "There was a problem with the following field:" + one: "Este o problemă cu următorul câmp:" few: "Există probleme cu următoarele câmpuri:" - other: "Există probleme cu următoarele câmpuri:" + other: "Există o probleme cu următoarele câmpuri:" header_additional_invalid_fields: one: "Additionally, there was a problem with the following field:" few: "Additionally, there were problems with the following fields:" @@ -1788,7 +1864,7 @@ ro: xls: label: "XLS" columns: - input_label_report: "Add columns to attribute table" + input_label_report: "Adaugă coloane la tabelul de atribute" input_caption_report: "By default all attributes added as columns in the work package list are selected. Long text fields are not available in the attribute table, but can be displayed below it." input_caption_table: "By default all attributes added as columns in the work package list are selected. Long text fields are not available in table based exports." pdf: @@ -1859,6 +1935,23 @@ ro: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext disponibil (opțional)" @@ -2065,7 +2158,7 @@ ro: label_ical_access_key_generation_hint: "Automatically generated when subscribing to a calendar." label_ical_access_key_latest: "latest" label_ical_access_key_revoke: "Revocă" - label_add_column: "Add column" + label_add_column: "Adaugă coloană" label_applied_status: "Stare aplicată" label_archive_project: "Proiect de arhivă" label_ascending: "Crescător" @@ -2217,6 +2310,7 @@ ro: label_environment: "Mediu" label_estimates_and_progress: "Estimări și progrese" label_equals: "este" + label_equals_with_descendants: "is any with descendants" label_everywhere: "Peste tot" label_example: "Exemplu" label_experimental: "Experimental" @@ -2361,10 +2455,10 @@ ro: label_months_from: "luni de la" label_more: "Mai mult" label_more_than_ago: "acum mai mult de zile" - label_move_column_left: "Move column left" - label_move_column_right: "Move column right" + label_move_column_left: "Mută coloana la stânga" + label_move_column_right: "Mută coloana la dreapta" label_move_work_package: "Mutare pachet de lucru" - label_my_account: "Account settings" + label_my_account: "Setări cont" label_my_activity: "Activitatea mea" label_my_account_data: "Datele din contul meu" label_my_avatar: "My avatar" @@ -2464,7 +2558,7 @@ ro: label_project_attributes_settings: "Project attributes settings" label_project_storage_plural: "File Storages" label_project_storage_project_folder: "File Storages: Project folders" - label_projects_disk_usage_information: "%{count} projects using %{used_disk_space} disk space" + label_projects_disk_usage_information: "%{count} proiecte care utilizează %{used_disk_space} spațiu pe disc" label_project_view_all: "Vizualizează toate proiectele" label_project_show_details: "Arată detaliile proietului" label_project_hide_details: "Ascunde detaliile proiectului" @@ -2481,12 +2575,14 @@ ro: label_related_work_packages: "Pachete de lucru asociate" label_relates: "asociat cu" label_relates_to: "asociat cu" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Ștergere relație" label_relation_new: "Relație nouă" label_release_notes: "Note privind lansarea noii versiuni" label_remaining_work: "Muncă rămasă" - label_remove_column: "Remove column" - label_remove_columns: "Eliminare coloane selectate" + label_remove_column: "Elimină coloana" + label_remove_columns: "Elimină coloane selectate" label_renamed: "redenumit" label_reply_plural: "Răspunsuri" label_report: "Raportare" @@ -2526,10 +2622,10 @@ ro: label_show_completed_versions: "Afișare versiuni complete" label_columns: "Coloane" label_sort: "Sortare" - label_sort_ascending: "Sort ascending" + label_sort_ascending: "Ordonează ascendent" label_sort_by: "Sortare după %{value}" label_sorted_by: "sortate după %{value}" - label_sort_descending: "Sort descending" + label_sort_descending: "Ordonează descendent" label_sort_higher: "Mută în sus" label_sort_highest: "Mută sus" label_sort_lower: "Mută în jos" @@ -2539,8 +2635,8 @@ ro: label_start_to_start: "început la început" label_statistics: "Statistici" label_status: "Stare" - label_storage_free_space: "Spațiu pe disc rămas" - label_storage_used_space: "Spațiu pe disc folosit" + label_storage_free_space: "Spațiu disc rămas" + label_storage_used_space: "Spațiu disc folosit" label_storage_group: "Sistem de fișiere pentru stocare %{identifier}" label_storage_for: "Conține stocarea pentru" label_string: "Text" @@ -2553,7 +2649,7 @@ ro: label_system_storage: "Informații privind stocarea" label_table_of_contents: "Cuprins" label_tag: "Etichetă" - label_team_planner: "Team Planner" + label_team_planner: "Planificare echipă" label_text: "Text lung" label_this_month: "luna curentă" label_this_week: "săptămâna curentă" @@ -2793,10 +2889,10 @@ ro: mail_body_register_header_title: "E-mail de invitație pentru membrii proiectului" mail_body_register_user: "Dragă %{name}," mail_body_register_links_html: | - Vă rugăm să nu ezitați să navigați pe canalul nostru de youtube (%{youtube_link}) unde oferim un webinar (%{webinar_link}) + Nu ezita să navighezi pe canalul nostru de youtube (%{youtube_link}) unde oferim un webinar (%{webinar_link}) și videoclipuri cu “Începe” (%{get_started_link}) pentru a face primii pași în OpenProject cât mai ușor posibil.
- Dacă aveți orice întrebări suplimentare, consultați documentația noastră (%{documentation_link}) sau contactați administratorul. + Dacă ai orice întrebări suplimentare, consultă documentația noastră (%{documentation_link}) sau contactează administratorul. mail_body_register_closing: "Echipa dumneavoastră OpenProject" mail_body_register_ending: "Rămâneți conectați! Vă salutăm cu drag," mail_body_reminder: "%{count} pachete de lucru care vă sunt atribuite au scadență în următoarele %{days} zile:" @@ -2806,7 +2902,7 @@ ro: mail_subject_account_activation_request: "cererea de activare a contului %{value}" mail_subject_backup_ready: "Backup-ul tău este gata" mail_subject_backup_token_reset: "Resetarea token-ului de backup" - mail_subject_incoming_email_error: "Un e-mail pe care l-ați trimis la OpenProject nu a putut fi procesat" + mail_subject_incoming_email_error: "Un e-mail pe care l-ai trimis la OpenProject nu a putut fi procesat" mail_subject_lost_password: "Parola dumneavoastră pentru %{value}" mail_subject_register: "Activarea contului dumneavoastră %{value}" mail_subject_wiki_content_added: "Pagina de wiki '%{id}' a fost adăugată" @@ -2909,7 +3005,7 @@ ro: notice_automatic_set_of_standard_type: "Setare automată a tipului standard." notice_logged_out: "Ați fost deconectat." notice_wont_delete_auth_source: The LDAP connection cannot be deleted as long as there are still users using it. - notice_project_cannot_update_custom_fields: "Nu puteți actualiza câmpurile particularizate disponibile ale proiectului. Proiectul este invalid: %{errors}" + notice_project_cannot_update_custom_fields: "Nu poți actualiza câmpurile particularizate disponibile ale proiectului. Proiectul este invalid: %{errors}" notice_attachment_migration_wiki_page: > Această pagină a fost generată automat în timpul actualizării OpenProject. Aceasta conține toate atașamentele asociate anterior cu %{container_type} "%{container_name}". #Default format for numbers @@ -2937,7 +3033,7 @@ ro: heading_getting_started: "Urmărește prezentarea generală" text_getting_started_description: "Obțineți o imagine de ansamblu rapidă a gestionării proiectelor și a colaborării în echipă cu OpenProject. Puteți reporni acest videoclip din meniul de ajutor." welcome: "Bun venit la %{app_title}" - select_language: "Vă rugăm să selectați limba dvs" + select_language: "Te rog selectează limba" permission_add_work_package_notes: "Adăugare note" permission_add_work_packages: "Adăugare pachete de lucru" permission_add_messages: "Publicare mesaje" @@ -3167,7 +3263,7 @@ ro: managed: "Creează repo nou în OpenProject" storage: not_available: "Consumul de spațiu de stocare nu este disponibil pentru acest repo." - update_timeout: "Păstraţi informaţia referitoare la spaţiul de stocare necesar pentru un repo timp de N minute. \nDeoarece măsurarea spațiului necesar pentru un repo poate fi costisitoare, creșteți această valoare pentru a reduce impactul în performanță." + update_timeout: "Păstrează ultimele informații privind spațiul necesar pe disc pentru un depozit timp de N minute.\nDeoarece numărarea spațiului necesar pe disc al unui depozit poate fi costisitoare, crește această valoare pentru a reduce impactul asupra performanței." oauth_application_details: "Valoarea secretă a clientului nu va mai fi accesibilă după ce închideți această fereastră. Vă rugăm să copiați aceste valori în setările Nextcloud OpenProject Integration:" oauth_application_details_link_text: "Mergi la pagina setări" setup_documentation_details: "Dacă aveți nevoie de ajutor pentru configurarea unui nou depozit de fișiere, consultați documentația: " @@ -3356,7 +3452,7 @@ ro: If this option is active, login requests will redirect to the configured omniauth provider. The login dropdown and sign-in page will be disabled.
Note: Unless you also disable password logins, with this option enabled, users can still log in internally by visiting the %{internal_path} login page. attachments: whitelist_text_html: > - Definește o listă validă de extensii de fișiere și/sau tipuri mime pentru fișierele încărcate.
Introduceți extensii de fișiere (de ex. %{ext_example}) sau tipuri mime (e. ., %{mime_example}).
Lăsați gol pentru a permite oricărui tip de fișier să fie încărcat. Valori multiple permise (o linie pentru fiecare valoare). + Definește o listă validă de extensii de fișiere și/sau tipuri mime pentru fișierele încărcate.
Introdu extensii de fișiere (de ex. %{ext_example}) sau tipuri mime (e. ., %{mime_example}).
Lasă gol pentru a permite oricărui tip de fișier să fie încărcat. Valori multiple permise (o linie pentru fiecare valoare). show_work_package_attachments: > Deactivating this option will hide the attachments list on the work packages files tab for new projects. The files attached in the description of a work package will still be uploaded in the internal attachments storage. antivirus: @@ -3450,7 +3546,7 @@ ro: text_access_token_hint: "Tichetele de acces permit aplicaţiilor externe accesul la resurse din OpenProject." text_analyze: "Continuare analiză: %{subject}" text_are_you_sure: "Sunteți sigur?" - text_are_you_sure_continue: "Sigur doriţi să continuați?" + text_are_you_sure_continue: "Sigur dorești să continui?" text_are_you_sure_with_children: "Doriți ștergerea pachetului de lucru și a tuturor pachetelor fii?" text_are_you_sure_with_project_custom_fields: "Deleting this attribute will also delete its values in all projects. Are you sure you want to do this?" text_assign_to_project: "Alocare la proiect" @@ -3530,7 +3626,7 @@ ro: text_no_notes: "Nu sunt comentarii disponibile pentru acest pachet de lucru." text_notice_too_many_values_are_inperformant: "Atenție: Afişarea unui număr mai mare de 100 de articole pe pagină poate creşte durata de încărcare." text_notice_security_badge_displayed_html: > - Notă: dacă este activată, aceasta va afișa o insignă cu starea instalării în fereastra %{information_panel_label} panoul de administrare și pe pagina principală. Aceasta este afișată numai pentru administratori.
Insigna va verifica versiunea curentă a OpenProject în raport cu baza de date oficială a versiunilor OpenProject pentru a vă alerta cu privire la orice actualizări sau vulnerabilități cunoscute. Pentru mai multe informații despre ce oferă verificarea, ce date sunt necesare pentru a furniza actualizările disponibile și cum să dezactivați această verificare, vă rugăm să vizitați documentația de configurare. + Notă: dacă este activată, aceasta va afișa o insignă cu starea instalării în fereastra %{information_panel_label} panoul de administrare și pe pagina principală. Aceasta este afișată numai pentru administratori.
Insigna va verifica versiunea curentă a OpenProject în raport cu baza de date oficială a versiunilor OpenProject pentru a alerta cu privire la orice actualizări sau vulnerabilități cunoscute. Pentru mai multe informații despre ce oferă verificarea, ce date sunt necesare pentru a furniza actualizările disponibile și cum să dezactivezi această verificare, te rog să vizitezi documentația de configurare. text_own_membership_delete_confirmation: "Sunteţi cale de a elimina unele sau toate permisiunile şi e posibil să nu mai puteți edita acest proiect după aceea. \nSunteţi sigur că doriţi să continuaţi?" text_plugin_assets_writable: "Se poate scrie în directorul de resurse pentru module" text_powered_by: "Propulsat de %{link}" @@ -3590,7 +3686,7 @@ ro: queries: apply_filter: Aplicare filtru preconfigurat configure_view: - heading: Configurați vizualizarea + heading: Configurează vizualizarea columns: input_label: "Adaugă coloane" input_placeholder: "Select a column" @@ -3812,7 +3908,7 @@ ro: work_package: "Pachetul de lucru pe care îl căutați nu poate fi găsit sau a fost șters." expected: date: "AAAA-MM-ZZ (doar formate ISO 8601)" - datetime: "AAAA-LL-ZZZZH:mm:ss[.lll][+h:mm] (orice date compatibile ISO 8601 datetime)" + datetime: "AAAA-LL-ZZZZH:mm:ss[.lll][+h:mm] (orice dăți compatibile ISO 8601 dată-oră)" duration: "Durată ISO 8601" invalid_content_type: "CONTENT-TYPE așteptat '%{content_type}', dar am primit '%{actual}'." invalid_format: "Format invalid pentru proprietatea '%{property}': format așteptat '%{expected_format}', dar am primit '%{actual}'." @@ -3857,7 +3953,7 @@ ro: #Common error messages invalid_request: unknown: "În cerere lipsește un parametru obligatoriu, include o valoare de parametru neacceptată sau este deformată în alt mod." - missing_param: "Lipseste parametrul necesar: %{value}." + missing_param: "Lipsește parametrul obligatoriu: %{value}." request_not_authorized: "Solicitarea trebuie să fie autorizată. Parametrul necesar pentru solicitarea de autorizare lipsește sau este invalid." invalid_redirect_uri: "URL-ul de redirecționare solicitat este deformat sau nu se potrivește cu URL-ul de redirecționare al clientului." unauthorized_client: "Clientul nu este autorizat să efectueze această cerere folosind această metodă." @@ -3951,12 +4047,12 @@ ro: urn_connection_status: connected: "Conectat" error: "Eroare" - failed_authorization: "Autorizarea nu a reuşit" + failed_authorization: "Autorizare nereușită" labels: label_oauth_integration: "Integrare OAuth2" - label_redirect_uri: "Redirecționați URI" - label_request_token: "Token de cerere" - label_refresh_token: "Reîmprospătare token" + label_redirect_uri: "URI redirecționare" + label_request_token: "Token cerere" + label_refresh_token: "Token reîmprospătare" errors: oauth_authorization_code_grant_had_errors: "OAuth2 Authorization grant unsuccessful" oauth_reported: "Furnizor OAuth2 raportat" diff --git a/config/locales/crowdin/ru.seeders.yml b/config/locales/crowdin/ru.seeders.yml index 51ed2546b41a..faa5a996758a 100644 --- a/config/locales/crowdin/ru.seeders.yml +++ b/config/locales/crowdin/ru.seeders.yml @@ -34,6 +34,17 @@ ru: name: Темно-серый item_13: name: Чёрный + life_cycle_colors: + item_0: + name: PM2 Оранжевый + item_1: + name: PM2 Фиолетовый + item_2: + name: PM2 Красный + item_3: + name: PM2 Пурпурный + item_4: + name: PM2 Зелено-жёлтый document_categories: item_0: name: Документация @@ -70,6 +81,21 @@ ru: item_1: name: Стандартная глобальная роль standard: + life_cycles: + item_0: + name: Запуск + item_1: + name: Готов к планированию + item_2: + name: Планирование + item_3: + name: Готово к выполнению + item_4: + name: Выполнение + item_5: + name: Готов к закрытию + item_6: + name: Закрытие priorities: item_0: name: Низкое @@ -299,18 +325,20 @@ ru: options: name: Приступая к работе text: | - Мы рады, что вы присоединились! Мы рекомендуем попробовать несколько вещей, чтобы начать работу в OpenProject. - - _Попробуйте следующие шаги:_[Backlogs]. *Пригласите новых участников к вашему проекту*: → Перейдите к [Members]({{opSetting:base_url}}/projects/your-scrum-project/members) в навигации по проекту. - 2. *Просмотр бэклога продукта и бэклогов Sprint *: → Перейти к [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) в навигации по проекту. - *Просмотр вашей панели задач*: → Перейдите на [Backlogs] ({{opSetting:base_url}}/projects/your-scrum-project/backlogs) → Нажмите на правую стрелку на Sprint → Выберите [Целевую панель](##sprint:scrum_project__version__sprint_1). - 4. *Создать новый пакет работ*: → Перейдите к [Пакеты работ → Create]({{opSetting:base_url}}/projects/your-scrum-project/work_packages/new). - 5. *Создать и обновить план проекта*: → Перейдите к [плану проекта](##query:scrum_project__query__project_plan) в навигации по проекту. - 6. *Создайте вики спринта*: → Перейдите в [Backlogs]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) и откройте вики спринта из правого выпадающего меню в спринте. Вы можете редактировать [шаблон вики]({{opSetting:base_url}}/projects/your-scrum-project/wiki/) на основе ваших потребностей. - 7. *Активировать дальнейшие модули*: → Перейдите к [настройкам проекта → Модулей]({{opSetting:base_url}}/projects/your-scrum-project/settings/modules). - - Здесь вы найдете наши [руководства пользователя](https://www. penproject.org/docs/user-guide/). - Пожалуйста, сообщите нам, если у вас есть какие-либо вопросы или нужна поддержка. Свяжитесь с нами: [support[at]openproject.com](mailto:support@openproject.com). + Мы рады, что Вы присоединились! Мы предлагаем попробовать несколько вещей, чтобы начать работу с OpenProject. + + _Попробуйте выполнить следующие шаги:_ + + 1. *Пригласите новых участников в свой проект*: → Перейдите к [Участники]({{opSetting:base_url}}/projects/your-scrum-project/members) в меню проекта. + 2. *Просмотрите бэклог Вашего продукта и бэклог спринта*: → Перейдите к [Бэклог]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) в меню проекта. + 3. *Просмотрите Вашу доску задач*: → Перейдите к [Бэклоги]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) → Нажмите стрелку вправо на Этапы → Выберите [Панель задач](##sprint:scrum_project__version__sprint_1). + 4. *Создайте новый рабочий пакет*: → Перейдите в раздел [Рабочие пакеты → Создать]({{opSetting:base_url}}/projects/your-scrum-project/work_packages/new). + 5. *Создайте и обновите план проекта*: → Перейдите к разделу [План проекта](##query:scrum_project__query__project_plan) в меню проекта. + 6. *Создайте вики спринта*: → Перейдите в раздел [Бэклоги]({{opSetting:base_url}}/projects/your-scrum-project/backlogs) и откройте вики спринта из правого выпадающего меню в спринте. Вы можете отредактировать шаблон [wiki]({{opSetting:base_url}}/projects/your-scrum-project/wiki/) в соответствии со своими потребностями. + 7. *Активируйте дополнительные модули*: → Перейдите в раздел [Настройки проекта → Модули]({{opSetting:base_url}}/projects/your-scrum-project/settings/modules). + + Здесь Вы найдете наши [руководства пользователя](https://www.openproject.org/docs/user-guide/). + Пожалуйста, сообщите нам, если у Вас возникнут вопросы или Вам понадобится поддержка. Свяжитесь с нами: [support[at]openproject.com](mailto:support@openproject.com). item_5: options: name: Пакеты работ diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index 1d41d31fdbc7..951a6cb66fd0 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -33,7 +33,7 @@ ru: label_activity_show_only_changes: "Показать только изменения" label_sort_asc: "Новые внизу" label_sort_desc: "Новые вверху" - label_type_to_comment: "Введите комментарий" + label_type_to_comment: "Добавить комментарий. Введите @ для уведомления пользователей." label_submit_comment: "Отправить комментарий" changed_on: "изменено" created_on: "создано в" @@ -224,10 +224,10 @@ ru: blankslate: root: title: "Ваш список пунктов пуст" - description: "Start by adding items to the custom field of type hierarchy. Each item can be used to create a hierarchy bellow it. To navigate and create sub-items inside a hierarchy click on the created item." + description: "Начните с добавления элементов в иерархическое настраиваемое поле. Каждый элемент может быть использован для создания иерархии ниже его. Чтобы переместить и создать подпункты внутри иерархии, нажмите на созданный элемент." item: - title: This item doesn't have any hierarchy level below - description: Add items to this list to create sub-items inside another one + title: Этот элемент не имеет уровня иерархии ниже + description: Добавьте элементы в этот список, чтобы создать подпункты внутри другого списка placeholder: label: "Название элемента" short: "Краткое имя" @@ -238,6 +238,8 @@ ru: zero: нет подпунктов one: 1 подпункт other: "%{count} подпунктов" + upsale: + custom_field_format_hierarchy: "Вам нужна иерархия в пользовательских полях для пакетов работ?" text_add_new_custom_field: > Прежде чем добавлять настраиваемые поля в проект, нужно создать их. is_enabled_globally: "Разрешено в глобальном масштабе" @@ -264,20 +266,20 @@ ru: single: "или" dry_validation: errors: - integer?: "должно быть целое число" - filled?: "должно быть заполнено" - greater_or_equal_zero: "должно быть больше или равно 0" - not_found: "не найдено" + int?: "должно быть целым числом." + filled?: "должно быть заполнено." + greater_or_equal_zero: "должно быть больше или равно 0." + not_found: "не найдено." rules: item: - root_item: "не может быть корневым элементом" - not_persisted: "должно быть уже существующим элементом" + root_item: "не может быть корневым элементом." + not_persisted: "должно быть уже существующим элементом." label: - not_unique: "должно быть уникальным в пределах одного уровня иерархии" + not_unique: "должно быть уникальным в пределах одного уровня иерархии." short: - not_unique: "должно быть уникальным в пределах одного уровня иерархии" + not_unique: "должно быть уникальным в пределах одного уровня иерархии." parent: - not_descendant: "должно быть потомком корня иерархии" + not_descendant: "должно быть потомком корневого уровня иерархии." rules: depth: "Глубина" item: "Элемент" @@ -535,7 +537,7 @@ ru: react_with: "Реакция %{reaction}" and_user: "и %{user}" and_others: - one: and 1 other + one: и еще 1 few: and %{count} others many: and %{count} others other: и еще %{count} @@ -647,6 +649,66 @@ ru: no_results_title_text: На данный момент доступных типов рабочих пакетов нет. version: no_results_title_text: На данный момент этапы отсутствуют. + work_package_relations_tab: + index: + action_bar_title: "Добавьте отношения к другим рабочим пакетам, чтобы создать связь между ними." + no_results_title_text: На данный момент связи отсутствуют. + blankslate_heading: "Нет связей" + blankslate_description: "У этого пакета работ пока нет никаких связей." + label_add_x: "Добавить %{x}" + label_edit_x: "Редактировать %{x}" + label_add_description: "Добавить описание" + relations: + label_relates_singular: "связан с" + label_relates_plural: "связаны с" + label_relates_to_singular: "связан с" + label_relates_to_plural: "связаны с" + relates_description: "Создает видимую связь между двумя рабочими пакетами без дополнительного эффекта" + relates_to_description: "Создает видимую связь между двумя рабочими пакетами без дополнительного эффекта" + label_precedes_singular: "наследник (после)" + label_precedes_plural: "наследники (после)\n" + precedes_description: "Связанный пакет работ обязательно должен начаться после завершения этого пакета" + label_follows_singular: "предшественник (до)" + label_follows_plural: "предшественники (до)" + follows_description: "Соответствующий пакет работ обязательно должен быть завершен до того, как начнется этот пакет" + label_child_singular: "дочерний пакет работ" + label_child_plural: "дочерние пакеты работ" + child_description: "Делает связанный пакет работ дочерним текущему (родительскому) пакету работ" + label_blocks_singular: "блоки" + label_blocks_plural: "блоки" + blocks_description: "Связанный пакет работ не может быть закрыт до тех пор, пока не будет закрыт этот пакет" + label_blocked_singular: "заблокирован" + label_blocked_plural: "заблокированы" + label_blocked_by_singular: "заблокирован" + label_blocked__by_plural: "заблокированы" + blocked_description: "Связанный пакет работ не может быть закрыт до тех пор, пока не будет закрыт связанный пакет" + blocked_by_description: "Связанный пакет работ не может быть закрыт до тех пор, пока не будет закрыт связанный пакет" + label_duplicates_singular: "дублирует" + label_duplicates_plural: "дублируют" + duplicates_description: "Это копия связанного пакета работ" + label_duplicated_singular: "дублеруется" + label_duplicated_plural: "дублируются" + label_duplicated_by_singular: "дублируется" + label_duplicated_by_plural: "дублируются" + duplicated_by_description: "Связанный пакет работ является копией этого" + duplicated_description: "Связанный пакет работ является копией этого" + label_includes_singular: "включает" + label_includes_plural: "включают" + includes_description: "Отмечает связанный пакет работ как включающий этот пакет без дополнительного эффекта" + label_partof_singular: "часть" + label_partof_plural: "часть" + label_part_of_singular: "часть" + label_part_of_plural: "часть" + partof_description: "Отмечает связанный пакет работ как часть этого пакета без дополнительного эффекта" + part_of_description: "Помечает связанный пакет работ как часть этого пакета без дополнительного эффекта" + label_requires_singular: "требует" + label_requires_plural: "требуют" + requires_description: "Отмечает связанный с этим пакет работ как требование к нему" + label_required_singular: "требуется" + label_required_plural: "требуется" + required_description: "Отмечает этот пакет работ как требование к связанному" + label_parent_singular: "родитель" + label_parent_plural: "родители" label_invitation: Приглашение account: delete: "Удалить учётную запись" @@ -1043,6 +1105,20 @@ ru: attributes: project_ids: blank: "Пожалуйста, выберите проект." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "должен быть либо Project::StageDefinition, либо Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "должен быть либо Project::Stage, либо Project::Gate" + must_be_a_stage: "должен быть Project::Stage" + must_be_a_gate: "должен быть Project::Stage" + project/gate: + attributes: + base: + end_date_not_allowed: "Невозможно присвоить `end_date` проекту Project::Gate" query: attributes: project: @@ -1210,7 +1286,7 @@ ru: special: "спецсимволы (например, \"%\")" reused: one: "уже использовался ранее. Пожалуйста, укажите другое значение." - few: "уже использовалось ранее. Пожалуйста, укажите другое значение." + few: "уже использовался ранее. Пожалуйста, укажите отличающийся пароль от %{count} использованных ранее." many: "уже использовались ранее. Пожалуйста, укажите значения отличающиеся от %{count}." other: "уже использовалось ранее. Пожалуйста, укажите значения отличающиеся от ваших последних %{count}." match: @@ -1894,6 +1970,23 @@ ru: units: hours: ч days: д + pdf_generator: + page_nr_footer: "Страница %{page} из %{total}" + dialog: + title: Создать PDF + submit: Создать + header_right: + label: Заголовок справа + caption: Текст, отображаемый справа от заголовка + footer_center: + label: Нижний колонтитул по центру + caption: Текст, отображаемый в центре нижнего колонтитула + hyphenation: + label: Расстановка переносов + caption: Разрыв слов между строками для улучшения выравнивания и читаемости текста. + paper_size: + label: Размер бумаги + caption: Размер бумаги, используемый в PDF. extraction: available: pdftotext: "Pdftotext доступно (опционально)" @@ -2252,6 +2345,7 @@ ru: label_environment: "Переменные среды" label_estimates_and_progress: "Оценки и прогресс" label_equals: "—" + label_equals_with_descendants: "любой с потомками" label_everywhere: "везде" label_example: "Пример" label_experimental: "Экспериментально" @@ -2516,6 +2610,8 @@ ru: label_related_work_packages: "Связанные пакеты работ" label_relates: "Связан с" label_relates_to: "Связан с" + label_relation: "Связь" + label_relation_actions: "Действия со связями" label_relation_delete: "Удалить связь" label_relation_new: "Новая связь" label_release_notes: "Список изменений" @@ -2915,9 +3011,9 @@ ru: notice_locking_conflict: "Информация была обновлена одновременно с вами по крайней мере одним пользователем." notice_locking_conflict_additional_information: "Обновление(-ия) пришли от %{users}." notice_locking_conflict_reload_page: "Пожалуйста перезагрузите страницу, пересмотрите изменения и повторно примените Ваши обновления." - notice_locking_conflict_warning: "This page has been updated by someone else. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_danger: "Could not save your changes because of conflicting modifications. To not lose your edits, copy them locally and reload to view the updated version." - notice_locking_conflict_action_button: "Discard changes and reload" + notice_locking_conflict_warning: "Эта страница была обновлена кем-то еще. Чтобы не потерять ваши изменения, скопируйте их локально и перезагрузите страницу, чтобы просмотреть обновленную версию." + notice_locking_conflict_danger: "Не удалось сохранить ваши изменения из-за конфликтующих изменений. Чтобы не потерять ваши изменения, скопируйте их локально и перезагрузите страницу для просмотра обновления." + notice_locking_conflict_action_button: "Отменить изменения и перезагрузить" notice_member_added: '%{name} добавлено в проект.' notice_members_added: В проект добавлено %{number} пользователей. notice_member_removed: "Пользователь %{user} удален из проекта." @@ -3388,7 +3484,7 @@ ru: authentication: single_sign_on: "Единый вход" omniauth_direct_login_hint_html: > - If this option is active, login requests will redirect to the configured omniauth provider. The login dropdown and sign-in page will be disabled.
Note: Unless you also disable password logins, with this option enabled, users can still log in internally by visiting the %{internal_path} login page. + Если эта опция включена, запросы на вход в систему будут перенаправлены на настроенный провайдер omniauth. Выпадающий список входа и страница входа будут отключены.
Примечание: Если вы также не отключите вход по паролю, то пользователи все еще могут войти внутри системы, посетив страницу входа %{internal_path}. attachments: whitelist_text_html: > Определите список допустимых расширений файлов и/или mime типов для загруженных файлов.
Введите расширения файлов (например, %{ext_example}) или mime типы (e. ., %{mime_example}).
Оставьте пустым, чтобы разрешить загрузку любого типа файла. Допустимы несколько значений (одна строка для каждого значения). diff --git a/config/locales/crowdin/rw.seeders.yml b/config/locales/crowdin/rw.seeders.yml index 86948caa9dba..de36a76fb714 100644 --- a/config/locales/crowdin/rw.seeders.yml +++ b/config/locales/crowdin/rw.seeders.yml @@ -34,6 +34,17 @@ rw: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ rw: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml index 0bf8a390f232..39a514280586 100644 --- a/config/locales/crowdin/rw.yml +++ b/config/locales/crowdin/rw.yml @@ -33,7 +33,7 @@ rw: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ rw: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ rw: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ rw: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ rw: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ rw: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ rw: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ rw: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/si.seeders.yml b/config/locales/crowdin/si.seeders.yml index a9916a6df888..74fc005b85cd 100644 --- a/config/locales/crowdin/si.seeders.yml +++ b/config/locales/crowdin/si.seeders.yml @@ -34,6 +34,17 @@ si: name: අළු (අඳුරු) item_13: name: කළු + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ si: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: අඩු diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml index 2d54483b4bd6..9643801aac70 100644 --- a/config/locales/crowdin/si.yml +++ b/config/locales/crowdin/si.yml @@ -33,7 +33,7 @@ si: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ si: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > ව්යාපෘතියකට නව අභිරුචි ක්ෂේත්ර එකතු කිරීම සඳහා ඔබ මුලින්ම මෙම ව්යාපෘතියට එකතු කිරීමට පෙර ඒවා නිර්මාණය කළ යුතුය. is_enabled_globally: "ගෝලීයව සබල කර ඇත" @@ -265,20 +267,20 @@ si: single: "හෝ" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ si: no_results_title_text: දැනට වර්ග නොමැත. version: no_results_title_text: දැනට කිසිදු අනුවාදයක් නොමැත. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: ඇරයුම account: delete: "ගිණුම මකන්න" @@ -1028,6 +1090,20 @@ si: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ si: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "ලබා ගත හැකි PDftotext (විකල්ප)" @@ -2181,6 +2274,7 @@ si: label_environment: "පරිසරය" label_estimates_and_progress: "Estimates and progress" label_equals: "වේ" + label_equals_with_descendants: "is any with descendants" label_everywhere: "සෑම තැනකම" label_example: "උදාහරණය" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ si: label_related_work_packages: "අදාළ වැඩ පැකේජ" label_relates: "සම්බන්ධ" label_relates_to: "සම්බන්ධ" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "සම්බන්ධතාවය මකන්න" label_relation_new: "නව සම්බන්ධතාවය" label_release_notes: "සටහන් නිකුත් කිරීම" diff --git a/config/locales/crowdin/sk.seeders.yml b/config/locales/crowdin/sk.seeders.yml index 2022a7ce9dd7..2cdc966629bf 100644 --- a/config/locales/crowdin/sk.seeders.yml +++ b/config/locales/crowdin/sk.seeders.yml @@ -34,6 +34,17 @@ sk: name: Šedá (tmavá) item_13: name: Čierna + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentácia @@ -70,6 +81,21 @@ sk: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Nízka diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml index 83e6714a929d..a7542273e4bd 100644 --- a/config/locales/crowdin/sk.yml +++ b/config/locales/crowdin/sk.yml @@ -33,7 +33,7 @@ sk: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ sk: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Ak chcete priradiť nové vlastné pole do projektu, je potrebné ich vytvoriť ako prvé. Následne je ich možné pridať v tomto projekte. is_enabled_globally: "Je povolené globálne" @@ -265,20 +267,20 @@ sk: single: "alebo" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -648,6 +650,66 @@ sk: no_results_title_text: Momentálne nie sú k dispozícii žiadne typy. version: no_results_title_text: V súčasnosti nie sú k dispozícii žiadne verzie. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Pozvánka account: delete: "Vymazať účet" @@ -1044,6 +1106,20 @@ sk: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1895,6 +1971,23 @@ sk: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext k dispozícii (voliteľné)" @@ -2253,6 +2346,7 @@ sk: label_environment: "Prostredie" label_estimates_and_progress: "Estimates and progress" label_equals: "je" + label_equals_with_descendants: "is any with descendants" label_everywhere: "všade" label_example: "Príklad" label_experimental: "Experimental" @@ -2517,6 +2611,8 @@ sk: label_related_work_packages: "Súvisiace pracovné balíčky" label_relates: "súvisiace s" label_relates_to: "súvisiace s" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Odstrániť vzťah" label_relation_new: "Nový vzťah" label_release_notes: "Zoznam zmien" diff --git a/config/locales/crowdin/sl.seeders.yml b/config/locales/crowdin/sl.seeders.yml index 3583e2c50355..17712bd1c543 100644 --- a/config/locales/crowdin/sl.seeders.yml +++ b/config/locales/crowdin/sl.seeders.yml @@ -34,6 +34,17 @@ sl: name: Temno siva item_13: name: Črno + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentacija @@ -70,6 +81,21 @@ sl: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Nizko diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml index a58d1ffbc31a..66684c2325d5 100644 --- a/config/locales/crowdin/sl.yml +++ b/config/locales/crowdin/sl.yml @@ -33,7 +33,7 @@ sl: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -238,6 +238,8 @@ sl: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Če želite projektu dodati nova polja po meri, jih morate najprej ustvariti, preden jih lahko dodate v ta projekt. is_enabled_globally: "Omogočeno po vsem svetu" @@ -264,20 +266,20 @@ sl: single: "ali" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -645,6 +647,66 @@ sl: no_results_title_text: Trenutno ni na voljo nobenih vrst. version: no_results_title_text: Trenutno ni na voljo nobene različice. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Povabilo account: delete: "Izbriši račun" @@ -1041,6 +1103,20 @@ sl: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1892,6 +1968,23 @@ sl: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Na voljo je pdftotekst (neobvezno)" @@ -2250,6 +2343,7 @@ sl: label_environment: "Okolje" label_estimates_and_progress: "Estimates and progress" label_equals: "je" + label_equals_with_descendants: "is any with descendants" label_everywhere: "Povsod" label_example: "Primer" label_experimental: "Experimental" @@ -2514,6 +2608,8 @@ sl: label_related_work_packages: "Soroden zahtevek/delovni paket" label_relates: "povezan z" label_relates_to: "povezan z" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Izbriši povezavo" label_relation_new: "Nova povezava" label_release_notes: "Opombe ob izdaji" diff --git a/config/locales/crowdin/sr.seeders.yml b/config/locales/crowdin/sr.seeders.yml index 7dbc9df6960b..a4378ba9f32e 100644 --- a/config/locales/crowdin/sr.seeders.yml +++ b/config/locales/crowdin/sr.seeders.yml @@ -34,6 +34,17 @@ sr: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ sr: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml index 48d40ea48561..c3703e2c81a9 100644 --- a/config/locales/crowdin/sr.yml +++ b/config/locales/crowdin/sr.yml @@ -33,7 +33,7 @@ sr: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ sr: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ sr: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -640,6 +642,66 @@ sr: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1036,6 +1098,20 @@ sr: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1859,6 +1935,23 @@ sr: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2217,6 +2310,7 @@ sr: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2481,6 +2575,8 @@ sr: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/sv.seeders.yml b/config/locales/crowdin/sv.seeders.yml index d3140cff32b8..fa7fc01a361b 100644 --- a/config/locales/crowdin/sv.seeders.yml +++ b/config/locales/crowdin/sv.seeders.yml @@ -34,6 +34,17 @@ sv: name: Grå (mörk) item_13: name: Svart + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Dokumentation @@ -70,6 +81,21 @@ sv: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Låg diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml index 704206e2a997..0ba760f392ce 100644 --- a/config/locales/crowdin/sv.yml +++ b/config/locales/crowdin/sv.yml @@ -33,7 +33,7 @@ sv: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ sv: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Innan du kan lägga till nya anpassade fält till ett projekt måste du skapa dessa. is_enabled_globally: "Är aktiverad globalt" @@ -265,24 +267,24 @@ sv: single: "eller" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" - label: "Label" + label: "Etikett" short: "Short name" parent: "Parent" global_search: @@ -631,6 +633,66 @@ sv: no_results_title_text: Det finns för närvarande inga typer tillgängliga. version: no_results_title_text: Det finns för närvarande inga tillgängliga versioner. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Inbjudan account: delete: "Ta bort konto" @@ -1027,6 +1089,20 @@ sv: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1822,6 +1898,23 @@ sv: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext tillgängligt (tillval)" @@ -2180,6 +2273,7 @@ sv: label_environment: "Miljö" label_estimates_and_progress: "Estimates and progress" label_equals: "är" + label_equals_with_descendants: "is any with descendants" label_everywhere: "överallt" label_example: "Exempel" label_experimental: "Experimentell" @@ -2444,6 +2538,8 @@ sv: label_related_work_packages: "Relaterat arbetspaket" label_relates: "Relaterad till" label_relates_to: "Relaterad till" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Ta bort relation" label_relation_new: "Ny relation" label_release_notes: "Versionsnoteringar" diff --git a/config/locales/crowdin/th.seeders.yml b/config/locales/crowdin/th.seeders.yml index 2bc0285b6727..3d3a1b7d6d5d 100644 --- a/config/locales/crowdin/th.seeders.yml +++ b/config/locales/crowdin/th.seeders.yml @@ -34,6 +34,17 @@ th: name: สีเทา (เข้ม) item_13: name: สีดำ + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ th: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: ต่ำ diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml index 864a97fb1aca..991edfc016ee 100644 --- a/config/locales/crowdin/th.yml +++ b/config/locales/crowdin/th.yml @@ -33,7 +33,7 @@ th: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ th: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ th: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -624,6 +626,66 @@ th: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "ลบบัญชีผู้ใช้" @@ -1020,6 +1082,20 @@ th: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1787,6 +1863,23 @@ th: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2145,6 +2238,7 @@ th: label_environment: "สภาพแวดล้อม" label_estimates_and_progress: "Estimates and progress" label_equals: "เป็น" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "ตัวอย่าง" label_experimental: "Experimental" @@ -2409,6 +2503,8 @@ th: label_related_work_packages: "ชุดภารกิจที่เกี่ยวข้อง" label_relates: "ที่เกี่ยวข้องกับ" label_relates_to: "ที่เกี่ยวข้องกับ" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "ลบความสัมพันธ์" label_relation_new: "ความสัมพันธ์ใหม่" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/tr.seeders.yml b/config/locales/crowdin/tr.seeders.yml index c257585da7ce..9a6e9c771b67 100644 --- a/config/locales/crowdin/tr.seeders.yml +++ b/config/locales/crowdin/tr.seeders.yml @@ -34,6 +34,17 @@ tr: name: Gri (koyu) item_13: name: Siyah + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Belgeleme @@ -70,6 +81,21 @@ tr: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Düşük diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml index eaafca04941e..d677aa8255fd 100644 --- a/config/locales/crowdin/tr.yml +++ b/config/locales/crowdin/tr.yml @@ -33,7 +33,7 @@ tr: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -64,8 +64,8 @@ tr: enterprise_more_info: "Not: Kullanılan logo herkese açık olacaktır." manage_colors: "Renk seçim seçeneklerini düzenle" instructions: - primary-button-color: "Strong accent color, used for the most important button on a screen." - accent-color: "Color for links and other decently highlighted elements." + primary-button-color: "Güçlü vurgu rengi, genellikle ekrandaki en önemli düğme için kullanılır." + accent-color: "Bağlantılar ve diğer uygun biçimde vurgulanmış öğeler için renk." header-item-bg-hover-color: "Tıklanabilir başlık bileşenleri nin üzerine gelindiğinde kullanılacak arka plan rengi." header-item-font-color: "Tıklanabilir başlık bileşenleri için yazı rengi." header-item-font-hover-color: "Tıklanabilir başlık bileşenleri nin üzerine gelindiğinde kullanılacak yazı rengi." @@ -89,9 +89,9 @@ tr: buttons: upgrade: "Hemen Yükselt" contact: "Demo için bizimle iletişime geçin" - enterprise_info_html: "is an Enterprise add-on." + enterprise_info_html: "bir Kurumsal eklentisidir." upgrade_info: "Etkinleştirmek ve ekibinizde kullanmaya başlamak için lütfen ücretli bir plana yükseltin." - jemalloc_allocator: Jemalloc memory allocator + jemalloc_allocator: Jemalloc bellek ayırıcı journal_aggregation: explanation: text: "Bir kullanıcının bireysel eylemleri (örneğin, bir iş paketini iki kez güncelleme), yaş farkı belirtilen zaman aralığından azsa tek bir eylemde toplanır. Uygulama içinde tek bir eylem olarak görüntülenecektir. Bu aynı zamanda gönderilen e-posta sayısını azaltarak bildirimleri aynı süre kadar geciktirecek ve ayrıca %{webhook_link} gecikmesini etkileyecektir." @@ -101,16 +101,16 @@ tr: is_active: şu an görüntüleniyor is_inactive: şu an görüntülenmiyor antivirus_scan: - not_processed_yet_message: "Downloading is blocked, as file was not scanned for viruses yet. Please try again later." - quarantined_message: "A virus was detected in file '%{filename}'. It has been quarantined and is not available for download." - deleted_message: "A virus was detected in file '%{filename}'. The file has been deleted." - deleted_by_admin: "The quarantined file '%{filename}' has been deleted by an administrator." - overridden_by_admin: "The quarantine for file '%{filename}' has been removed by %{user}. The file can now be acccessed." + not_processed_yet_message: "Dosya henüz virüs taramasından geçirilmediği için indirme işlemi engellendi. Lütfen daha sonra tekrar deneyin." + quarantined_message: "'%{filename}' dosyasında bir virüs tespit edildi. Dosya karantinaya alındı ve indirilemez." + deleted_message: "'%{filename}' dosyasında bir virüs tespit edildi. Dosya silinmiştir." + deleted_by_admin: "Karantinaya alınan '%{filename}' dosyası bir yönetici tarafından silindi." + overridden_by_admin: "'%{filename}' dosyası için karantina %{user} tarafından kaldırıldı. Dosyaya artık erişilebilir." quarantined_attachments: - container: "Container" - delete: "Delete the quarantined file" - title: "Quarantined attachments" - error_cannot_act_self: "Cannot perform actions on your own uploaded files." + container: "Depo" + delete: "Karantinaya alınan dosyayı sil" + title: "Karantinaya alınan ekler" + error_cannot_act_self: "Kendi yüklediğiniz dosyalar üzerinde işlem yapamazsınız." attribute_help_texts: note_public: "Bu alana eklediğiniz herhangi bir metin ve resim, oturum açmış tüm kullanıcılar tarafından herkes tarafından görülebilir!" text_overview: "Bu görünümde, öznitelikleri görünüm için özel yardım metinler oluşturabilirsiniz. Tanımladığınızda, bu metinler, aidiyet öznitelik yanındaki Yardım simgesini tıklayarak gösterilebilir." @@ -125,8 +125,8 @@ tr: ldap_auth_sources: ldap_error: "LDAP-Hatası: %{error_message}" ldap_auth_failed: "LDAP sunucusunda kimlik doğrulaması yapılamadı." - sync_failed: "Failed to synchronize from LDAP: %{message}." - back_to_index: "Click here to go back to the list of connection." + sync_failed: "LDAP'den senkronizasyon başarısız oldu: %{message}." + back_to_index: "Bağlantı listesine geri dönmek için buraya tıklayın." technical_warning_html: | Bu LDAP formu, LDAP / Active Directory kurulumunuz hakkında teknik bilgi gerektirir.
@@ -218,27 +218,29 @@ tr: admin: custom_field_projects: is_for_all_blank_slate: - heading: For all projects - description: This custom field is enabled in all projects since the "For all projects" option is checked. It cannot be deactivated for individual projects. + heading: Tüm projeler için + description: '"Tüm projeler için" seçeneği işaretli olduğu için bu proje niteliği tüm projelerde etkindir. Projeler için bağımsız olarak devre dışı bırakılamaz.' items: - actions: "Item actions" + actions: "Öğe eylemleri" blankslate: root: - title: "Your list of items is empty" - description: "Start by adding items to the custom field of type hierarchy. Each item can be used to create a hierarchy bellow it. To navigate and create sub-items inside a hierarchy click on the created item." + title: "Öğeler listeniz boş" + description: "Hiyerarşi türündeki özel alana öğeler ekleyerek başlayın. Her öğe, altında bir hiyerarşi oluşturmak için kullanılabilir. Bir hiyerarşi içinde gezinmek ve alt öğeler oluşturmak için oluşturulan öğeye tıklayın." item: - title: This item doesn't have any hierarchy level below - description: Add items to this list to create sub-items inside another one + title: Bu öğenin altında herhangi bir hiyerarşi düzeyi yoktur + description: Başka bir listenin içinde alt öğeler oluşturmak için bu listeye öğeler ekleyin placeholder: - label: "Item label" - short: "Short name" + label: "Öğe etiketi" + short: "Kısa adı" notice: - remember_items_and_projects: "Remember to set items and projects in the respective tabs for this custom field." + remember_items_and_projects: "Bu özel alan için ilgili sekmelerde öğeleri ve projeleri ayarlamayı unutmayın." hierarchy: subitems: - zero: no sub-items - one: 1 sub-item - other: "%{count} sub-items" + zero: alt öğe yok + one: 1 alt öğe + other: "%{count} alt öğe" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Bir projeye yeni özel alanlar eklemeden önce onları oluşturmalısınız. is_enabled_globally: "Genel için etkinleştirildi" @@ -249,13 +251,13 @@ tr: reorder_confirmation: "Uyarı: Mevcut değerlerin sırası kaybolacak. Devam et?" instructions: is_required: "Mark the custom field as required. This will make it mandatory to fill in the field when creating new or updating existing resources." - is_required_for_project: "Check to enable this attribute and make it required in all projects. It cannot be deactived for individual projects." + is_required_for_project: "Bu özelliği etkinleştirmek ve tüm projelerde gerekli kılmak için işaretleyin. Tek tek projeler için devre dışı bırakılamaz." is_for_all: "Mark the custom field as available in all existing and new projects." - multi_select: "Allows the user to assign multiple values to this custom field." + multi_select: "Kullanıcının bu özel alana birden fazla değer atamasına izin verir." searchable: "Include the field values when using the global search functionality." - searchable_for_project: "Check to make this attribute available as a filter in project lists." + searchable_for_project: "Bu niteliği proje listelerinde filtre olarak kullanmak için işaretleyin." editable: "Allow the field to be editable by users themselves." - admin_only: "Check to make this attribute only visible to administrators. Users without admin rights will not be able to view or edit it." + admin_only: "Bu niteliğin yalnızca yöneticilere görünür kılmak için işaretleyin. Yönetici hakları olmayan kullanıcılar bunu görüntüleyemez veya düzenleyemez." is_filter: > Allow the custom field to be used in a filter in work package views. Note that only with 'For all projects' selected, the custom field will show up in global views. tab: @@ -265,28 +267,28 @@ tr: single: "ya da" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: - depth: "Depth" - item: "Item" - label: "Label" - short: "Short name" - parent: "Parent" + depth: "Derinlik" + item: "Öğe" + label: "Etiket" + short: "Kısa adı" + parent: "Üst" global_search: - placeholder: "Search in %{app_title}" + placeholder: "%{app_title} içinde ara" overwritten_tabs: wiki_pages: "Viki" messages: "Forum" @@ -311,7 +313,7 @@ tr: work_package_attachments: "İş paketleri: ekler" work_package_categories: "İş paketleri: kategoriler" work_package_file_links: "Çalışma paketleri: dosya bağlantıları" - work_package_shares: "Work packages: shares" + work_package_shares: "İş paketleri: paylaşımlar" delete: scheduled: "Silme planlandı ve arka planda gerçekleştirilir. Sonuçtan haberdar edileceksiniz." schedule_failed: "Proje silinemiyor: %{errors}" @@ -325,8 +327,8 @@ tr: no_results_title_text: Şu anda hiç proje bulunmamakta no_results_content_text: Yeni bir proje oluşturun search: - label: Project name filter - placeholder: Search by project name + label: Proje adı filtresi + placeholder: Proje adına göre ara lists: active: "Aktif projeler" my: "Projelerim" @@ -487,11 +489,11 @@ tr: browser: "Tarayıcı" device: "Cihaz / İşletim Sistemi" unknown_browser: "bilinmeyen tarayıcı" - unknown_os: "unknown operating system" - current: "Current session" - title: "Session management" - instructions: "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize or you have no longer access to." - may_not_delete_current: "You cannot delete your current session." + unknown_os: "bilinmeyen işletim sistemi" + current: "Şuanki oturum" + title: "Oturum yönetimi" + instructions: "Bu, hesabınıza giriş yapmış olan cihazların bir listesidir. Tanımadığınız veya artık erişiminizin olmadığı oturumları iptal edin." + may_not_delete_current: "Şuanki oturumunuzu silemezsiniz." groups: member_in_these_groups: "Bu kullanıcı şu anda aşağıdaki grupların bir üyesidir:" no_results_title_text: Bu kullanıcı şu anda hiçbir gruba üye değil. @@ -519,14 +521,14 @@ tr: Bu önceliğin rengini atamak veya değiştirmek için tıklayın. Tablodaki iş paketlerini vurgulamak için kullanılabilir. reactions: - action_title: "React" - add_reaction: "Add reaction" - react_with: "React with %{reaction}" - and_user: "and %{user}" + action_title: "Tepki" + add_reaction: "Tepki ekle" + react_with: "%{reaction} ile tepki ver" + and_user: "ve %{user} ile" and_others: - one: and 1 other - other: and %{count} others - reaction_by: "%{reaction} by" + one: ve 1 diğeri + other: ve %{count} tane daha + reaction_by: "tarafından %{reaction}" reportings: index: no_results_title_text: Halen durum bildirimleri yok. @@ -537,14 +539,13 @@ tr: Bu durumun rengini atamak veya değiştirmek için tıklayın. Durum düğmesinde gösterilir ve tablodaki iş paketlerini vurgulamak için kullanılabilir. status_default_text: |- - New work packages are by default set to this type. They cannot be read-only. + Yeni iş paketleri varsayılan olarak bu türe ayarlanmıştır. Salt okunur olamazlar. status_excluded_from_totals_text: |- - Check this option to exclude work packages with this status from totals of Work, - Remaining work, and % Complete in a hierarchy. + Bir hiyerarşide bu duruma sahip iş paketlerini İş, + Kalan iş ve % Tamamlandı toplamlarından hariç tutmak için bu seçeneği işaretleyin. status_percent_complete_text: |- - In status-based progress calculation mode, the % Complete of a work - package is automatically set to this value when this status is selected. - Ignored in work-based mode. + Durum bazlı ilerleme hesaplama modunda, bu durum seçildiğinde bir işin % Tamamlandı durumu otomatik olarak bu değere ayarlanır. + İş bazlı modda yok sayılır. status_readonly_html: | Bu durumdaki iş paketlereni salt okunur olarak işaretlemek için bu seçeneği işaretleyin. Durum haricindeki başka özellikler değiştirilemez. @@ -557,11 +558,11 @@ tr: is_default: "Varsayılan" is_closed: "Kapalı" is_readonly: "Salt okunur" - excluded_from_totals: "Excluded from totals" + excluded_from_totals: "Toplamlardan hariç tutulanlar" themes: - dark: "Dark" - light: "Light" - light_high_contrast: "Light high contrast" + dark: "Koyu" + light: "Açık" + light_high_contrast: "Yüksek kontrastlı açık" types: index: no_results_title_text: Şu anda hiç tip yok. @@ -580,7 +581,7 @@ tr: Seçilen renk, Gantt şemalarında veya iş paketleri tablolarında farklı türleri ayırt eder. Bu nedenle güçlü bir renk kullanılması önerilir. versions: overview: - work_packages_in_archived_projects: "The version is shared with archived projects which still have work packages assigned to this version. These are counted, but will not appear in the linked views." + work_packages_in_archived_projects: "Sürüm, hala bu sürüme atanmış iş paketleri olan arşivlenmiş projelerle paylaşılmakta. Bunlar sayılır, ancak bağlantılı görünümlerde gösterilmez." no_results_title_text: Bu sürüme atadığım iş paketi bulunmuyor. wiki: page_not_editable_index: İstenen sayfa mevcut değil (henüz). Tüm wiki sayfalarının dizinine yönlendirildiniz. @@ -596,20 +597,20 @@ tr: one: "Bir soydan iş paketi" other: "%{count} Bir soydan iş paketi" bulk: - copy_failed: "The work packages could not be copied." - move_failed: "The work packages could not be moved." + copy_failed: "İş paketleri kopyalanamadı." + move_failed: "İş paketleri taşınamadı." could_not_be_saved: "Aşağıdaki iş paketleri kaydedilemedi:" none_could_be_saved: "%{total} iş paketlerinin hiçbiri güncellenemedi." x_out_of_y_could_be_saved: "%{total} iş paketinden %{failing} tanesi güncellenemezken %{success} güncellenebildi." - selected_because_descendants: "While %{selected} work packages were selected, in total %{total} work packages are affected which includes descendants." + selected_because_descendants: "Seçilen %{selected} iş paketleri seçiliyken, toplamda alt iş paketlerini de içeren %{total} iş paketi etkilenmekte." descendant: "seçilmiş nesil" move: no_common_statuses_exists: "Seçilen tüm iş paketleri için uygun bir durum yoktur. Durumları değiştirilemez." unsupported_for_multiple_projects: "Birden çok projeden iş paketi için toplu taşıma / kopyalama desteklenmiyor" current_type_not_available_in_target_project: > - The current type of the work package is not enabled in the target project. Please enable the type in the target project if you'd like it to remain unchanged. Otherwise, select an available type in the target project from the list. + İş paketinin mevcut türü hedef projede etkinleştirilmemiştir. Değişmeden kalmasını istiyorsanız lütfen hedef projede bu türü etkinleştirin. Aksi takdirde, listeden hedef projede kullanılabilir bir tür seçin. bulk_current_type_not_available_in_target_project: > - The current types of the work packages aren't enabled in the target project. Please enable the types in the target project if you'd like them to remain unchanged. Otherwise, select an available type in the target project from the list. + İş paketinin mevcut türleri hedef projede etkinleştirilmemiştir. Değişmeden kalmasını istiyorsanız lütfen hedef projede bu türleri etkinleştirin. Aksi takdirde, listeden hedef projede kullanılabilir bir tür seçin. sharing: missing_workflow_warning: title: "Workflow missing for work package sharing" @@ -631,6 +632,66 @@ tr: no_results_title_text: Şu anda hiçbir tip mevcut değil. version: no_results_title_text: Şu anda sürüm bulunmuyor. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Davet account: delete: "Hesabı sil" @@ -657,7 +718,7 @@ tr: error_self_registration_disabled: > Bu sistemde kullanıcı kaydı yapılması devre dışı bırakılmıştır. Lütfen bir yöneticiden sizin için bir hesap oluşturmasını isteyin. error_self_registration_limited_provider: > - User registration is limited for the Single sign-on provider '%{name}'. Please ask an administrator to activate the account for you or change the self registration limit for this provider. + Tek noktadan oturum açma sağlayıcısı '%{name}' için kullanıcı kaydı sınırlıdır. Lütfen yöneticiden hesabınızı sizin için etkinleştirmesini veya bu sağlayıcı için kendi kendine kayıt sınırını değiştirmesini isteyin. login_with_auth_provider: "veya varolan hesabınızı kullanarak oturum açın" signup_with_auth_provider: "veya kullanarak kaydolun" auth_source_login: Hesabınızı aktifleştirmek için lütfen %{login} olarak giriş yapın. @@ -686,12 +747,12 @@ tr: custom_action: actions: "Eylemler" custom_field: - allow_non_open_versions: "Allow non-open versions" + allow_non_open_versions: "Açık olmayan sürümlere izin ver" default_value: "Varsayılan değer" editable: "Düzenlenebilir" field_format: "Biçim" is_filter: "Filtre olarak kullanılan" - is_for_all: "For all projects" + is_for_all: "Tüm projeler için" is_required: "Gerekli" max_length: "Maksimum uzunluk" min_length: "Minimum uzunluk" @@ -699,15 +760,15 @@ tr: possible_values: "Olası değerler" regexp: "Düzenli ifade" searchable: "Aranabilir" - admin_only: "Admin-only" + admin_only: "Yalnızca yönetici" custom_value: value: "Değer" doorkeeper/application: uid: "Müşteri Kimliği" secret: "Müşteri gizliliği" owner: "Ürün Sahibi" - builtin: "Builtin" - enabled: "Active" + builtin: "Dahili" + enabled: "Aktif" redirect_uri: "Yönlendirme URI'si" client_credentials_user_id: "Müşteri Kimlik Bilgileri ve Kullanıcı Kimliği gereklidir" scopes: "Kapsamlar" @@ -755,7 +816,7 @@ tr: queries: "Sorgular" status_code: "Proje Durumu" description: "Açıklama" - status_explanation: "Project status description" + status_explanation: "Proje durumunun tanımı" status_codes: not_started: "Başlatılmadı" on_track: "Takipte" @@ -771,8 +832,8 @@ tr: versions: "Sürümler" work_packages: "İş Paketleri" project_custom_field: - is_required: "Required for all projects" - custom_field_section: Section + is_required: "Tüm projelerde zorunludur" + custom_field_section: Bölüm query: column_names: "Sütunlar" relations_to_type_column: "%{type} ile ilişkileri" @@ -781,7 +842,7 @@ tr: filters: "Filtreler" timeline_labels: "Zaman çizelgesi etiketleri" relation: - lag: "Lag" + lag: "Gecikme" from: "İş paketi" to: "İlgili iş paketi" repository: @@ -791,14 +852,14 @@ tr: status: is_closed: "İş paketi kapalı" is_readonly: "İş paketi salt okunur" - excluded_from_totals: "Exclude from calculation of totals in hierarchy" - default_done_ratio: "% Complete" + excluded_from_totals: "Hiyerarşideki toplamların hesaplanmasından hariç tut" + default_done_ratio: "% Tamamlandı" time_entry: activity: "Etkinlik" hours: "Saat" spent_on: "Tarih" type: "Tür" - ongoing: "Ongoing" + ongoing: "Devam eden" type: description: "Açıklama için varsayılan metin" attribute_groups: "" @@ -810,7 +871,7 @@ tr: admin: "Yönetici" auth_source: "Authentication source" ldap_auth_source: "LDAP bağlantısı" - identity_url: "Identity URL" + identity_url: "Kimlik URL'si" current_password: "Mevcut parola" force_password_change: "Sonraki oturum açma işleminde parola değişikliğine zorla" language: "Dil" @@ -824,8 +885,8 @@ tr: time_zone: "Zaman dilimi" auto_hide_popups: "Başarılı bildirimleri otomatik olarak gizle" warn_on_leaving_unsaved: "İş paketlerinden ayrılırken kaydedilmemiş değişiklik olduğunda beni uyar" - theme: "Mode" - mode_guideline: "Some modes will overwrite custom theme colours for accessibility and legibility. For the full custom theme, please select Light mode." + theme: "Mod" + mode_guideline: "Bazı modlar, erişilebilirlik ve okunabilirlik için özel tema renklerini değiştirecektir. Özel temada tüm özellikleri kullanmak için lütfen Açık modu seçin." version: effective_date: "Bitiş tarihi" sharing: "Paylaşım" @@ -841,7 +902,7 @@ tr: derived_done_ratio: "Toplam tamamlanma %" derived_remaining_hours: "Toplam kalan iş" derived_remaining_time: "Toplam kalan iş" - done_ratio: "% Complete" + done_ratio: "% Tamamlandı" duration: "Süre" end_insertion: "Ekleme işlemi bitti" end_deletion: "Silme işlemi bitti" @@ -850,16 +911,16 @@ tr: title: "İş Günleri" false: "Sadece iş günleri" true: "çalışılmayan günleri dahil et" - notify: "Notify" #used in custom actions + notify: "Bildirim" #used in custom actions parent: "Üst" parent_issue: "Üst" parent_work_package: "Üst" priority: "Öncelik" - progress: "% Complete" + progress: "% Tamamlandı" readonly: "Salt okunur" remaining_hours: "Kalan çalışma" remaining_time: "Kalan çalışma" - shared_with_users: "Shared with" + shared_with_users: "Şununla paylaşıldı" schedule_manually: "Manuel zamanlamayı etkinleştir" spent_hours: "Harcanan zaman" spent_time: "Harcanan zaman" @@ -877,8 +938,8 @@ tr: before_or_equal_to: "%{date}} tarihinden önce veya ona eşit olmalıdır." blank: "boş bırakılamaz." blank_nested: "'%{property}' özelliğinin ayarlanmış olması gerekir." - cannot_delete_mapping: "is required. Cannot be deleted." - is_for_all_cannot_modify: "is for all projects and can therefore not be modified." + cannot_delete_mapping: "zorunlu. Silinemez." + is_for_all_cannot_modify: "tüm projeler içindir ve bu nedenle değiştirilemez." cant_link_a_work_package_with_a_descendant: "İş paketi alt görevlerinden birine bağlanamaz." circular_dependency: "Bu ilişki döngüsel bağımlılık oluşturacak." confirmation: "%{attribute} eşleşmiyor." @@ -909,17 +970,17 @@ tr: not_available: "Sistem yapılandırması nedeniyle kullanılamaz.\n" not_deletable: "kaldırılamadı." not_current_user: "mevcut kullanıcı değil." - not_found: "not found." + not_found: "bulunamadı." not_a_date: "geçerli bir tarih değil." not_a_datetime: "geçerli bir zaman değil." not_a_number: "bir sayı değil." not_allowed: "Eksik izinler nedeniyle geçersiz." - not_json: "is not a valid JSON object." + not_json: "geçerli bir JSON nesnesi değildir." not_an_integer: "bir tamsayı değil." not_an_iso_date: "geçerli bir tarih değil. Gerekli biçim:: YYYY-AA-GG." not_same_project: "aynı projeye ait değil." odd: "tek sayı olmalı." - regex_match_failed: "does not match the regular expression %{expression}." + regex_match_failed: "%{expression} düzenli ifadesiyle eşleşmiyor." regex_invalid: "atanmış düzenli ifadeler ile doğrulanamadı." smaller_than_or_equal_to_max_length: "en fazla uzunluğa eşit veya daha küçük olmalıdır." taken: "zaten alınmıştır." @@ -957,7 +1018,7 @@ tr: custom_fields_project: attributes: project_ids: - blank: "Please select a project." + blank: "Lütfen bir proje seçin." custom_actions: only_one_allowed: "(%{name}) yalnızca bir değer verilir." empty: "(%{name}) değeri boş olamaz." @@ -1027,6 +1088,20 @@ tr: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1396,9 +1471,9 @@ tr: button_actions: "Eylemler" button_add: "Ekle" button_add_comment: "Yorum ekle" - button_add_item_above: "Add item above" - button_add_item_below: "Add item below" - button_add_sub_item: "Add sub-item" + button_add_item_above: "Öğeyi yukarıya ekle" + button_add_item_below: "Öğeyi aşağıya ekle" + button_add_sub_item: "Alt öğeyi ekle" button_add_member: Üye ekle button_add_watcher: "Takipçi ekle" button_annotate: "Atanan" @@ -1418,7 +1493,7 @@ tr: button_continue: "Devam et" button_copy: "Kopyala" button_copy_to_clipboard: "Panoya kopyala" - button_copy_link_to_clipboard: "Copy link to clipboard" + button_copy_link_to_clipboard: "Bağlantıyı panoya kopyala" button_copy_and_follow: "Kopyala ve takip et" button_create: "Oluştur" button_create_and_continue: "Oluştur ve devam et" @@ -1432,7 +1507,7 @@ tr: button_expand_all: "Tümünü genişlet" button_favorite: "Favorilere Ekle" button_filter: "Filtre" - button_finish_setup: "Finish setup" + button_finish_setup: "Kurulumu bitir" button_generate: "Üretmek" button_list: "Liste" button_lock: "Kilitle" @@ -1470,23 +1545,23 @@ tr: button_add_menu_entry: "Menü öğesi ekle" button_configure_menu_entry: "Menü öğesini düzenle" button_delete_menu_entry: "Menü öğesini sil" - button_view_shared_work_packages: "View shared work packages" - button_manage_roles: "Manage roles" - button_remove_member: "Remove member" - button_remove_member_and_shares: "Remove member and shares" - button_revoke_work_package_shares: "Revoke work package shares" - button_revoke_access: "Revoke access" - button_revoke_all: "Revoke all" - button_revoke_only: "Revoke only %{shared_role_name}" - button_publish: "Make public" - button_unpublish: "Make private" + button_view_shared_work_packages: "Baylaşılan iş paketlerinin göster" + button_manage_roles: "Görevleri yönet" + button_remove_member: "Üyeyi çıkart" + button_remove_member_and_shares: "Üye ve paylaşımlarını kaldır" + button_revoke_work_package_shares: "İş paketi paylaşımlarını iptal edin" + button_revoke_access: "Erişimi iptal et" + button_revoke_all: "Tümünü iptal et" + button_revoke_only: "Yalnızca %{shared_role_name} iptal et" + button_publish: "Herkese aç" + button_unpublish: "Özel hale getir" consent: checkbox_label: Yukarıdakilere dikkat ettim ve onay verdim. failure_message: Rıza alımı başarısız oldu, işlenemedi. title: Kullanıcı Rızası decline_warning_message: Onay vermeyi reddettiniz ve çıkış yaptınız. - user_has_consented: The user gave their consent to your [configured consent information text](consent_settings). - not_yet_consented: The user has not yet given their consent to your [configured consent information text](consent_settings). They will be reminded the next time they log in. + user_has_consented: Kullanıcı [yapılandırılmış rıza bilgisi metninize] (consent_settings) onay verdi. + not_yet_consented: Kullanıcı henüz [yapılandırılmış rıza bilgisi metninize] (consent_settings) onay vermedi. Bir sonraki girişlerinde kendisine hatırlatılacak. contact_mail_instructions: Veri değişikliği veya kaldırma isteklerini gerçekleştirmek için kullanıcıların bir veri denetleyicisine erişebilecekleri posta adresini tanımlayın. contact_your_administrator: Hesabınızın silinmesini istiyorsanız, lütfen yöneticinize başvurun. contact_this_mail_address: Hesabınızın silinmesini istiyorsanız, lütfen %{mail_address} ile iletişime geçin. @@ -1597,23 +1672,23 @@ tr: one: "1 dakika" other: "%{count} dakika" x_minutes_abbreviated: - one: "1 min" - other: "%{count} mins" + one: "1 dak" + other: "%{count} dak" x_hours: one: "1 saat" other: "%{count} saat" x_hours_abbreviated: - one: "1 hr" - other: "%{count} hrs" + one: "1 sa" + other: "%{count} sa" x_weeks: - one: "1 week" - other: "%{count} weeks" + one: "1 hafta" + other: "%{count} hafta" x_months: one: "1 ay" other: "%{count} ay" x_years: one: "1 yıl" - other: "%{count} years" + other: "%{count} yıl" x_seconds: one: "1 saniye" other: "%{count} saniye" @@ -1670,8 +1745,8 @@ tr: error_can_not_archive_project: "Bu proje arşivlenemiyor: %{errors}" error_can_not_delete_entry: "Girdi silinemiyor" error_can_not_delete_custom_field: "Özel alan silinemiyor" - error_can_not_delete_in_use_archived_undisclosed: "There are also work packages in archived projects. You need to ask an administrator to perform the deletion to see which projects are affected." - error_can_not_delete_in_use_archived_work_packages: "There are also work packages in archived projects. You need to reactivate the following projects first, before you can change the attribute of the respective work packages: %{archived_projects_urls}" + error_can_not_delete_in_use_archived_undisclosed: "Arşivlenmiş projelerde de iş paketleri var. Hangi projelerin etkilendiğini görmek için bir yöneticiden silme işlemini gerçekleştirmesini istemeniz gerekir." + error_can_not_delete_in_use_archived_work_packages: "Arşivlenen projelerde de iş paketleri var. İlgili iş paketlerinin niteliğini değiştirebilmeniz için önce aşağıdaki projeleri yeniden etkinleştirmeniz gerekir: %{archived_projects_urls}" error_can_not_delete_type: explanation: 'Bu tür iş paketleri içerir ve silinemez. Etkilenen tüm iş paketlerini bu görünümde görebilirsiniz.' error_can_not_delete_standard_type: "Standart türler silinemez." @@ -1696,7 +1771,7 @@ tr: error_pdf_failed_to_export: "PDF çıktısı kaydedilemedi: %{error}" error_token_authenticity: "Siteler Arası İstek Sahteciliği belirteci doğrulanamadı. Birden fazla tarayıcı veya sekme hakkında veri göndermeyi denediniz mi? Lütfen tüm sekmeleri kapatın ve tekrar deneyin" error_work_package_not_found_in_project: "Iş paketi bulunamadı veya bu projeye ait değil" - error_work_package_id_not_found: "The work package was not found." + error_work_package_id_not_found: "İş paketi bulunamadı." error_must_be_project_member: "projesi üyesi olmalıdır" error_migrations_are_pending: "OpenProject kurulumunuzda bekleyen veritabanı geçişleri var. Son yükseltme işleminizde geçiş işlemlerini gerçekleştirme ihtimalinizi büyük olasılıkla kaçırdınız. Lütfen kurulumunuzu uygun şekilde yükseltmek için yükseltme kılavuzunu kontrol edin." error_migrations_visit_upgrade_guides: "Lütfen yükseltme kılavuzu belgelerimizi ziyaret edin" @@ -1719,7 +1794,7 @@ tr: error_menu_item_not_saved: Menü öğesi kaydedilemez error_wiki_root_menu_item_conflict: > Var olan menü üyesi "%{existing_caption}" (%{existing_identifier}) ile çakıştığından, "%{old_name}" adı "%{new_name}" olarak değiştirilemiyor. - error_external_authentication_failed_message: "An error occurred during external authentication: %{message}" + error_external_authentication_failed_message: "Harici kimlik doğrulama sırasında bir hata oluştu: %{message}" error_attribute_not_highlightable: "Nitelikler vurgulanmıyor: %{attributes}" events: changeset: "Değişiklikler düzenlendi" @@ -1736,13 +1811,13 @@ tr: work_package_note: "İk Paketi notu eklendi" title: project: "Proje: %{name}" - subproject: "Subproject: %{name}" + subproject: "Alt-proje: %{name}" export: dialog: - title: "Export" - submit: "Export" + title: "Dışarı aktar" + submit: "Dışarı aktar" format: - label: "File format" + label: "Dosya biçimi" options: csv: label: "CSV" @@ -1751,32 +1826,32 @@ tr: xls: label: "XLS" columns: - input_label_report: "Add columns to attribute table" - input_caption_report: "By default all attributes added as columns in the work package list are selected. Long text fields are not available in the attribute table, but can be displayed below it." - input_caption_table: "By default all attributes added as columns in the work package list are selected. Long text fields are not available in table based exports." + input_label_report: "Nitelik tablosuna sütun ekle" + input_caption_report: "Varsayılan olarak, iş paketi listesine sütun olarak eklenen tüm nitelikler seçilir. Uzun metin alanları nitelik tablosunda mevcut değildir, ancak altında görüntülenebilir." + input_caption_table: "Varsayılan olarak, iş paketi listesine sütun olarak eklenen tüm nitelikler seçilir. Uzun metin alanları tablo olarak dışarı aktarımda mevcut değildir." pdf: export_type: - label: "PDF export type" + label: "PDF dışa aktarma türü" options: table: - label: "Table" - caption: "Export the work packages list in a table with the desired columns." + label: "Tablo" + caption: "İş paketleri listesini istediğiniz sütunlarla bir tablo halinde dışa aktarın." report: - label: "Report" - caption: "Export the work package on a detailed report of all work packages in the list." + label: "Rapor" + caption: "Listedeki tüm iş paketlerini içeren ayrıntılı bir rapor olarak iş paketini dışa aktarın." gantt: - label: "Gantt chart" - caption: "Export the work packages list in a Gantt diagram view." + label: "Gantt grafiği" + caption: "İş paketleri listesini bir Gantt diyagramı görünümünde dışa aktarın." include_images: - label: "Include images" - caption: "Exclude images to reduce the size of the PDF export." + label: "Görüntüleri dahil et" + caption: "PDF boyutunu küçültmek için görüntüleri hariç tutun." gantt_zoom_levels: - label: "Zoom levels" - caption: "Select what is the zoom level for dates displayed in the chart." + label: "Yakınlaştırma düzeyi" + caption: "Grafikte görüntülenen tarihler için yakınlaştırma düzeyinin ne olduğunu seçin." options: - days: "Days" - weeks: "Weeks" - months: "Months" + days: "Gün" + weeks: "Hafta" + months: "Ay" quarters: "Quarters" column_width: label: "Table column width" @@ -1822,6 +1897,23 @@ tr: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext kullanılabilir (isteğe bağlı)" @@ -2180,6 +2272,7 @@ tr: label_environment: "Ortam" label_estimates_and_progress: "Estimates and progress" label_equals: "şuysa" + label_equals_with_descendants: "is any with descendants" label_everywhere: "heryer" label_example: "Örnek" label_experimental: "Deneysel" @@ -2444,6 +2537,8 @@ tr: label_related_work_packages: "İlişkili iş paketleri" label_relates: "ile ilişkili" label_relates_to: "ile ilişkili" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "İlişkiyi sil" label_relation_new: "Yeni ilişki" label_release_notes: "Sürüm notları" @@ -3593,7 +3688,7 @@ tr: status_user_and_brute_force: "%{user} ve %{brute_force}" status_change: "Durum değişikliği" text_change_disabled_for_provider_login: "Ad, giriş sağlayıcınız tarafından belirlenir ve bu nedenle değiştirilemez." - text_change_disabled_for_ldap_login: "The name and email is set by LDAP and can thus not be changed." + text_change_disabled_for_ldap_login: "İsim ve e-posta LDAP tarafından belirlenir ve bu nedenle değiştirilemez." unlock: "Kilidi kaldır" unlock_and_reset_failed_logins: "Başarısız oturum açma işlemlerinin kilidini aç ve sıfırla" version_status_closed: "kapalı" diff --git a/config/locales/crowdin/uk.seeders.yml b/config/locales/crowdin/uk.seeders.yml index f3280179825e..cf35404eb4d4 100644 --- a/config/locales/crowdin/uk.seeders.yml +++ b/config/locales/crowdin/uk.seeders.yml @@ -34,6 +34,17 @@ uk: name: Сірий (темний) item_13: name: Чорний + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Документація @@ -70,6 +81,21 @@ uk: item_1: name: Стандартна глобальна роль standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Низький diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml index 194af11293a7..9e32422cd338 100644 --- a/config/locales/crowdin/uk.yml +++ b/config/locales/crowdin/uk.yml @@ -33,13 +33,13 @@ uk: label_activity_show_only_changes: "Показувати лише зміни" label_sort_asc: "Найновіші внизу" label_sort_desc: "Найновіші вгорі" - label_type_to_comment: "Місце для коментаря" + label_type_to_comment: "Додайте коментар. Введіть @, щоб сповістити людину." label_submit_comment: "Надіслати коментар" changed_on: "змінено" created_on: "створив(-ла)" - changed: "змінено" - created: "створено" - commented: "прокоментовано" + changed: "змінив(-ла)" + created: "створив(-ла)" + commented: "прокоментував(-ла)" admin: plugins: no_results_title_text: Зараз немає встановлених плагінів. @@ -234,6 +234,8 @@ uk: zero: немає піделементів one: 1 піделемент other: "Піделементів: %{count}" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Щоб додати нові користувальницькі поля до проекту, спочатку потрібно створити їх, перш ніж ви зможете додати їх до цього проекту. is_enabled_globally: "Увімкнено у всьому світі" @@ -260,20 +262,20 @@ uk: single: "або" dry_validation: errors: - integer?: "має бути цілим числом" - filled?: "має бути заповнено" - greater_or_equal_zero: "має дорівнювати нулю або перевищувати його" - not_found: "не знайдено" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "не може бути кореневим елементом" - not_persisted: "має бути вже наявним елементом" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "має бути унікальним у межах одного рівня ієрархії" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "має бути унікальним у межах одного рівня ієрархії" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "має бути дочірнім елементом кореня ієрархії" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Глибина" item: "Елемент" @@ -641,6 +643,66 @@ uk: no_results_title_text: Наразі немає доступних типів. version: no_results_title_text: Наразі немає доступних версій. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Запрошення account: delete: "Видалити обліковий запис" @@ -1037,6 +1099,20 @@ uk: attributes: project_ids: blank: "Виберіть проєкт." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1888,6 +1964,23 @@ uk: units: hours: г days: д + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Доступний текст PDF (необов'язково)" @@ -2246,6 +2339,7 @@ uk: label_environment: "Навколишнє середовище" label_estimates_and_progress: "Оцінки й прогрес виконання" label_equals: "є" + label_equals_with_descendants: "is any with descendants" label_everywhere: "скрізь" label_example: "Приклад" label_experimental: "Експериментальне" @@ -2510,6 +2604,8 @@ uk: label_related_work_packages: "Пов'язані робочі пакети" label_relates: "пов'язані з" label_relates_to: "пов'язані з" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Видалити зв'язок" label_relation_new: "Новий зв'язок" label_release_notes: "Примітки до випуску" diff --git a/config/locales/crowdin/uz.seeders.yml b/config/locales/crowdin/uz.seeders.yml index fe9f16ab84d9..b12e7a405d2e 100644 --- a/config/locales/crowdin/uz.seeders.yml +++ b/config/locales/crowdin/uz.seeders.yml @@ -34,6 +34,17 @@ uz: name: Grey (dark) item_13: name: Black + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Documentation @@ -70,6 +81,21 @@ uz: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Low diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml index d8f1709f3f16..57b15c854d3b 100644 --- a/config/locales/crowdin/uz.yml +++ b/config/locales/crowdin/uz.yml @@ -33,7 +33,7 @@ uz: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -239,6 +239,8 @@ uz: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" 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. is_enabled_globally: "Is enabled globally" @@ -265,20 +267,20 @@ uz: single: "or" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -632,6 +634,66 @@ uz: no_results_title_text: There are currently no types available. version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Invitation account: delete: "Delete account" @@ -1028,6 +1090,20 @@ uz: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1823,6 +1899,23 @@ uz: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext available (optional)" @@ -2181,6 +2274,7 @@ uz: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2445,6 +2539,8 @@ uz: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" diff --git a/config/locales/crowdin/vi.seeders.yml b/config/locales/crowdin/vi.seeders.yml index 22c8e1f32d79..56e1077cc7ba 100644 --- a/config/locales/crowdin/vi.seeders.yml +++ b/config/locales/crowdin/vi.seeders.yml @@ -34,6 +34,17 @@ vi: name: Xám (tối) item_13: name: Đen + life_cycle_colors: + item_0: + name: PM2 Orange + item_1: + name: PM2 Purple + item_2: + name: PM2 Red + item_3: + name: PM2 Magenta + item_4: + name: PM2 Green Yellow document_categories: item_0: name: Tài liệu @@ -70,6 +81,21 @@ vi: item_1: name: Standard global role standard: + life_cycles: + item_0: + name: Initiating + item_1: + name: Ready for Planning + item_2: + name: Planning + item_3: + name: Ready for Executing + item_4: + name: Executing + item_5: + name: Ready for Closing + item_6: + name: Closing priorities: item_0: name: Thấp diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml index 7dfec8efa781..54de24adfb31 100644 --- a/config/locales/crowdin/vi.yml +++ b/config/locales/crowdin/vi.yml @@ -33,7 +33,7 @@ vi: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -241,6 +241,8 @@ vi: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > Để thêm các trường tùy chỉnh mới vào một dự án, trước tiên bạn cần tạo chúng trước khi có thể thêm vào dự án này. is_enabled_globally: "Được bật toàn cầu" @@ -267,20 +269,20 @@ vi: single: "hoặc" dry_validation: errors: - integer?: "must be an integer" - filled?: "must be filled" - greater_or_equal_zero: "must be greater or equal to 0" - not_found: "not found" + int?: "must be an integer." + filled?: "must be filled." + greater_or_equal_zero: "must be greater or equal to 0." + not_found: "not found." rules: item: - root_item: "cannot be a root item" - not_persisted: "must be an already existing item" + root_item: "cannot be a root item." + not_persisted: "must be an already existing item." label: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." short: - not_unique: "must be unique within the same hierarchy level" + not_unique: "must be unique within the same hierarchy level." parent: - not_descendant: "must be a descendant of the hierarchy root" + not_descendant: "must be a descendant of the hierarchy root." rules: depth: "Depth" item: "Item" @@ -626,6 +628,66 @@ vi: no_results_title_text: Hiện tại không có loại nào có sẵn. version: no_results_title_text: Hiện tại không sẵn có phiên bản nào. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + label_parent_singular: "parent" + label_parent_plural: "parent" label_invitation: Thư mời account: delete: "Xoá tài khoản" @@ -1022,6 +1084,20 @@ vi: attributes: project_ids: blank: "Vui lòng chọn một dự án." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1789,6 +1865,23 @@ vi: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: pdftotext: "Pdftotext có sẵn (không bắt buộc)" @@ -2147,6 +2240,7 @@ vi: label_environment: "Môi trường" label_estimates_and_progress: "Ước lượng và tiến độ" label_equals: "là" + label_equals_with_descendants: "is any with descendants" label_everywhere: "mọi nơi" label_example: "Ví dụ" label_experimental: "Thử nghiệm" @@ -2411,6 +2505,8 @@ vi: label_related_work_packages: "Work package liên quan" label_relates: "liên quan đến" label_relates_to: "liên quan đến" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Xóa quan hệ" label_relation_new: "Quan hệ mới" label_release_notes: "Ghi chú phát hành" diff --git a/config/locales/crowdin/zh-CN.seeders.yml b/config/locales/crowdin/zh-CN.seeders.yml index f1d465d015fe..ddc400fa4b41 100644 --- a/config/locales/crowdin/zh-CN.seeders.yml +++ b/config/locales/crowdin/zh-CN.seeders.yml @@ -34,6 +34,17 @@ zh-CN: name: 灰色(深) item_13: name: 黑色 + life_cycle_colors: + item_0: + name: PM2 橙色 + item_1: + name: PM2 紫色 + item_2: + name: PM2 红色 + item_3: + name: PM2 品红 + item_4: + name: PM2 绿黄 document_categories: item_0: name: 文档 @@ -70,6 +81,21 @@ zh-CN: item_1: name: 默认全局角色 standard: + life_cycles: + item_0: + name: 正在启动 + item_1: + name: 准备计划 + item_2: + name: 计划中 + item_3: + name: 准备执行 + item_4: + name: 执行中 + item_5: + name: 准备关闭 + item_6: + name: 关闭中 priorities: item_0: name: 低 diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml index 034b70d6eb71..4224afbc7d15 100644 --- a/config/locales/crowdin/zh-CN.yml +++ b/config/locales/crowdin/zh-CN.yml @@ -33,7 +33,7 @@ zh-CN: label_activity_show_only_changes: "仅显示更改" label_sort_asc: "时间升序" label_sort_desc: "时间降序" - label_type_to_comment: "在此输入评论" + label_type_to_comment: "添加评论。输入 @ 以通知他人。" label_submit_comment: "提交评论" changed_on: "更改于" created_on: "创建于" @@ -236,6 +236,8 @@ zh-CN: zero: 无子项目 one: 1个子项目 other: "%{count} 个子项目" + upsale: + custom_field_format_hierarchy: "工作包的自定义字段需要层级结构?" text_add_new_custom_field: > 要向项目添加新的自定义字段,您需要先创建字段,然后才能将其添加到此项目中。 is_enabled_globally: "已全局启用" @@ -262,7 +264,7 @@ zh-CN: single: "或" dry_validation: errors: - integer?: "必须是整数" + int?: "必须为整数" filled?: "必须填写" greater_or_equal_zero: "必须大于或等于 0" not_found: "未找到" @@ -619,6 +621,66 @@ zh-CN: no_results_title_text: 目前有可用的类型。 version: no_results_title_text: 目前有可用的版本。 + work_package_relations_tab: + index: + action_bar_title: "将关系添加到其他工作包以创建它们之间的链接。" + no_results_title_text: 目前没有任何关系。 + blankslate_heading: "没有关系" + blankslate_description: "此工作包还没有任何关系。" + label_add_x: "添加 %{x}" + label_edit_x: "编辑 %{x}" + label_add_description: "添加说明" + relations: + label_relates_singular: "关联到" + label_relates_plural: "关联到" + label_relates_to_singular: "关联到" + label_relates_to_plural: "关联到" + relates_description: "在两个工作包之间建立一个可见的链接,不产生额外效果" + relates_to_description: "在两个工作包之间建立一个可见的链接,不产生额外效果" + label_precedes_singular: "继承者(以后)" + label_precedes_plural: "继承者(以后)" + precedes_description: "相关的工作包必然需要在这个完成后启动" + label_follows_singular: "前任(之前)" + label_follows_plural: "前任(之前)" + follows_description: "相关工作包必须在本工作包启动前完成" + label_child_singular: "子节点" + label_child_plural: "子节点" + child_description: "使相关工作包成为当前(父) 工作包的子项目" + label_blocks_singular: "阻止" + label_blocks_plural: "阻止" + blocks_description: "在本工作包结束之前,相关工作包不能关闭" + label_blocked_singular: "被阻止" + label_blocked_plural: "被阻止" + label_blocked_by_singular: "被阻止" + label_blocked__by_plural: "被阻止" + blocked_description: "在本工作包结束之前,相关工作包不能关闭" + blocked_by_description: "在本工作包结束之前,相关工作包不能关闭" + label_duplicates_singular: "复制" + label_duplicates_plural: "复制" + duplicates_description: "这是相关工作包的副本" + label_duplicated_singular: "复制于" + label_duplicated_plural: "复制于" + label_duplicated_by_singular: "复制于" + label_duplicated_by_plural: "复制于" + duplicated_by_description: "相关的工作包是这个副本的" + duplicated_description: "相关的工作包是这个副本的" + label_includes_singular: "包括" + label_includes_plural: "包括" + includes_description: "将相关工作包标记为包括本工作包,不产生额外效果" + label_partof_singular: "隶属于" + label_partof_plural: "隶属于" + label_part_of_singular: "隶属于" + label_part_of_plural: "隶属于" + partof_description: "将相关工作包标记为包括本工作包,不产生额外效果" + part_of_description: "将相关工作包标记为包括本工作包,不产生额外效果" + label_requires_singular: "需求" + label_requires_plural: "需求" + requires_description: "将相关工作包标记为该工作包的需求" + label_required_singular: "需求于" + label_required_plural: "需求于" + required_description: "将此工作包标记为相关工作包的需求" + label_parent_singular: "父级" + label_parent_plural: "父级" label_invitation: 邀请 account: delete: "删除帐户" @@ -1015,6 +1077,20 @@ zh-CN: attributes: project_ids: blank: "请选择一个项目。" + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "必须是 Project::StageDefinition 或 Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "必须是 Project::Stage 或 Project::Gate" + must_be_a_stage: "必须是 Project::Stage" + must_be_a_gate: "必须是 Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "无法将 `end_date` 分配给一个项目::Gate" query: attributes: project: @@ -1782,6 +1858,23 @@ zh-CN: units: hours: 时 days: 天 + pdf_generator: + page_nr_footer: "第 %{page} 页,共%{total} 页" + dialog: + title: 生成 PDF + submit: 生成 + header_right: + label: 页眉右侧 + caption: 标题右侧显示的文本 + footer_center: + label: 页脚中心 + caption: 在页脚中心显示的文本 + hyphenation: + label: 断字 + caption: 在行之间打断单词,以改进文本解释和可读性。 + paper_size: + label: 纸张大小 + caption: 用于PDF的纸张大小。 extraction: available: pdftotext: "Pdftotext 可用 (可选)" @@ -2140,6 +2233,7 @@ zh-CN: label_environment: "环境" label_estimates_and_progress: "预估和进度" label_equals: "是" + label_equals_with_descendants: "是任何与子节点相关的" label_everywhere: "任何位置" label_example: "示例" label_experimental: "实验" @@ -2404,6 +2498,8 @@ zh-CN: label_related_work_packages: "相关的工作包" label_relates: "关于" label_relates_to: "关于" + label_relation: "关系" + label_relation_actions: "关联操作" label_relation_delete: "删除关系" label_relation_new: "新的关系" label_release_notes: "更新日志" diff --git a/config/locales/crowdin/zh-TW.seeders.yml b/config/locales/crowdin/zh-TW.seeders.yml index f1d57fe537a1..cd67529e5141 100644 --- a/config/locales/crowdin/zh-TW.seeders.yml +++ b/config/locales/crowdin/zh-TW.seeders.yml @@ -34,6 +34,17 @@ zh-TW: name: 灰色 (深) item_13: name: 黑色 + life_cycle_colors: + item_0: + name: PM2 橙色 + item_1: + name: PM2 紫色 + item_2: + name: PM2 紅色 + item_3: + name: PM2 紅紫色 + item_4: + name: PM2 黃綠色 document_categories: item_0: name: 說明文件 @@ -70,6 +81,21 @@ zh-TW: item_1: name: 標準全域角色 standard: + life_cycles: + item_0: + name: 初始化中 + item_1: + name: 準備規劃 + item_2: + name: 計劃中 + item_3: + name: 準備執行 + item_4: + name: 執行 + item_5: + name: 準備關閉 + item_6: + name: 正在關閉 priorities: item_0: name: 低 diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml index a1ff27764455..e4050a26a0c6 100644 --- a/config/locales/crowdin/zh-TW.yml +++ b/config/locales/crowdin/zh-TW.yml @@ -33,7 +33,7 @@ zh-TW: label_activity_show_only_changes: "僅顯示差異" label_sort_asc: "最新的在最下面" label_sort_desc: "最新的在最上面" - label_type_to_comment: "在此留言" + label_type_to_comment: "留言。輸入 @ 來通知他人。" label_submit_comment: "留言" changed_on: "異動於" created_on: "新增於" @@ -238,6 +238,8 @@ zh-TW: zero: 無子項目 one: 1 個子項目 other: "%{count} 子項目" + upsale: + custom_field_format_hierarchy: "工作項目的自訂欄位需要分層嗎?" text_add_new_custom_field: > 要加入客製欄位至一個專案,您必須先建立欄位才能將它們加入至此專案。 is_enabled_globally: "已全域啟用" @@ -264,7 +266,7 @@ zh-TW: single: "或者" dry_validation: errors: - integer?: "必須是整數" + int?: "必須是整數" filled?: "必填" greater_or_equal_zero: "必須大於或等於 0" not_found: "未找到" @@ -273,11 +275,11 @@ zh-TW: root_item: "不能為根項目" not_persisted: "必須是已存在的項目" label: - not_unique: "在同一層級內必須唯一" + not_unique: "在同一階層內必須唯一" short: not_unique: "在同一階層內必須唯一" parent: - not_descendant: "必須是階層根的展開的" + not_descendant: "必須是層級展開的" rules: depth: "深度" item: "項目" @@ -621,6 +623,66 @@ zh-TW: no_results_title_text: 目前沒有可用的類型 version: no_results_title_text: 目前沒有可用的版本 + work_package_relations_tab: + index: + action_bar_title: "新增關係至其他工作項目,以建立它們之間的連結。" + no_results_title_text: 目前沒有相關工作項目 + blankslate_heading: "沒有關聯" + blankslate_description: "此工作項目尚未建立任何關係。" + label_add_x: "新增 %{x}" + label_edit_x: "編輯:%{x}" + label_add_description: "新增說明" + relations: + label_relates_singular: "相關於" + label_relates_plural: "相關於" + label_relates_to_singular: "相關於" + label_relates_to_plural: "相關於" + relates_description: "在兩個工作項目之間建立可見的連結,沒有額外影響" + relates_to_description: "在兩個工作項目之間建立可見的連結,沒有額外影響" + label_precedes_singular: "繼承(後)" + label_precedes_plural: "繼承(後)" + precedes_description: "相關的工作項目必須在完成後才開始執行" + label_follows_singular: "繼承(前)" + label_follows_plural: "繼承(前)" + follows_description: "在這個工作項目開始之前,相關的工作必須先完成" + label_child_singular: "子項目" + label_child_plural: "子項目" + child_description: "使相關工作項目成為目前(父)工作子項目" + label_blocks_singular: "區塊" + label_blocks_plural: "區塊" + blocks_description: "在本工作項目結束之前,關聯工作無法結束" + label_blocked_singular: "標示禁止" + label_blocked_plural: "標示禁止" + label_blocked_by_singular: "標示禁止" + label_blocked__by_plural: "標示禁止" + blocked_description: "在關聯工作項目先結束之前,此工作無法結束" + blocked_by_description: "在關聯工作項目先結束之前,此工作無法結束" + label_duplicates_singular: "重複" + label_duplicates_plural: "重複" + duplicates_description: "這是關聯工作項目的複本" + label_duplicated_singular: "重複於" + label_duplicated_plural: "重複於" + label_duplicated_by_singular: "重複於" + label_duplicated_by_plural: "重複於" + duplicated_by_description: "關聯工作項目於此複製" + duplicated_description: "關聯工作項目於此複製" + label_includes_singular: "包括" + label_includes_plural: "包括" + includes_description: "將關聯工作標示包含此工作項目,但無額外影響" + label_partof_singular: "部份於" + label_partof_plural: "部份於" + label_part_of_singular: "部份於" + label_part_of_plural: "部份於" + partof_description: "將相關工作項目標示為此工作一部分,但無額外影響" + part_of_description: "將相關工作項目標示為此工作一部分,但無額外影響" + label_requires_singular: "需要" + label_requires_plural: "需要" + requires_description: "將關聯工作項目標示為此工作套件的需求" + label_required_singular: "要求由" + label_required_plural: "要求由" + required_description: "將此工作項目標示為相關工作的需求" + label_parent_singular: "上層" + label_parent_plural: "上層" label_invitation: 邀請 account: delete: "刪除帳號" @@ -1017,6 +1079,20 @@ zh-TW: attributes: project_ids: blank: "請選擇一個專案" + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "" + must_be_a_stage: "" + must_be_a_gate: "必須是 Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "無法指定 `end_date` 到 Project::Gate" query: attributes: project: @@ -1291,7 +1367,7 @@ zh-TW: assigned_to: "執行者" assignee: "執行者" attachments: "附加檔" - author: "作者" + author: "工作項目發起者" base: "一般錯誤:" blocks_ids: "已被限制的工作項目 IDs" category: "類別" @@ -1784,6 +1860,23 @@ zh-TW: units: hours: 小時 days: 日 + pdf_generator: + page_nr_footer: "頁面 %{page} of %{total}" + dialog: + title: 產生PDF檔案 + submit: 產生 + header_right: + label: 標題右側 + caption: 要顯示在標頭右側的文字 + footer_center: + label: 頁尾中心 + caption: 要顯示在頁尾中央的文字 + hyphenation: + label: 連字符 + caption: 在行與行之間分隔字詞,以改善文字的正確性和可讀性。 + paper_size: + label: 紙張大小 + caption: PDF 要使用的紙張尺寸。 extraction: available: pdftotext: "Pdftotext 可用 (非必要)" @@ -2142,6 +2235,7 @@ zh-TW: label_environment: "環境" label_estimates_and_progress: "預估和進度" label_equals: "是" + label_equals_with_descendants: "任何子項目" label_everywhere: "全部" label_example: "範例" label_experimental: "實驗性" @@ -2406,6 +2500,8 @@ zh-TW: label_related_work_packages: "相關的工作項目" label_relates: "相關於" label_relates_to: "相關於" + label_relation: "關聯" + label_relation_actions: "關聯動作" label_relation_delete: "刪除關聯" label_relation_new: "新增關聯" label_release_notes: "發行說明" diff --git a/config/locales/en.yml b/config/locales/en.yml index 008c15973abf..354204222c66 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -41,7 +41,7 @@ en: label_activity_show_only_changes: "Show changes only" label_sort_asc: "Newest at the bottom" label_sort_desc: "Newest on top" - label_type_to_comment: "Type here to comment" + label_type_to_comment: "Add a comment. Type @ to notify people." label_submit_comment: "Submit comment" changed_on: "changed on" created_on: "created this on" @@ -263,6 +263,8 @@ en: zero: no sub-items one: 1 sub-item other: "%{count} sub-items" + upsale: + custom_field_format_hierarchy: "Need a hierarchy in your custom fields for work packages?" text_add_new_custom_field: > To add new custom fields to a project you first need to create them before @@ -705,6 +707,72 @@ en: version: no_results_title_text: There are currently no versions available. + work_package_relations_tab: + index: + action_bar_title: "Add relations to other work packages to create a link between them." + no_results_title_text: There are currently no relations available. + blankslate_heading: "No relations" + blankslate_description: "This work package does not have any relations yet." + label_add_x: "Add %{x}" + label_edit_x: "Edit %{x}" + label_add_description: "Add description" + lag: + subject: "Lag" + title: "Lag (in days)" + caption: "The gap in number of working days in between the two work packages" + relations: + label_relates_singular: "related to" + label_relates_plural: "related to" + label_relates_to_singular: "related to" + label_relates_to_plural: "related to" + relates_description: "Creates a visible link between the two work packages with no additional effect" + relates_to_description: "Creates a visible link between the two work packages with no additional effect" + label_precedes_singular: "successor (after)" + label_precedes_plural: "successors (after)" + precedes_description: "The related work package necessarily needs to start after this one finishes" + label_follows_singular: "predecessor (before)" + label_follows_plural: "predecessors (before)" + follows_description: "The related work package necessarily needs to finish before this one can start" + label_child_singular: "child" + label_child_plural: "children" + child_description: "Makes the related a work package a sub-item of the current (parent) work package" + label_blocks_singular: "blocks" + label_blocks_plural: "blocks" + blocks_description: "The related work package cannot be closed until this one is closed first" + label_blocked_singular: "blocked by" + label_blocked_plural: "blocked by" + label_blocked_by_singular: "blocked by" + label_blocked__by_plural: "blocked by" + blocked_description: "This work package cannot be closed until the related one is closed first" + blocked_by_description: "This work package cannot be closed until the related one is closed first" + label_duplicates_singular: "duplicates" + label_duplicates_plural: "duplicates" + duplicates_description: "This is a copy of the related work package" + label_duplicated_singular: "duplicated by" + label_duplicated_plural: "duplicated by" + label_duplicated_by_singular: "duplicated by" + label_duplicated_by_plural: "duplicated by" + duplicated_by_description: "The related work package is a copy of this" + duplicated_description: "The related work package is a copy of this" + label_includes_singular: "includes" + label_includes_plural: "includes" + includes_description: "Marks the related work package as including this one with no additional effect" + label_partof_singular: "part of" + label_partof_plural: "part of" + label_part_of_singular: "part of" + label_part_of_plural: "part of" + partof_description: "Marks the related work package as being part of this one with no additional effect" + part_of_description: "Marks the related work package as being part of this one with no additional effect" + label_requires_singular: "requires" + label_requires_plural: "requires" + requires_description: "Marks the related work package as a requirement to this one" + label_required_singular: "required by" + label_required_plural: "required by" + required_description: "Marks this work package as being a requirement to the related one" + + label_parent_singular: "parent" + label_parent_plural: "parent" + label_invitation: Invitation account: delete: "Delete account" @@ -1108,6 +1176,20 @@ en: attributes: project_ids: blank: "Please select a project." + project/life_cycle_step_definition: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::StageDefinition or Project::GateDefinition" + project/life_cycle_step: + attributes: + type: + must_be_a_stage_or_gate: "must be either Project::Stage or Project::Gate" + must_be_a_stage: "must be a Project::Stage" + must_be_a_gate: "must be a Project::Gate" + project/gate: + attributes: + base: + end_date_not_allowed: "Cannot assign `end_date` to a Project::Gate" query: attributes: project: @@ -1605,7 +1687,7 @@ en: create_new_page: "Wiki page" date: - abbr_day_names: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ] + abbr_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] abbr_month_names: [ ~, @@ -1931,6 +2013,23 @@ en: units: hours: h days: d + pdf_generator: + page_nr_footer: "Page %{page} of %{total}" + dialog: + title: Generate PDF + submit: Generate + header_right: + label: Header right + caption: Text to be displayed in the right of the header + footer_center: + label: Footer center + caption: Text to be displayed in the center of the footer + hyphenation: + label: Hyphenation + caption: Break words between lines to improve text justification and readability. + paper_size: + label: Paper size + caption: The size of the paper to use for the PDF. extraction: available: @@ -2303,6 +2402,7 @@ en: label_environment: "Environment" label_estimates_and_progress: "Estimates and progress" label_equals: "is" + label_equals_with_descendants: "is any with descendants" label_everywhere: "everywhere" label_example: "Example" label_experimental: "Experimental" @@ -2567,6 +2667,8 @@ en: label_related_work_packages: "Related work packages" label_relates: "related to" label_relates_to: "related to" + label_relation: "Relation" + label_relation_actions: "Relation actions" label_relation_delete: "Delete relation" label_relation_new: "New relation" label_release_notes: "Release notes" @@ -3490,7 +3592,7 @@ en: If this option is active, login requests will redirect to the configured omniauth provider. The login dropdown and sign-in page will be disabled.
- Note: Unless you also disable password logins, with this option enabled, + Note: Unless you also disable password logins, with this option enabled, users can still log in internally by visiting the %{internal_path} login page. attachments: whitelist_text_html: > diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index 322eeb3246f7..761b7a5153c6 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -122,6 +122,7 @@ en: button_update: "Update" button_export-pdf: "Download PDF" button_export-atom: "Download Atom" + button_generate_pdf: "Generate PDF" button_create: "Create" card: @@ -399,18 +400,16 @@ en: learn_about: "Learn more about the new features" # Include the version to invalidate outdated translations in other locales. # Otherwise, e.g. chinese might still have the translations for 10.0 in the 12.0 release. - "15_0": + "15_1": standard: new_features_html: > The release brings various features and improvements for you, e.g.
    -
  • Boost your communication with a better structured Activity tab, real-time loading messages and notifications, emoji reactions, and more.
  • -
  • Benefit from easy Single Sign-On authentication settings with SAML and OIDC in your Enterprise Cloud administration.
  • -
  • Use the new 'Standard global role' and enable permissions to view email addresses.
  • -
  • Enjoy easier navigation in project lists with quick action table headers.
  • -
  • Experience simplified design settings with fewer sidebar design variables needed.
  • -
  • Reduce manual cleanup when adding a custom field to a type – no more auto-applying to all projects.
  • -
  • Benefit from improved navigation clarity – 'My account' is renamed to 'Account settings'.
  • +
  • Custom fields of type hierarchy (Enterprise add-on).
  • +
  • Redesign of the Relations tab in work packages.
  • +
  • Redesign of the Meetings index page.
  • +
  • Manual page breaks in PDF work package exports.
  • +
  • Zen mode for project lists.
ical_sharing_modal: @@ -631,7 +630,7 @@ en: members: "Invite new members to join your project." quick_add_button: "Click on the plus (+) icon in the header navigation to create a new project or to invite coworkers." sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu." - welcome: "Take a three minutes introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." + welcome: "Take a three-minute introduction tour to learn the most important features.
We recommend completing the steps until the end. You can restart the tour any time." wiki: "Within the wiki you can document and share knowledge together with your team." backlogs: overview: "Manage your work in the backlogs view." diff --git a/config/routes.rb b/config/routes.rb index 02699c025748..158ed8a6a293 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -574,6 +574,9 @@ get "hover_card" => "work_packages/hover_card#show", on: :member + get "generate_pdf_dialog" => "work_packages#generate_pdf_dialog", on: :member + post "generate_pdf" => "work_packages#generate_pdf", on: :member + # move bulk of wps get "move/new" => "work_packages/moves#new", on: :collection, as: "new_move" post "move" => "work_packages/moves#create", on: :collection, as: "move" @@ -595,6 +598,8 @@ end end + resources :children, only: %i[new create destroy], controller: "work_package_children" + resource :progress, only: %i[new edit update], controller: "work_packages/progress" collection do resource :progress, @@ -602,6 +607,9 @@ controller: "work_packages/progress", as: :work_package_progress end + resources :relations_tab, only: %i[index], controller: "work_package_relations_tab" + resources :relations, only: %i[new create edit update destroy], controller: "work_package_relations" + get "/export_dialog" => "work_packages#export_dialog", on: :collection, as: "export_dialog" get :show_conflict_flash_message, on: :collection # we don't need a specific work package for this diff --git a/db/migrate/20241030154245_create_project_life_cycles.rb b/db/migrate/20241030154245_create_project_life_cycles.rb new file mode 100644 index 000000000000..e3c28014eb1a --- /dev/null +++ b/db/migrate/20241030154245_create_project_life_cycles.rb @@ -0,0 +1,53 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class CreateProjectLifeCycles < ActiveRecord::Migration[7.1] + def change + create_table :project_life_cycle_step_definitions do |t| + t.string :type + t.string :name + t.integer :position, null: true + t.references :color, foreign_key: true + + t.timestamps + end + + create_table :project_life_cycle_steps do |t| + t.string :type + t.date :start_date + t.date :end_date + t.boolean :active, default: false, null: false + t.references :project, foreign_key: true + t.references :definition, foreign_key: { to_table: :project_life_cycle_step_definitions } + + t.timestamps + end + + add_reference :work_packages, :project_life_cycle_step, null: true + end +end diff --git a/db/migrate/20241120103858_add_start_end_times_to_time_entries.rb b/db/migrate/20241120103858_add_start_end_times_to_time_entries.rb new file mode 100644 index 000000000000..4d30710e517e --- /dev/null +++ b/db/migrate/20241120103858_add_start_end_times_to_time_entries.rb @@ -0,0 +1,13 @@ +class AddStartEndTimesToTimeEntries < ActiveRecord::Migration[7.1] + def change + change_table :time_entries, bulk: true do |t| + t.integer :start_time, null: true + t.integer :end_time, null: true + end + + change_table :time_entry_journals, bulk: true do |t| + t.integer :start_time, null: true + t.integer :end_time, null: true + end + end +end diff --git a/db/migrate/20241121094113_migrate_cost_settings_to_regular_settings.rb b/db/migrate/20241121094113_migrate_cost_settings_to_regular_settings.rb new file mode 100644 index 000000000000..7d1c1a4b8710 --- /dev/null +++ b/db/migrate/20241121094113_migrate_cost_settings_to_regular_settings.rb @@ -0,0 +1,24 @@ +class MigrateCostSettingsToRegularSettings < ActiveRecord::Migration[7.1] + def up + costs_settings = Setting.plugin_costs || {} + if costs_settings["costs_currency"] + Setting.create(name: "costs_currency", value: costs_settings["costs_currency"]) + end + + if costs_settings["costs_currency_format"] + Setting.create(name: "costs_currency_format", value: costs_settings["costs_currency_format"]) + end + + Setting.where(name: "plugin_costs").destroy_all + end + + def down + costs_settings = { + "costs_currency" => Setting.costs_currency, + "costs_currency_format" => Setting.costs_currency_format + } + + Setting.create(name: "plugin_costs", value: costs_settings) + Setting.where(name: ["costs_currency", "costs_currency_format"]).destroy_all + end +end diff --git a/db/migrate/20241125104347_add_timezone_identifier_to_time_entry.rb b/db/migrate/20241125104347_add_timezone_identifier_to_time_entry.rb new file mode 100644 index 000000000000..b75120ef873e --- /dev/null +++ b/db/migrate/20241125104347_add_timezone_identifier_to_time_entry.rb @@ -0,0 +1,13 @@ +class AddTimezoneIdentifierToTimeEntry < ActiveRecord::Migration[7.1] + def change + change_table :time_entries, bulk: true do |t| + t.string :time_zone, null: true + t.remove :end_time, type: :integer + end + + change_table :time_entry_journals, bulk: true do |t| + t.string :time_zone, null: true + t.remove :end_time, type: :integer + end + end +end diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 42913e5e1945..3ebc3d750387 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -14,7 +14,7 @@ services: - RUBY_VERSION environment: CI_JOBS: "${CI_JOBS}" - RSPEC_RETRY_RETRY_COUNT: "${CI_RETRY_COUNT:-3}" + RSPEC_RETRY_RETRY_COUNT: "${CI_RETRY_COUNT:-4}" CAPYBARA_AWS_ACCESS_KEY_ID: "${CAPYBARA_AWS_ACCESS_KEY_ID}" CAPYBARA_AWS_SECRET_ACCESS_KEY: "${CAPYBARA_AWS_SECRET_ACCESS_KEY}" tmpfs: diff --git a/docker/dev/backend/Dockerfile b/docker/dev/backend/Dockerfile index 9fe6fc7594a4..d1e2b2f9422f 100644 --- a/docker/dev/backend/Dockerfile +++ b/docker/dev/backend/Dockerfile @@ -34,17 +34,6 @@ RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesourc RUN apt-get update RUN apt-get install -y nodejs -# Install watchexec for continuous test execution. -# Usage: -# - Add the following line to your ~/.bashrc ("dcrw" stands for "Docker Compose Rspec Watch"): -# dcrw() { docker compose exec backend-test watchexec --exts rb,erb -- bin/rspec --order defined --format documentation --fail-fast $1; } -# - and then use it like this: -# dcrw -RUN curl -fsSL https://apt.cli.rs/pubkey.asc | tee -a /usr/share/keyrings/rust-tools.asc -RUN curl -fsSL https://apt.cli.rs/rust-tools.list | tee /etc/apt/sources.list.d/rust-tools.list -RUN apt update -RUN apt install watchexec-cli - COPY ./docker/dev/backend/scripts/setup /usr/sbin/setup COPY ./docker/dev/backend/scripts/setup-bim /usr/sbin/setup-bim COPY ./docker/dev/backend/scripts/run-app /usr/sbin/run-app diff --git a/docker/dev/backend/scripts/setup-bim b/docker/dev/backend/scripts/setup-bim index 4ec396b503a2..bb59a141878b 100755 --- a/docker/dev/backend/scripts/setup-bim +++ b/docker/dev/backend/scripts/setup-bim @@ -29,8 +29,8 @@ unzip -q COLLADA2GLTF-v2.1.5-linux.zip mv COLLADA2GLTF-bin "/usr/local/bin/COLLADA2GLTF" # IFCconvert -wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.6.0-517b819-linux64.zip -unzip -q IfcConvert-v0.6.0-517b819-linux64.zip +wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.7.11-fea8e3a-linux64.zip +unzip -q IfcConvert-v0.7.11-fea8e3a-linux64.zip mv IfcConvert "/usr/local/bin/IfcConvert" wget --quiet https://github.com/bimspot/xeokit-metadata/releases/download/1.0.1/xeokit-metadata-linux-x64.tar.gz diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile index 2025a5d0ece2..828c7e6ec711 100644 --- a/docker/prod/Dockerfile +++ b/docker/prod/Dockerfile @@ -96,7 +96,9 @@ FROM base AS all-in-one ENV OPENPROJECT_RAILS__CACHE__STORE=memcache ENV DATABASE_URL=postgres://openproject:openproject@127.0.0.1/openproject ENV PGDATA=/var/openproject/pgdata -ENV GOSU_VERSION="1.17" + +COPY --from=openproject/gosu /go/bin/gosu /usr/local/bin/gosu +RUN chmod +x /usr/local/bin/gosu && gosu nobody true RUN ./docker/prod/setup/postinstall-onprem.sh && \ ln -s /app/docker/prod/setup/.irbrc /root/ diff --git a/docker/prod/setup/postinstall-onprem.sh b/docker/prod/setup/postinstall-onprem.sh index af673a8010ce..78f5721d3528 100755 --- a/docker/prod/setup/postinstall-onprem.sh +++ b/docker/prod/setup/postinstall-onprem.sh @@ -52,11 +52,5 @@ rm -rf /tmp/nulldb a2enmod proxy proxy_http rm -f /etc/apache2/sites-enabled/000-default.conf -# gosu -dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')" -wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch" -chmod +x /usr/local/bin/gosu -gosu nobody true - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* truncate -s 0 /var/log/*log diff --git a/docker/prod/setup/preinstall-common.sh b/docker/prod/setup/preinstall-common.sh index 976cc5d2b5b5..8ba635d252c1 100755 --- a/docker/prod/setup/preinstall-common.sh +++ b/docker/prod/setup/preinstall-common.sh @@ -77,8 +77,8 @@ if [ ! "$BIM_SUPPORT" = "false" ]; then mv COLLADA2GLTF-bin "/usr/local/bin/COLLADA2GLTF" # IFCconvert - wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.6.0-517b819-linux64.zip - unzip -q IfcConvert-v0.6.0-517b819-linux64.zip + wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.7.11-fea8e3a-linux64.zip + unzip -q IfcConvert-v0.7.11-fea8e3a-linux64.zip mv IfcConvert "/usr/local/bin/IfcConvert" wget --quiet https://github.com/bimspot/xeokit-metadata/releases/download/1.0.1/xeokit-metadata-linux-x64.tar.gz diff --git a/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml b/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml index 6d59d1137244..4d0693eea18e 100644 --- a/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml +++ b/docs/api/apiv3/components/schemas/file_link_collection_read_model.yml @@ -1,28 +1,21 @@ # Schema: FileLinkCollectionReadModel --- allOf: - - $ref: './collection_model.yml' + - $ref: './paginated_collection_model.yml' - type: object - required: - - _links - - _embedded properties: _links: type: object - required: - - self properties: self: allOf: - - $ref: "./link.yml" + - $ref: './link.yml' - description: |- This file links collection **Resource**: FileLinkCollectionReadModel _embedded: type: object - required: - - elements properties: elements: type: array @@ -33,9 +26,17 @@ example: _type: Collection total: 2 count: 2 + pageSize: 30 + offset: 1 _links: self: href: '/api/v3/work_packages/42/file_links' + jumpTo: + href: '/api/v3/work_packages/42/file_links?offset=%7Boffset%7D&pageSize=30' + templated: true + changeSize: + href: '/api/v3/work_packages/42/file_links?offset=1&pageSize=%7Bsize%7D' + templated: true _embedded: elements: - id: 1337 diff --git a/docs/api/apiv3/components/schemas/file_link_read_model.yml b/docs/api/apiv3/components/schemas/file_link_read_model.yml index bcf766608739..8c912c5a4441 100644 --- a/docs/api/apiv3/components/schemas/file_link_read_model.yml +++ b/docs/api/apiv3/components/schemas/file_link_read_model.yml @@ -1,11 +1,6 @@ # Schema: FileLinkReadModel --- type: object -required: - - id - - _type - - originData - - _links properties: id: type: integer @@ -36,17 +31,6 @@ properties: $ref: './work_package_model.yml' _links: type: object - required: - - self - - storage - - container - - creator - - permission - - originOpen - - staticOriginOpen - - originOpenLocation - - staticOriginOpenLocation - - staticOriginDownload properties: self: allOf: @@ -166,24 +150,8 @@ example: container: _hint: Work package resource shortened for brevity _type: WorkPackage - _links: - self: - href: "/api/v3/work_packages/1528" - title: Develop API - schema: - href: "/api/v3/work_packages/schemas/11-2" id: 1528 subject: Develop API - description: - format: markdown - raw: Develop super cool OpenProject API. - html: "

Develop super cool OpenProject API.

" - scheduleManually: false - readonly: false - startDate: - dueDate: - createdAt: '2014-08-29T12:40:53.860Z' - updatedAt: '2014-08-29T12:44:41.036Z' _links: self: href: /api/v3/work_package/17/file_links/1337 @@ -199,8 +167,8 @@ example: delete: href: /api/v3/work_package/17/file_links/1337 status: - href: urn:openproject-org:api:v3:file-links:permission:View - title: View + href: urn:openproject-org:api:v3:file-links:permission:ViewAllowed + title: View allowed originOpen: href: https://nextcloud.deathstar.rocks/index.php/f/5503?openfile=1 staticOriginOpen: diff --git a/docs/contributions-guide/README.md b/docs/contributions-guide/README.md new file mode 100644 index 000000000000..82fe61ba24d1 --- /dev/null +++ b/docs/contributions-guide/README.md @@ -0,0 +1,37 @@ +--- +sidebar_navigation: + title: Contributions guide + priority: 956 +description: OpenProject contributions guide. +keywords: contributions guide, translate OpenProject, contribute, community, documentation +--- + +# Contributions guide + +Welcome to the OpenProject **Contributions guide**. + +This platform thrives on the support of its Community, and there are many ways you can help make it even better. Whether you're a developer, a user, or simply someone passionate about improving open-source tools, your contributions matter. + +## Overview + +| Topic | Content | +| ------------------------------------------------------------ | :-------------------------------------------------------- | +| [Contribute to documentation](contribution-documentation) | Learn how you can contribute to OpenProject documentation | +| [Translate OpenProject](translate-openproject) | Help translate OpenProject | +| [Give back to Community](give-back-to-community) | Learn how you can support OpenProject Community | +| [Report a bug](../development/report-a-bug/) | Learn how to report a bug in OpenProject | +| [Submit a feature idea](../development/submit-feature-idea/) | See how you can submit an new feature idea | + + +## How can you help? + +### Contribute to Documentation +Help keep our documentation accurate, comprehensive, and user-friendly. Whether it's fixing typos, updating outdated information, or adding new sections, your contributions make a difference. [Learn more](./contribution-documentation/). + +### Translate OpenProject +Assist in making OpenProject accessible in more languages or refine existing translations. Your input ensures that users worldwide have a seamless experience. [Learn more](./translate-openproject/). + +### Support the Community +Share your experiences by leaving a review, sharing our blog articles, or promoting OpenProject in your network. Every small effort helps expand our Community. [Learn more](./give-back-to-community). + +Please also refer to the [Development guide](../development) for Code review guidelines. diff --git a/docs/contributions-guide/contribution-documentation/README.md b/docs/contributions-guide/contribution-documentation/README.md new file mode 100644 index 000000000000..98da92ecbe73 --- /dev/null +++ b/docs/contributions-guide/contribution-documentation/README.md @@ -0,0 +1,62 @@ +--- +sidebar_navigation: + title: Contribute to documentation + priority: 999 +description: Overview of the OpenProject documentation +keywords: contribution, documentation, documentation process +--- + +# Contribute to the OpenProject documentation + +High-quality documentation is essential for the success of OpenProject. It ensures that users, developers, and administrators can effectively understand and use the platform. + +By contributing to the documentation, you help: + +- Keep the content accurate and up-to-date. +- Make complex features easier to understand. +- Ensure that OpenProject is accessible to a wider audience. + +Whether it’s fixing typos, clarifying instructions, or adding missing sections, every contribution is valuable. This guide will walk you through the process of contributing to our documentation, ensuring your work is effective and aligned with OpenProject’s standards. + +## Overview + +| Topic | Content | +| ------------------------------------------------------ | :----------------------------------------------------------- | +| [Documentation process](documentation-process) | A step-by-step guide on how to contribute to the documentation. | +| [Documentation style guide](documentation-style-guide) | What are the styles and other requirements to follow when contributing to the documentation? | +| [Contribution support](contribution-support) | What to do if you need help regarding your contribution to the documentation? | + +With this guide for contributing to the OpenProject documentation we followed and took inspiration from the [Contribute to GitLab guide](https://about.gitlab.com/community/contribute/). + +> [!TIP] +> Documentation changes are **not** changes or additions to the code of the OpenProject application. For contributions to the code, see our [product development guide](../../development/product-development-handbook/). Please also refer to the [development guide](../../development/code-review-guidelines/) for Code review guidelines + +## OpenProject documentation overview + +The OpenProject documentation provides comprehensive resources, including user guides, system administration, installation and operation instructions, API references, development guides, and release notes. It is available online at [OpenProject Documentation](https://www.openproject.org/docs/), and can also be accessed directly from your OpenProject application via the **Help** menu (question mark icon in the top-right corner). + +The documentation supports current and future users by offering step-by-step instructions for setup, configuration, and integration of OpenProject. It also provides detailed use cases, feature guides, and instructions for using OpenProject alongside other applications. + +To ensure clarity, accuracy, and completeness, the documentation is continuously updated to reflect new features, improvements, and Community feedback. + +### Contributing to OpenProject Documentation + +As an open-source platform, OpenProject thrives on Community collaboration. Contributions to our documentation are open to everyone, whether you're a developer, a long-time user, or someone new to the platform. + +By contributing to the documentation, you help ensure it remains accurate, clear, and up-to-date, benefiting the entire OpenProject Community. We welcome contributions of all kinds, including improving existing content, fixing errors, and adding new sections. + +## Contribution guidelines for documentation + +### Report it via e-mail + +If you would like to report a typo or an inconsistency in our documentation, the quickest way to do it is to **write an e-mail** to [support@openproject.com](mailto:support@openproject.com) and describe it with as much detail an possible. + +### Let us know through the OpenProject Community installation + +You can also join us directly through the [OpenProject Community installation](https://community.openproject.org). Here you can **leave a message on the [Forum](https://community.openproject.org/projects/openproject/forums)**, or **create a work package with the type *Documentation* ** and describe or request a documentation change. + +To gain access to the Community installation at, please send an email to [support@openproject.com](mailto:support@openproject.com) with the subject line **"Joining Community"**. Our team will review your request and send you an invitation as soon as possible. + +### Write your own pull request + +If you prefer, you can also go ahead and create a **draft pull request** with your suggestions and ask for the review from our team. Please take a look at the [documentation process](./documentation-process/) for the exact steps to do that and consult the [documentation style guide](./documentation-style-guide/) for instructions on documentation formatting in OpenProject. diff --git a/docs/development/contribution-documentation/contribution-support/README.md b/docs/contributions-guide/contribution-documentation/contribution-support/README.md similarity index 100% rename from docs/development/contribution-documentation/contribution-support/README.md rename to docs/contributions-guide/contribution-documentation/contribution-support/README.md diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/README.md b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/README.md similarity index 91% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/README.md rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/README.md index f3d2f091716c..66a91125bc08 100644 --- a/docs/development/contribution-documentation/documentation-process-internal-contributor/README.md +++ b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/README.md @@ -12,10 +12,10 @@ This guide describes how internal team members with write permissions can contri ## Prerequisites -1. [The contributor has a user account on GitHub.com](../../../development/contribution-documentation/documentation-process/#step-1-create-user-account-on-githubcom) +1. [The contributor has a user account on GitHub.com](../documentation-process/#step-1-create-user-account-on-githubcom) 2. The contributor has write permissions on the [OpenProject repository](https://github.com/opf/openproject) -3. [Software Typora editor installed](../../../development/contribution-documentation/documentation-process/#step-2-install-typora) -4. [Software GitHub Desktop installed](../../../development/contribution-documentation/documentation-process/#step-3-install-github-desktop) +3. [Software Typora editor installed](../documentation-process/#step-2-install-typora) +4. [Software GitHub Desktop installed](../documentation-process/#step-3-install-github-desktop) ## Step 1: Clone the OpenProject repository in GitHub Desktop diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/add-documentation-label-pull-requests.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/add-documentation-label-pull-requests.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/add-documentation-label-pull-requests.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/add-documentation-label-pull-requests.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/clone-repository.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/clone-repository.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/clone-repository.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/clone-repository.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/commit-history-in-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/commit-history-in-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/commit-history-in-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/commit-history-in-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/comparing-changes.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/comparing-changes.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/comparing-changes.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/comparing-changes.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-1.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-1.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-1.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-1.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-2.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-2.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-2.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-new-branch-step-2.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/create-pull-request-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-pull-request-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/create-pull-request-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/create-pull-request-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/fetch-origin-in-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/fetch-origin-in-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/fetch-origin-in-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/fetch-origin-in-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/push-origin-in-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/push-origin-in-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/push-origin-in-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/push-origin-in-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/select-cloned-repository.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/select-cloned-repository.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/select-cloned-repository.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/select-cloned-repository.png diff --git a/docs/development/contribution-documentation/documentation-process-internal-contributor/select-reviewer-for-documentation.png b/docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/select-reviewer-for-documentation.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process-internal-contributor/select-reviewer-for-documentation.png rename to docs/contributions-guide/contribution-documentation/documentation-process-internal-contributor/select-reviewer-for-documentation.png diff --git a/docs/development/contribution-documentation/documentation-process/Create-draft-pull-request.png b/docs/contributions-guide/contribution-documentation/documentation-process/Create-draft-pull-request.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/Create-draft-pull-request.png rename to docs/contributions-guide/contribution-documentation/documentation-process/Create-draft-pull-request.png diff --git a/docs/development/contribution-documentation/documentation-process/README.md b/docs/contributions-guide/contribution-documentation/documentation-process/README.md similarity index 100% rename from docs/development/contribution-documentation/documentation-process/README.md rename to docs/contributions-guide/contribution-documentation/documentation-process/README.md diff --git a/docs/development/contribution-documentation/documentation-process/Ready-for-review.png b/docs/contributions-guide/contribution-documentation/documentation-process/Ready-for-review.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/Ready-for-review.png rename to docs/contributions-guide/contribution-documentation/documentation-process/Ready-for-review.png diff --git a/docs/development/contribution-documentation/documentation-process/add-documentation-label-pull-requests.png b/docs/contributions-guide/contribution-documentation/documentation-process/add-documentation-label-pull-requests.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/add-documentation-label-pull-requests.png rename to docs/contributions-guide/contribution-documentation/documentation-process/add-documentation-label-pull-requests.png diff --git a/docs/development/contribution-documentation/documentation-process/branches-drop-down-list.png b/docs/contributions-guide/contribution-documentation/documentation-process/branches-drop-down-list.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/branches-drop-down-list.png rename to docs/contributions-guide/contribution-documentation/documentation-process/branches-drop-down-list.png diff --git a/docs/development/contribution-documentation/documentation-process/clone-repository.png b/docs/contributions-guide/contribution-documentation/documentation-process/clone-repository.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/clone-repository.png rename to docs/contributions-guide/contribution-documentation/documentation-process/clone-repository.png diff --git a/docs/development/contribution-documentation/documentation-process/commit-history-in-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process/commit-history-in-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/commit-history-in-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process/commit-history-in-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process/continue-sign-in-in-browser.png b/docs/contributions-guide/contribution-documentation/documentation-process/continue-sign-in-in-browser.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/continue-sign-in-in-browser.png rename to docs/contributions-guide/contribution-documentation/documentation-process/continue-sign-in-in-browser.png diff --git a/docs/development/contribution-documentation/documentation-process/create-new-branch-step-1.png b/docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-1.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/create-new-branch-step-1.png rename to docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-1.png diff --git a/docs/development/contribution-documentation/documentation-process/create-new-branch-step-2.png b/docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-2.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/create-new-branch-step-2.png rename to docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-2.png diff --git a/docs/development/contribution-documentation/documentation-process/create-new-branch-step-3.png b/docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-3.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/create-new-branch-step-3.png rename to docs/contributions-guide/contribution-documentation/documentation-process/create-new-branch-step-3.png diff --git a/docs/development/contribution-documentation/documentation-process/create-pull-request-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process/create-pull-request-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/create-pull-request-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process/create-pull-request-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process/define-how-to-use-the-fork.png b/docs/contributions-guide/contribution-documentation/documentation-process/define-how-to-use-the-fork.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/define-how-to-use-the-fork.png rename to docs/contributions-guide/contribution-documentation/documentation-process/define-how-to-use-the-fork.png diff --git a/docs/development/contribution-documentation/documentation-process/disable-github-actions.png b/docs/contributions-guide/contribution-documentation/documentation-process/disable-github-actions.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/disable-github-actions.png rename to docs/contributions-guide/contribution-documentation/documentation-process/disable-github-actions.png diff --git a/docs/development/contribution-documentation/documentation-process/edit-the-pull-request.png b/docs/contributions-guide/contribution-documentation/documentation-process/edit-the-pull-request.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/edit-the-pull-request.png rename to docs/contributions-guide/contribution-documentation/documentation-process/edit-the-pull-request.png diff --git a/docs/development/contribution-documentation/documentation-process/fork-openproject.png b/docs/contributions-guide/contribution-documentation/documentation-process/fork-openproject.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/fork-openproject.png rename to docs/contributions-guide/contribution-documentation/documentation-process/fork-openproject.png diff --git a/docs/development/contribution-documentation/documentation-process/open-pr-in-forked-repository.png b/docs/contributions-guide/contribution-documentation/documentation-process/open-pr-in-forked-repository.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/open-pr-in-forked-repository.png rename to docs/contributions-guide/contribution-documentation/documentation-process/open-pr-in-forked-repository.png diff --git a/docs/development/contribution-documentation/documentation-process/pull-upstream-changes.png b/docs/contributions-guide/contribution-documentation/documentation-process/pull-upstream-changes.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/pull-upstream-changes.png rename to docs/contributions-guide/contribution-documentation/documentation-process/pull-upstream-changes.png diff --git a/docs/development/contribution-documentation/documentation-process/push-origin-in-github-desktop.png b/docs/contributions-guide/contribution-documentation/documentation-process/push-origin-in-github-desktop.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/push-origin-in-github-desktop.png rename to docs/contributions-guide/contribution-documentation/documentation-process/push-origin-in-github-desktop.png diff --git a/docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-1.png b/docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-1.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-1.png rename to docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-1.png diff --git a/docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-2.png b/docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-2.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-2.png rename to docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-2.png diff --git a/docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-3.png b/docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-3.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-3.png rename to docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-3.png diff --git a/docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-4.png b/docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-4.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/rebase-your-fork-step-4.png rename to docs/contributions-guide/contribution-documentation/documentation-process/rebase-your-fork-step-4.png diff --git a/docs/development/contribution-documentation/documentation-process/select-repository-to-be-cloned.png b/docs/contributions-guide/contribution-documentation/documentation-process/select-repository-to-be-cloned.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/select-repository-to-be-cloned.png rename to docs/contributions-guide/contribution-documentation/documentation-process/select-repository-to-be-cloned.png diff --git a/docs/development/contribution-documentation/documentation-process/select-reviewer-for-documentation.png b/docs/contributions-guide/contribution-documentation/documentation-process/select-reviewer-for-documentation.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/select-reviewer-for-documentation.png rename to docs/contributions-guide/contribution-documentation/documentation-process/select-reviewer-for-documentation.png diff --git a/docs/development/contribution-documentation/documentation-process/select-the-new-release-branch.png b/docs/contributions-guide/contribution-documentation/documentation-process/select-the-new-release-branch.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/select-the-new-release-branch.png rename to docs/contributions-guide/contribution-documentation/documentation-process/select-the-new-release-branch.png diff --git a/docs/development/contribution-documentation/documentation-process/sign-in-into-github.png b/docs/contributions-guide/contribution-documentation/documentation-process/sign-in-into-github.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/sign-in-into-github.png rename to docs/contributions-guide/contribution-documentation/documentation-process/sign-in-into-github.png diff --git a/docs/development/contribution-documentation/documentation-process/switch-the-default-branch-step-1.png b/docs/contributions-guide/contribution-documentation/documentation-process/switch-the-default-branch-step-1.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/switch-the-default-branch-step-1.png rename to docs/contributions-guide/contribution-documentation/documentation-process/switch-the-default-branch-step-1.png diff --git a/docs/development/contribution-documentation/documentation-process/switch-the-default-branch-step-2.png b/docs/contributions-guide/contribution-documentation/documentation-process/switch-the-default-branch-step-2.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/switch-the-default-branch-step-2.png rename to docs/contributions-guide/contribution-documentation/documentation-process/switch-the-default-branch-step-2.png diff --git a/docs/development/contribution-documentation/documentation-process/sync-fork-update-branch.png b/docs/contributions-guide/contribution-documentation/documentation-process/sync-fork-update-branch.png similarity index 100% rename from docs/development/contribution-documentation/documentation-process/sync-fork-update-branch.png rename to docs/contributions-guide/contribution-documentation/documentation-process/sync-fork-update-branch.png diff --git a/docs/development/contribution-documentation/documentation-style-guide/OpenProject_documentation_menu.png b/docs/contributions-guide/contribution-documentation/documentation-style-guide/OpenProject_documentation_menu.png similarity index 100% rename from docs/development/contribution-documentation/documentation-style-guide/OpenProject_documentation_menu.png rename to docs/contributions-guide/contribution-documentation/documentation-style-guide/OpenProject_documentation_menu.png diff --git a/docs/development/contribution-documentation/documentation-style-guide/README.md b/docs/contributions-guide/contribution-documentation/documentation-style-guide/README.md similarity index 100% rename from docs/development/contribution-documentation/documentation-style-guide/README.md rename to docs/contributions-guide/contribution-documentation/documentation-style-guide/README.md diff --git a/docs/development/contribution-documentation/documentation-style-guide/screenshot_area_highlight.png b/docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_area_highlight.png similarity index 100% rename from docs/development/contribution-documentation/documentation-style-guide/screenshot_area_highlight.png rename to docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_area_highlight.png diff --git a/docs/development/contribution-documentation/documentation-style-guide/screenshot_highlights_example.png b/docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_highlights_example.png similarity index 100% rename from docs/development/contribution-documentation/documentation-style-guide/screenshot_highlights_example.png rename to docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_highlights_example.png diff --git a/docs/development/contribution-documentation/documentation-style-guide/screenshot_numberedlabels_highlight.png b/docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_numberedlabels_highlight.png similarity index 100% rename from docs/development/contribution-documentation/documentation-style-guide/screenshot_numberedlabels_highlight.png rename to docs/contributions-guide/contribution-documentation/documentation-style-guide/screenshot_numberedlabels_highlight.png diff --git a/docs/contributions-guide/give-back-to-community/README.md b/docs/contributions-guide/give-back-to-community/README.md new file mode 100644 index 000000000000..34ba45efe638 --- /dev/null +++ b/docs/contributions-guide/give-back-to-community/README.md @@ -0,0 +1,71 @@ +--- +sidebar_navigation: + title: Give back to Community + priority: 700 +description: Guide on how to contribute to OpenProject Community +keywords: community, review, video, blog, contribution +--- + +# Give back to Community + +OpenProject thrives on the strength and engagement of its Community. Beyond coding or documentation, there are many ways you can help spread the word, share your experiences, and inspire others to adopt and use OpenProject effectively. + +## Share your experience + +> [!IMPORTANT] +> By submitting your content, we assume that you grant us permission to publish it on our platforms. If you would like to review the content before it is published, please let us know explicitly, and we will be happy to accommodate your request. + +Your unique experience with OpenProject can inspire others and provide valuable feedback to our team. Here are some ideas for sharing your story: + +- **Written Texts** + Create a brief article (0.5–2 pages) that covers the following topics: + + - A short introduction of yourself and your project. + - Basic details such as the project’s duration, objectives, and participants. + - An overview of which OpenProject modules you used and how they supported your work. + - Your overall experience: What works well for you? What could be improved? + - Include screenshots showcasing your OpenProject setup (with permission to publish). + + **Example**: take a look one one our case studies with an [NGO](https://www.openproject.org/project-management-ngos-foundations/case-study-open-source-initiative-osi/) , a [university project](https://www.openproject.org/project-management-universities-research/case-study-rewrite/) or a [municipality](https://www.openproject.org/project-management-public-sector/case-study-city-ravensburg/). + +- **Blog Posts** + Write a detailed blog post about your OpenProject journey. You can either: + + - Submit your blog post for publication on the OpenProject website. [Contact us](https://www.openproject.org/contact/) for guidelines. + - Publish it on your own channels (website, blog, or LinkedIn) and link back to OpenProject. + +- **Video Contributions** + Record a short video explaining how you or your team use OpenProject. Include key features, workflows, and tips that others might find useful. + +- **Testimonials and Quotes** + Share a short testimonial or quote about your experience with OpenProject. If possible, **include a professional photo** of yourself or your team for publication. + +## Support us online + +Help OpenProject reach more users by engaging with our content and sharing it with your network. + +- **Social Media Posts** + - Share your experience with OpenProject on your social channels, including a link to our website. + - You can also re-share content from the [OpenProject blog](https://www.openproject.org/blog/) or our official social media accounts. + + [Follow us on LinkedIn](https://www.linkedin.com/company/openproject-gmbh) + + [Follow us on Reddit](https://www.reddit.com/r/openproject) + + [Follow us on Fosstodon](https://fosstodon.org/@openproject) + + [Follow us on Twitter/X](https://twitter.com/openproject) + + [Follow us on Bluesky](https://bsky.app/profile/openproject.bsky.social) +- **Add a Backlink to Your Website** + Include a link to OpenProject’s website on your blog, portfolio, or company website to help more people discover our tool. +- **Write a Review** + Share your thoughts about OpenProject on one of our review platforms. [Leave a review ](https://www.openproject.org/reviews/). + +## Spread the word + +Let your network know how OpenProject has made an impact for you. Whether it’s during a team meeting, at an industry event, or simply in a conversation with a peer, sharing your experiences can inspire others to explore OpenProject. + +## Join our Community + +Be part of the conversation! **Join us in our weekly team call** and share how you use OpenProject in your team or organization. diff --git a/docs/contributions-guide/give-back-to-community/openproject-user-guide-create-project-plan.gif b/docs/contributions-guide/give-back-to-community/openproject-user-guide-create-project-plan.gif new file mode 100644 index 000000000000..86bdb3c00e5b Binary files /dev/null and b/docs/contributions-guide/give-back-to-community/openproject-user-guide-create-project-plan.gif differ diff --git a/docs/contributions-guide/give-back-to-community/openproject-user-guide-edit-project-plan.gif b/docs/contributions-guide/give-back-to-community/openproject-user-guide-edit-project-plan.gif new file mode 100644 index 000000000000..1e3e21b26a77 Binary files /dev/null and b/docs/contributions-guide/give-back-to-community/openproject-user-guide-edit-project-plan.gif differ diff --git a/docs/contributions-guide/give-back-to-community/openproject-user-guide-select-gantt-charts-module.png b/docs/contributions-guide/give-back-to-community/openproject-user-guide-select-gantt-charts-module.png new file mode 100644 index 000000000000..466e10d66b95 Binary files /dev/null and b/docs/contributions-guide/give-back-to-community/openproject-user-guide-select-gantt-charts-module.png differ diff --git a/docs/development/translate-openproject/GitHub-CrowdIn-OP.png b/docs/contributions-guide/translate-openproject/GitHub-CrowdIn-OP.png similarity index 100% rename from docs/development/translate-openproject/GitHub-CrowdIn-OP.png rename to docs/contributions-guide/translate-openproject/GitHub-CrowdIn-OP.png diff --git a/docs/development/translate-openproject/README.md b/docs/contributions-guide/translate-openproject/README.md similarity index 98% rename from docs/development/translate-openproject/README.md rename to docs/contributions-guide/translate-openproject/README.md index f41c4c8913e9..f3976cf99638 100644 --- a/docs/development/translate-openproject/README.md +++ b/docs/contributions-guide/translate-openproject/README.md @@ -1,7 +1,7 @@ --- sidebar_navigation: title: Translate OpenProject - priority: 985 + priority: 800 description: How to translate OpenProject to your language keywords: translation, translate, crowdin, localization --- @@ -64,4 +64,4 @@ If you are interested in becoming a proof reader, please contact one of the proj If your language is not listed in the list of CrowdIn languages, please contact our project managers or send us an email so we can add your language. -Find out more about our development concepts regarding translations [here](../concepts/translations). +Find out more about our development concepts regarding translations [here](../../development/concepts/translations). diff --git a/docs/development/translate-openproject/crowdin-editor.png b/docs/contributions-guide/translate-openproject/crowdin-editor.png similarity index 100% rename from docs/development/translate-openproject/crowdin-editor.png rename to docs/contributions-guide/translate-openproject/crowdin-editor.png diff --git a/docs/development/translate-openproject/crowdin-language-overview.png b/docs/contributions-guide/translate-openproject/crowdin-language-overview.png similarity index 100% rename from docs/development/translate-openproject/crowdin-language-overview.png rename to docs/contributions-guide/translate-openproject/crowdin-language-overview.png diff --git a/docs/development/translate-openproject/crowdin-multi-translation.png b/docs/contributions-guide/translate-openproject/crowdin-multi-translation.png similarity index 100% rename from docs/development/translate-openproject/crowdin-multi-translation.png rename to docs/contributions-guide/translate-openproject/crowdin-multi-translation.png diff --git a/docs/development/translate-openproject/crowdin-overview.png b/docs/contributions-guide/translate-openproject/crowdin-overview.png similarity index 100% rename from docs/development/translate-openproject/crowdin-overview.png rename to docs/contributions-guide/translate-openproject/crowdin-overview.png diff --git a/docs/development/translate-openproject/fair-language/README.md b/docs/contributions-guide/translate-openproject/fair-language/README.md similarity index 100% rename from docs/development/translate-openproject/fair-language/README.md rename to docs/contributions-guide/translate-openproject/fair-language/README.md diff --git a/docs/development/contribution-documentation/README.md b/docs/development/contribution-documentation/README.md deleted file mode 100644 index 39055ad8e01f..000000000000 --- a/docs/development/contribution-documentation/README.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -sidebar_navigation: - title: Contribute to documentation - priority: 999 -description: Overview of the OpenProject documentation -keywords: contribution, documentation, documentation process ---- - -# Contribute to the OpenProject documentation - -## How do I get access to the OpenProject Community installation? - -To get an account for community.openproject.org, please write an email with the subject 'Joining community' to [support@openproject.com](mailto:support@openproject.com), if you would like to join our Community. We will then invite you as soon as possible. - -## What does the OpenProject documentation entail? - -The OpenProject documentation makes available user guides, system admin, installation and operation, API as well as development guides and release notes. - -Current and future users of the application find instructions for the set up and configuration of OpenProject in the documentation. Furthermore, it contains use cases and usage instructions for all OpenProject features and the use of OpenProject with other applications. - -This documentation evolves continuously with new features and improvements to achieve clarity, accuracy, and completeness. - -## Where to find the OpenProject documentation? - -The documentation for OpenProject is published [here](https://www.openproject.org/docs/). You can also access the documentation from your OpenProject application under user guides and API documentation below the question mark at the top right in the header menu. - -## Who can contribute to the documentation? - -Being proudly open source, we invite anyone in our community to contribute to our software as well as the documentation to improve it even further. - -## What can you contribute to the documentation? - -Documentation improvements and changes apply to the documentation described in the section above. Documentation changes are **not** changes or additions to the code of the OpenProject application. For contributions to the code, see our [product development guide](../product-development-handbook/). - -We are looking forward to receiving the following contributions from you: - -- Eliminating errors and working on other improvements in the existing documentation. This could be missing content, e.g. descriptions or step-by-step guides for features. - -- Adding use cases. - -- Adding visuals, e.g. screenshots, to complement descriptions. - -- Fixing of spelling, grammar, punctuation mistakes. - -- Fixing of internal and external links that are not working or are incorrect. - -- Translations into your mother tongue (coming soon). - -## Overview - -| Topic | Content | -| ------------------------------------------------------ | :----------------------------------------------------------- | -| [Documentation process](documentation-process) | A step-by-step guide on how to contribute to the documentation. | -| [Documentation style guide](documentation-style-guide) | What are the styles and other requirements to follow when contributing to the documentation? | -| [Contribution support](contribution-support) | What to do if you need help regarding your contribution to the documentation? | - -With this guide for contributing to the OpenProject documentation we followed and took inspiration from the [Contribute to GitLab guide](https://about.gitlab.com/community/contribute/). diff --git a/docs/development/development-environment/docker/README.md b/docs/development/development-environment/docker/README.md index a16792714f2e..cdb667db5232 100644 --- a/docs/development/development-environment/docker/README.md +++ b/docs/development/development-environment/docker/README.md @@ -218,6 +218,18 @@ you want to see what the browsers are doing. `gvncviewer` or `vinagre` on Linux the `docker-compose.override.yml` to access a container of a specific browser. As a default, the `chrome` container is exposed on port 5900. The password is `secret` for all. +Adding additional external docker networks to the test services like `backend-test` (e.g. inside the +`docker-compose.override.yml`) breaks the functionality of the Selenium service. This results in failing tests running +inside a Selenium context, like feature and UI tests. + +``` +Selenium::WebDriver::Error::UnknownError: + unknown error: net::ERR_CONNECTION_REFUSED + (Session info: chrome=130.0.6723.91) +``` + +If this happens just comment out the network overrides. + ## TLS support Within `docker/dev/tls` compose files are provided, that elevate the development stack to be run under full TLS diff --git a/docs/faq/README.md b/docs/faq/README.md index fe32c403a21b..462983058f16 100644 --- a/docs/faq/README.md +++ b/docs/faq/README.md @@ -296,7 +296,7 @@ OpenProject changed the database from MySQL (rarely also MariaDB) in older Versi ### How can I contribute to OpenProject? -We welcome everybody willing to help make OpenProject better. There are a lot of possibilities for helping, be it [improving the translations](../development/translate-openproject) via crowdin, answering questions in the [forums](https://community.openproject.org/projects/openproject/forums) or by fixing bugs and implementing features. +We welcome everybody willing to help make OpenProject better. There are a lot of possibilities for helping, be it [improving the translations](../contributions-guide/translate-openproject) via crowdin, answering questions in the [forums](https://community.openproject.org/projects/openproject/forums) or by fixing bugs and implementing features. If you want to code, a good starting point would be to make yourself familiar with the [basic approaches for developing](../development/) in OpenProject and opening a pull request on GitHub referencing an existing bug report or feature request. Find our GitHub page [here](https://github.com/opf/openproject). diff --git a/docs/installation-and-operations/configuration/README.md b/docs/installation-and-operations/configuration/README.md index 839ec412458f..7c30eb8c10ff 100644 --- a/docs/installation-and-operations/configuration/README.md +++ b/docs/installation-and-operations/configuration/README.md @@ -173,6 +173,16 @@ OPENPROJECT_SEED_ADMIN_USER_NAME="OpenProject Admin" # Name to assign to that us OPENPROJECT_SEED_ADMIN_USER_MAIL="admin@example.net" # Email attribute to assign to that user. Note that in packaged installations, a wizard step will assign this variable as well. ``` +Optionally, you can also lock the admin user that gets created right away. This is useful when you have an LDAP or SSO integration set up and you want to prevent the admin user from logging in. + +> [!WARNING] +> With the admin user seeding disabled, you need to have an LDAP or SSO integration set up through environment variables. +> Otherwise, you will not be able to retain access to the system. + +```shell +OPENPROJECT_SEED_ADMIN_USER_LOCKED="true" +``` + ### Seeding LDAP connections OpenProject allows you to create and maintain an LDAP connection with optional synchronized group filters. This is relevant for e.g., automated deployments, where you want to trigger the synchronization right at the start. diff --git a/docs/installation-and-operations/configuration/outbound-emails/README.md b/docs/installation-and-operations/configuration/outbound-emails/README.md index dfff551b9bac..15ca4b7005eb 100644 --- a/docs/installation-and-operations/configuration/outbound-emails/README.md +++ b/docs/installation-and-operations/configuration/outbound-emails/README.md @@ -47,6 +47,7 @@ These are the options that are available. Please see the [Configuration guide](. | SMTP password | smtp_password | `OPENPROJECT_SMTP__PASSWORD` | Password for authentication against the SMTP server (when authentication is required) | | Automatically use STARTTLS | smtp_enable_starttls_auto | `OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO` | You can enable or disable STARTTLS here in case it doesn't work. Make sure you don't login to a SMTP server over a public network when using this. Recommended to leave this on if your server supports it. Possible values: true / false | | OpenSSL verify mode | smtp_openssl_verify_mode | `OPENPROJECT_SMTP__OPENSSL__VERIFY__MODE` | Define how the SMTP server certificate is validated. Make sure you don't just disable verification here unless both, OpenProject and SMTP servers are on a private network. Possible values: `none`, `peer`, `client_once` or `fail_if_no_peer_cert`.
Note: This setting can only be set through ENV/settings | +| SMTP Timeout | smtp_timeout | `OPENPROJECT_SMTP__TIMEOUT` | This optional setting allows you to specify the number of seconds to wait for SMTP connections to be opened and read.
If the value is set too low, a `Net::OpenTimeout` or `Net::ReadTimeout` might be raised. | ## Package-based installation (DEB/RPM) @@ -59,7 +60,7 @@ openproject config:set OPENPROJECT_SMTP__PORT=587 openproject config:set OPENPROJECT_SMTP__DOMAIN=my.domain.com openproject config:set OPENPROJECT_SMTP__AUTHENTICATION=login openproject config:set OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO=true -openproject config:set OPENPROJECT_SMTP__USER_NAME="apikey" +openproject config:set OPENPROJECT_SMTP__USER__NAME="apikey" openproject config:set OPENPROJECT_SMTP__PASSWORD="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" ``` @@ -76,7 +77,7 @@ docker run -d \ -e OPENPROJECT_SMTP__DOMAIN=my.domain.com \ -e OPENPROJECT_SMTP__AUTHENTICATION=login \ -e OPENPROJECT_SMTP__ENABLE__STARTTLS__AUTO=true \ - -e OPENPROJECT_SMTP__USER_NAME="apikey" \ + -e OPENPROJECT_SMTP__USER__NAME="apikey" \ -e OPENPROJECT_SMTP__PASSWORD="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" \ ... ``` diff --git a/docs/release-notes/12/12-0-7/README.md b/docs/release-notes/12/12-0-7/README.md index 4baf3e484be6..667a1c216eef 100644 --- a/docs/release-notes/12/12-0-7/README.md +++ b/docs/release-notes/12/12-0-7/README.md @@ -23,7 +23,7 @@ There is now a separate setting for the max API size that will be used for these OpenProject relies on community translations for some languages that we cannot provide translations for ourselves. It was brought to our attention that the Russian translations partially contain expletive languages. Thanks to community contributors Sergey and Christina, these translations were fixed on crowdin and could now be included into the release. -We need your help to improve and extend translations of OpenProject into your native language. To get more information, please see our [Translating OpenProject guide](../../../development/translate-openproject/) and our [project on crowdin.com](https://crowdin.com/project/openproject), where you can provide and help approve translations from your browser. If you wish to become a proofreader for your language, please reach out to [info@openproject.com](mailto:info@openproject.com) +We need your help to improve and extend translations of OpenProject into your native language. To get more information, please see our [Translating OpenProject guide](../../../contributions-guide/translate-openproject/) and our [project on crowdin.com](https://crowdin.com/project/openproject), where you can provide and help approve translations from your browser. If you wish to become a proofreader for your language, please reach out to [info@openproject.com](mailto:info@openproject.com) ## Custom plugins in packaged installations diff --git a/docs/release-notes/13-4-0/README.md b/docs/release-notes/13-4-0/README.md index e23756b496e8..39f389fa5280 100644 --- a/docs/release-notes/13-4-0/README.md +++ b/docs/release-notes/13-4-0/README.md @@ -173,4 +173,4 @@ An important part is also the translations, for which we thank the following con - [Marek Bajon](https://crowdin.com/profile/mbajon), who translated to Polish - [Vlastislav Dockal](https://crowdin.com/profile/vdockal), who translated to Czech -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-0-0/README.md b/docs/release-notes/14-0-0/README.md index 8d7b81dc0e3c..185f90706439 100644 --- a/docs/release-notes/14-0-0/README.md +++ b/docs/release-notes/14-0-0/README.md @@ -297,4 +297,4 @@ Silas Kropf, Philipp Schulz, Benjamin Rönnau, Mario Haustein, Matt User, Mario Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight user [izzahk](https://crowdin.com/profile/izzahk) who has done an outstanding number of translations for the Malaysian language in recent weeks. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-1-0/README.md b/docs/release-notes/14-1-0/README.md index aa2488be3e18..21f6ca66ec98 100644 --- a/docs/release-notes/14-1-0/README.md +++ b/docs/release-notes/14-1-0/README.md @@ -190,4 +190,4 @@ Also thanks for finding and responsibly disclosing the CVE-2024-135224 vulnerabi Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight user [Syvert](https://crowdin.com/profile/syvert) who has done an outstanding number of translations for the Norwegian language in recent weeks. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-2-0/README.md b/docs/release-notes/14-2-0/README.md index 851475f6828f..195801e4fd78 100644 --- a/docs/release-notes/14-2-0/README.md +++ b/docs/release-notes/14-2-0/README.md @@ -125,4 +125,4 @@ A very special thank you goes to the City of Cologne for sponsoring features on Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight user [aniessalam](https://crowdin.com/profile/aniessalam) who has done an outstanding number of translations for the Malay language in recent weeks. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-3-0/README.md b/docs/release-notes/14-3-0/README.md index e5fd4a780e53..23a9739840c8 100644 --- a/docs/release-notes/14-3-0/README.md +++ b/docs/release-notes/14-3-0/README.md @@ -192,4 +192,4 @@ A thank you also goes to Eric Guo for contributing the Date zoom based on calend Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! This release we would like to highlight user [Todor Belov](https://crowdin.com/profile/todor.belov), who has done an outstanding number of translations for the Bulgarian language in recent weeks. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-5-0/README.md b/docs/release-notes/14-5-0/README.md index ef89c4690755..b86f02b92407 100644 --- a/docs/release-notes/14-5-0/README.md +++ b/docs/release-notes/14-5-0/README.md @@ -78,11 +78,11 @@ See our user guide to learn more about [project lists and how to filter them](.. ### PDF export of meeting agenda and meeting -When pressing the key combination for printing – e.g. **cmd + P** for mac users or **STRG + P** for Windows users – you can create your meeting as PDF, download and print it. This has been improved with OpenProject 14.5, so that, for example, meeting buttons like **+ Add** are not displayed in the PDF. +When pressing the key combination for printing – e.g. **cmd + P** for mac users or **CTRL + P** for Windows users – you can create your meeting as PDF, download and print it. This has been improved with OpenProject 14.5, so that, for example, meeting buttons like **+ Add** are not displayed in the PDF. ### Meetings: Disable by default "Send out invitation emails upon creation" -When creating a new meeting in OpenProject, you can choose wheather you want to send out invitation emails or not. Up until now, this has been enabled by default. Due to user feedback, this option is now disabled per default. +When creating a new meeting in OpenProject, you can choose whether you want to send out invitation emails or not. Up until now, this has been enabled by default. Due to user feedback, this option is now disabled per default. ### Rename actions in work package dropdown menu @@ -131,7 +131,7 @@ In this release, the dynamic bootstrapping of Angular components has been remove - Bugfix: \[API doc\] GET /projects missing params and incorrect response \[[#40642](https://community.openproject.org/wp/40642)\] - Bugfix: OpenAPI Specs wrong for creating work package relations \[[#40942](https://community.openproject.org/wp/40942)\] - Bugfix: API Description and OpenAPI Spec not consistent \[[#40945](https://community.openproject.org/wp/40945)\] -- Bugfix: Truncaded custom fields in work package table (Browser: Edge) \[[#52890](https://community.openproject.org/wp/52890)\] +- Bugfix: Truncated custom fields in work package table (Browser: Edge) \[[#52890](https://community.openproject.org/wp/52890)\] - Bugfix: GitLab integration pipeline status not updated \[[#54122](https://community.openproject.org/wp/54122)\] - Bugfix: Wrong date format in notification email \[[#54136](https://community.openproject.org/wp/54136)\] - Bugfix: Sort order of wiki pages in side-menu wrong / inconsistent \[[#54450](https://community.openproject.org/wp/54450)\] @@ -147,8 +147,8 @@ In this release, the dynamic bootstrapping of Angular components has been remove - Bugfix: Internal error when trying to change 2FA settings that are enforced through ENV \[[#56821](https://community.openproject.org/wp/56821)\] - Bugfix: FixDeletedDataJournals migration can fail sometimes \[[#56846](https://community.openproject.org/wp/56846)\] - Bugfix: Backlogs and GitHub have unnecessarily nested menu nodes \[[#56920](https://community.openproject.org/wp/56920)\] -- Bugfix: Wording of error message for Nextcloud host in storage form is missleading \[[#56992](https://community.openproject.org/wp/56992)\] -- Bugfix: OpenProject Dark Mode: selection colour of table rows \[[#57003](https://community.openproject.org/wp/57003)\] +- Bugfix: Wording of error message for Nextcloud host in storage form is misleading \[[#56992](https://community.openproject.org/wp/56992)\] +- Bugfix: OpenProject Dark Mode: selection color of table rows \[[#57003](https://community.openproject.org/wp/57003)\] - Bugfix: Work package toolbar has double outline on left \[[#57004](https://community.openproject.org/wp/57004)\] - Bugfix: Firefox cuts PDF export after the first page \[[#57027](https://community.openproject.org/wp/57027)\] - Bugfix: Some status indicators are missing a border \[[#57031](https://community.openproject.org/wp/57031)\] @@ -158,16 +158,16 @@ In this release, the dynamic bootstrapping of Angular components has been remove - Bugfix: Nextcloud "recheck connection" checks for GroupFolderApp though AMPF is deactivated \[[#57068](https://community.openproject.org/wp/57068)\] - Bugfix: In the calendar widget on the My Page page, meetings are displayed with the wrong time \[[#57078](https://community.openproject.org/wp/57078)\] - Bugfix: Default user avatar is too big for work package table rendering (safari) \[[#57093](https://community.openproject.org/wp/57093)\] -- Bugfix: OpenProject Dark Mode: CKEditor using too light colours e.g. for pressed buttons \[[#57103](https://community.openproject.org/wp/57103)\] +- Bugfix: OpenProject Dark Mode: CKEditor using too light colors e.g. for pressed buttons \[[#57103](https://community.openproject.org/wp/57103)\] - Bugfix: Cannot download 2FA backup codes \[[#57146](https://community.openproject.org/wp/57146)\] - Bugfix: OpenProject Dark Mode: diff view for description (and large text fields) not matching \[[#57151](https://community.openproject.org/wp/57151)\] - Bugfix: Project filter in notification center is not correctly highlighted \[[#57154](https://community.openproject.org/wp/57154)\] - Bugfix: Time and cost report : text of unit cost activity is displayed with html tag '<i>' \[[#57198](https://community.openproject.org/wp/57198)\] - Bugfix: Meeting selection in work packages highly confusing \[[#57205](https://community.openproject.org/wp/57205)\] - Bugfix: Attachment headlines are semi-transparent and overlapped by content \[[#57209](https://community.openproject.org/wp/57209)\] -- Bugfix: Webhook doesn't log all errors \[[#57277](https://community.openproject.org/wp/57277)\] +- Bugfix: Webhook doesn't log all errors \[[#57277](https://community.openproject.org/wp/57277)\] - Bugfix: Notifications for date alerts show name of a person \[[#57279](https://community.openproject.org/wp/57279)\] -- Bugfix: OpenProject Dark Mode: reiterate hover/active button colour \[[#57282](https://community.openproject.org/wp/57282)\] +- Bugfix: OpenProject Dark Mode: reiterate hover/active button color \[[#57282](https://community.openproject.org/wp/57282)\] - Bugfix: Robots follow action links unnecessarily \[[#57316](https://community.openproject.org/wp/57316)\] - Bugfix: Some previews in the Lookbook do not work \[[#57322](https://community.openproject.org/wp/57322)\] - Bugfix: Number of meeting participants does not add up \[[#57392](https://community.openproject.org/wp/57392)\] @@ -214,4 +214,4 @@ Last but not least, we are very grateful for our very engaged translation contri - [Sebvita_devinci](https://crowdin.com/profile/sebvita_devinci), for proof reading French translations. - [Alin Marcu](https://crowdin.com/profile/deconfcom), for proof reading Romanian translations. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/14-6-0/README.md b/docs/release-notes/14-6-0/README.md index 96fa924c27e2..3efd7683c6c6 100644 --- a/docs/release-notes/14-6-0/README.md +++ b/docs/release-notes/14-6-0/README.md @@ -83,7 +83,7 @@ On the Meetings tab in the split screen view, the number next to the “Meetings - Bugfix: Authorization::UnknownPermissionError happened in GET::API::V3::Root#/ \[[#56064](https://community.openproject.org/wp/56064)\] - Bugfix: Some Gantt charts get migrated to the work package module \[[#56769](https://community.openproject.org/wp/56769)\] - Bugfix: \[API doc\] color attribute of status missing \[[#57016](https://community.openproject.org/wp/57016)\] -- Bugfix: Menu Transparent for existings user afer db upgrade to 14.3.0 from 9.x \[[#57037](https://community.openproject.org/wp/57037)\] +- Bugfix: Menu Transparent for existing user after db upgrade to 14.3.0 from 9.x \[[#57037](https://community.openproject.org/wp/57037)\] - Bugfix: Right side of the instance upper banner looks misaligned \[[#57092](https://community.openproject.org/wp/57092)\] - Bugfix: Primer: Action menu is sometimes incorrectly positioned on mobile \[[#57143](https://community.openproject.org/wp/57143)\] - Bugfix: Icons and spacing is off on Work package table configuration view \[[#57345](https://community.openproject.org/wp/57345)\] @@ -103,7 +103,7 @@ On the Meetings tab in the split screen view, the number next to the “Meetings - Bugfix: www-authenticate header lacks comma \[[#58009](https://community.openproject.org/wp/58009)\] - Bugfix: Nextcloud connection validation fails on disabled AMPF configuration \[[#58018](https://community.openproject.org/wp/58018)\] - Bugfix: White space wrong in text diff \[[#58092](https://community.openproject.org/wp/58092)\] -- Bugfix: Primary button with a different custom colour remains green on click/pressed \[[#58130](https://community.openproject.org/wp/58130)\] +- Bugfix: Primary button with a different custom color remains green on click/pressed \[[#58130](https://community.openproject.org/wp/58130)\] - Bugfix: 'dd' is showing when reloading notification center \[[#58134](https://community.openproject.org/wp/58134)\] - Bugfix: Update storage banners to render with rounded borders \[[#58142](https://community.openproject.org/wp/58142)\] - Bugfix: Update the post storage creation message: admins don't need to activate individual modules per project anymore \[[#58150](https://community.openproject.org/wp/58150)\] @@ -123,7 +123,7 @@ On the Meetings tab in the split screen view, the number next to the “Meetings - Feature: Add to connection validation that managed directory is empty for Nextcloud storages \[[#57347](https://community.openproject.org/wp/57347)\] - Feature: Turn project list into favorite without reloading the page \[[#57505](https://community.openproject.org/wp/57505)\] - Feature: Remove menu entry "Projects" from "System settings" submenu in the Administration \[[#57536](https://community.openproject.org/wp/57536)\] -- Feature: Replace "Add assignee" button in Team Pleanner with "+ Assignee" \[[#57648](https://community.openproject.org/wp/57648)\] +- Feature: Replace "Add assignee" button in Team Planner with "+ Assignee" \[[#57648](https://community.openproject.org/wp/57648)\] - Feature: Update all clickable elements inside the box elements with the link color \[[#57649](https://community.openproject.org/wp/57649)\] - Feature: Keep scroll position when reloading a meeting through the update flash \[[#57904](https://community.openproject.org/wp/57904)\] - Feature: Improvements to the Participants side panel (phrasing and spacing) \[[#57911](https://community.openproject.org/wp/57911)\] @@ -143,4 +143,4 @@ Last but not least, we are very grateful for our very engaged translation contri - [BigSeung](https://crowdin.com/profile/BigSeung), for translations into Korean. - [Raffaele Brevetti](https://crowdin.com/profile/rbrevetti), for translations into Italian. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/15-0-0/README.md b/docs/release-notes/15-0-0/README.md index 84e49020f158..809db56fbba1 100644 --- a/docs/release-notes/15-0-0/README.md +++ b/docs/release-notes/15-0-0/README.md @@ -169,7 +169,7 @@ For more information, please see our updated guides on these topics: - Feature: Primerised version of the basic work package hovercard \[[#58512](https://community.openproject.org/wp/58512)\] - Bugfix: Work package date picker: wrong spacing \[[#47777](https://community.openproject.org/wp/47777)\] - Bugfix: User is not taken to the secondary input field after selecting a filter \[[#53767](https://community.openproject.org/wp/53767)\] -- Bugfix: Creating project from template doesn't take over version filter correctly \[[#53978](https://community.openproject.org/wp/53978)\] +- Bugfix: Creating project from template doesn't take over version filter correctly \[[#53978](https://community.openproject.org/wp/53978)\] - Bugfix: \[mobile\] Scrolling within a modal scrolls the content underneath \[[#54109](https://community.openproject.org/wp/54109)\] - Bugfix: Missing "cause" in WP journal when closing duplicates \[[#54372](https://community.openproject.org/wp/54372)\] - Bugfix: The Assignee drop down list in the work packages list can't show long name perfectly. \[[#55870](https://community.openproject.org/wp/55870)\] @@ -187,10 +187,10 @@ For more information, please see our updated guides on these topics: - Bugfix: Topbar search input text color is too dark when unfocused \[[#57950](https://community.openproject.org/wp/57950)\] - Bugfix: The Activity entry for creation is lacking the info that it is a "Creation". \[[#57968](https://community.openproject.org/wp/57968)\] - Bugfix: Number of listed Work Packages limited to 20 only w/o button of page number for switching \[[#57977](https://community.openproject.org/wp/57977)\] -- Bugfix: Fix AMPF "Health status" error messages capitalisation \[[#58016](https://community.openproject.org/wp/58016)\] +- Bugfix: Fix AMPF "Health status" error messages capitalization \[[#58016](https://community.openproject.org/wp/58016)\] - Bugfix: User tab headers overlap when header text is long \[[#58106](https://community.openproject.org/wp/58106)\] - Bugfix: Dark mode: "Custom text" widget - table cell editing UI has wrong colors \[[#58108](https://community.openproject.org/wp/58108)\] -- Bugfix: Self notification doesn't trigger a notifcation and mail \[[#58151](https://community.openproject.org/wp/58151)\] +- Bugfix: Self notification doesn't trigger a notification and mail \[[#58151](https://community.openproject.org/wp/58151)\] - Bugfix: Unnecessary space to the right on certain view width \[[#58237](https://community.openproject.org/wp/58237)\] - Bugfix: Access token refresh results in error message in files tab \[[#58271](https://community.openproject.org/wp/58271)\] - Bugfix: Improve sidebar item alignment \[[#58280](https://community.openproject.org/wp/58280)\] @@ -200,7 +200,7 @@ For more information, please see our updated guides on these topics: - Bugfix: My page is empty if user has no permissions \[[#58341](https://community.openproject.org/wp/58341)\] - Bugfix: Update-Warning is not readable in dark mode \[[#58359](https://community.openproject.org/wp/58359)\] - Bugfix: Sorting custom actions by "sort" header produces 500 \[[#58361](https://community.openproject.org/wp/58361)\] -- Bugfix: Creating project from template doesn't take over version column correctly \[[#58388](https://community.openproject.org/wp/58388)\] +- Bugfix: Creating project from template doesn't take over version column correctly \[[#58388](https://community.openproject.org/wp/58388)\] - Bugfix: Meetings modules is not showing the sidebar selection in the PageHeader \[[#58393](https://community.openproject.org/wp/58393)\] - Bugfix: Enterprise banners have excessive top-margin \[[#58404](https://community.openproject.org/wp/58404)\] - Bugfix: Enterprise banner is not shown on "new board" page \[[#58411](https://community.openproject.org/wp/58411)\] @@ -212,7 +212,7 @@ For more information, please see our updated guides on these topics: - Bugfix: Improve error handling when two users edit the same work package in parallel (conflict) \[[#58634](https://community.openproject.org/wp/58634)\] - Bugfix: Slow project template selector on new project page \[[#58657](https://community.openproject.org/wp/58657)\] - Bugfix: Admin info "bug" icon is misleading \[[#58671](https://community.openproject.org/wp/58671)\] -- Bugfix: Emoji bar doesn't stay anchored \[[#58706](https://community.openproject.org/wp/58706)\] +- Bugfix: Emoji bar doesn't stay anchored \[[#58706](https://community.openproject.org/wp/58706)\] - Bugfix: Replace the + icon next to the work package creation item with a regular icon \[[#58735](https://community.openproject.org/wp/58735)\] - Bugfix: SAML UI migration fails if expired certificate present in current configuration \[[#58851](https://community.openproject.org/wp/58851)\] - Bugfix: OpenID connect provider does not show Redirect URI \[[#59057](https://community.openproject.org/wp/59057)\] @@ -235,4 +235,4 @@ Last but not least, we are very grateful for our very engaged translation contri - [hmmftg](https://crowdin.com/profile/hmmftg), for a great number of translations into Persian. - [william](https://crowdin.com/profile/WilliamFromTW), for a great number of translations into Chinese Simplified and Chinese Traditional. -Would you like to help out with translations yourself? Then take a look at our [translation guide](../../development/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! +Would you like to help out with translations yourself? Then take a look at our [translation guide](../../contributions-guide/translate-openproject/) and find out exactly how you can contribute. It is very much appreciated! diff --git a/docs/release-notes/15-0-1/README.md b/docs/release-notes/15-0-1/README.md new file mode 100644 index 000000000000..4802f363f2e4 --- /dev/null +++ b/docs/release-notes/15-0-1/README.md @@ -0,0 +1,28 @@ +--- +title: OpenProject 15.0.1 +sidebar_navigation: + title: 15.0.1 +release_version: 15.0.1 +release_date: 2024-11-13 +--- + +# OpenProject 15.0.1 + +Release date: 2024-11-13 + +We released OpenProject [OpenProject 15.0.1](https://community.openproject.org/versions/2157). +This release contains an important fix for OpenID Connect providers using Microsoft Entra. +The tenant of the Azure environment was not correctly communicated to the provider, resulting in failing logins. + +This has been fixed. If you are affected by this issue, please update to 15.0.1 and logins should be restored. + + +## Bug fixes and changes + + + + +- Bugfix: OpenID Connect Microsoft Entra: Tenant not correctly output \[[#59261](https://community.openproject.org/wp/59261)\] + + + diff --git a/docs/release-notes/15-0-2/README.md b/docs/release-notes/15-0-2/README.md new file mode 100644 index 000000000000..87f50df7b795 --- /dev/null +++ b/docs/release-notes/15-0-2/README.md @@ -0,0 +1,36 @@ +--- +title: OpenProject 15.0.2 +sidebar_navigation: + title: 15.0.2 +release_version: 15.0.2 +release_date: 2024-11-20 +--- + +# OpenProject 15.0.2 + +Release date: 2024-11-20 + +We released OpenProject [OpenProject 15.0.2](https://community.openproject.org/versions/2158). +The release contains several bug fixes and we recommend updating to the newest version. +In these Release Notes, we will give an overview of important feature changes. +At the end, you will find a complete list of all changes and bug fixes. + + + +## Bug fixes and changes + + + + +- Bugfix: Work package creation event not displayed if aggregation includes a comment \[[#58738](https://community.openproject.org/wp/58738)\] +- Bugfix: Error toast giving a 500 error without relevant details \[[#59065](https://community.openproject.org/wp/59065)\] +- Bugfix: The comment box remains open and does not blur on submitting comment \[[#59279](https://community.openproject.org/wp/59279)\] +- Bugfix: Split screen activity tab does not scroll to the right position from list view \[[#59281](https://community.openproject.org/wp/59281)\] +- Bugfix: Storage in copied project does not have the correct Project Folder setting \[[#59344](https://community.openproject.org/wp/59344)\] +- Bugfix: Cannot change limit\_self\_registration for SAML auth providers \[[#59370](https://community.openproject.org/wp/59370)\] +- Bugfix: Option to limit\_self\_registration in SAML provider not respected \[[#59375](https://community.openproject.org/wp/59375)\] +- Bugfix: Migration of SAML auth providers doesn't retain limit\_self\_registration \[[#59403](https://community.openproject.org/wp/59403)\] +- Bugfix: OpenID connect does not allow setting custom scopes \[[#59430](https://community.openproject.org/wp/59430)\] + + + diff --git a/docs/release-notes/15-1-0/README.md b/docs/release-notes/15-1-0/README.md new file mode 100644 index 000000000000..ef71de6e2d42 --- /dev/null +++ b/docs/release-notes/15-1-0/README.md @@ -0,0 +1,79 @@ +--- +title: OpenProject 15.1.0 +sidebar_navigation: + title: 15.1.0 +release_version: 15.1.0 +release_date: 2024-11-28 +--- + +# OpenProject 15.1.0 + +Release date: 2024-11-28 + +We released OpenProject [OpenProject 15.1.0](https://community.openproject.org/versions/2122). +The release contains several bug fixes and we recommend updating to the newest version. +In these Release Notes, we will give an overview of important feature changes. +At the end, you will find a complete list of all changes and bug fixes. + +## Important feature changes + + + +## Important updates and breaking changes + + + + + +## Bug fixes and changes + + + + +- Feature: Multi-level selection fields to support custom hierarchical attributes \[[#36033](https://community.openproject.org/wp/36033)\] +- Bugfix: Unsorted "User" list in "Time and costs" \[[#43829](https://community.openproject.org/wp/43829)\] +- Bugfix: 500 when filtering by date field and specifying too big number \[[#55393](https://community.openproject.org/wp/55393)\] +- Bugfix: Sorting by custom field has strong impact on performance for the project list \[[#57305](https://community.openproject.org/wp/57305)\] +- Bugfix: Absent value for custom field is ordered not consistently at the beginning or end for different formats \[[#57554](https://community.openproject.org/wp/57554)\] +- Bugfix: Notification on a mention added to an edited comment is not triggered \[[#58007](https://community.openproject.org/wp/58007)\] +- Bugfix: Sidebar menu should be hidden when page width is reduced \[[#58454](https://community.openproject.org/wp/58454)\] +- Bugfix: Info box on new custom field of type hierarchy is permanent \[[#58466](https://community.openproject.org/wp/58466)\] +- Bugfix: Item add form disappears after added a new item to a custom field of type hierarchy \[[#58467](https://community.openproject.org/wp/58467)\] +- Bugfix: Using multi-select and required options do not work \[[#58635](https://community.openproject.org/wp/58635)\] +- Bugfix: HTML files served as plain text \[[#58646](https://community.openproject.org/wp/58646)\] +- Bugfix: Performance issues on work\_packages api endpoint \[[#58689](https://community.openproject.org/wp/58689)\] +- Bugfix: Breadcrumb of hierarchy items has left margin \[[#58700](https://community.openproject.org/wp/58700)\] +- Bugfix: Add local spacing to inline enterprise banner \[[#59284](https://community.openproject.org/wp/59284)\] +- Bugfix: Hierarchy custom fields causing 500 on custom actions \[[#59354](https://community.openproject.org/wp/59354)\] +- Bugfix: Signing in after two factor methods have been deleted lead to a 500 error \[[#59408](https://community.openproject.org/wp/59408)\] +- Bugfix: User without permission to "Save views" can save changes to work package views \[[#59479](https://community.openproject.org/wp/59479)\] +- Bugfix: Double provider showing on OpenID provider list \[[#59510](https://community.openproject.org/wp/59510)\] +- Bugfix: Hierarchy items not correctly displayed if custom field is shown in wp table \[[#59572](https://community.openproject.org/wp/59572)\] +- Bugfix: Buttons not visible on iOS in edit relations modal \[[#59772](https://community.openproject.org/wp/59772)\] +- Feature: Work package PDF export: Insert page breaks \[[#44047](https://community.openproject.org/wp/44047)\] +- Feature: Zen mode for project lists page \[[#52150](https://community.openproject.org/wp/52150)\] +- Feature: Create and edit custom field of type hierarchy \[[#57806](https://community.openproject.org/wp/57806)\] +- Feature: Enable ordering of hierarchy values of same level \[[#57820](https://community.openproject.org/wp/57820)\] +- Feature: Enable assignment of hierarchy values to work packages \[[#57824](https://community.openproject.org/wp/57824)\] +- Feature: Enable filtering on custom fields of type hierarchy \[[#57825](https://community.openproject.org/wp/57825)\] +- Feature: Primerised Meeting index pages \[[#57854](https://community.openproject.org/wp/57854)\] +- Feature: Re-design Relations tab according to Figma mockups (Primerise) \[[#58345](https://community.openproject.org/wp/58345)\] +- Feature: Move primary action to subheader \[[#58636](https://community.openproject.org/wp/58636)\] +- Feature: Validate uniqueness of short names of hierarchy items \[[#58852](https://community.openproject.org/wp/58852)\] +- Feature: Add enterprise gateway to creation of custom fields of type hierarchy \[[#58865](https://community.openproject.org/wp/58865)\] +- Feature: Primer: Implement proper mobile behaviour for BoxTable \[[#59248](https://community.openproject.org/wp/59248)\] +- Feature: Allow locking of the seeded admin user \[[#59722](https://community.openproject.org/wp/59722)\] + + + + +## Contributions +A very special thank you goes to our sponsors for this release. +Also a big thanks to our Community members for reporting bugs and helping us identify and provide fixes. +Special thanks for reporting and finding bugs go to Frank Long, Claudio Pagnani, Ivan Kuchin, samuel law, Gerrit B.. + +Last but not least, we are very grateful for our very engaged translation contributors on Crowdin, who translated quite a few OpenProject strings! +Would you like to help out with translations yourself? +Then take a look at our translation guide and find out exactly how you can contribute. +It is very much appreciated! + diff --git a/docs/release-notes/README.md b/docs/release-notes/README.md index 0df98a76e026..0aa676ccdc3e 100644 --- a/docs/release-notes/README.md +++ b/docs/release-notes/README.md @@ -13,6 +13,20 @@ Stay up to date and get an overview of the new features included in the releases +## 15.0.2 + +Release date: 2024-11-20 + +[Release Notes](15-0-2/) + + +## 15.0.1 + +Release date: 2024-11-13 + +[Release Notes](15-0-1/) + + ## 15.0.0 Release date: 2024-11-13 diff --git a/docs/system-admin-guide/authentication/openid-providers/README.md b/docs/system-admin-guide/authentication/openid-providers/README.md index 059878d9edaf..832d24d306dc 100644 --- a/docs/system-admin-guide/authentication/openid-providers/README.md +++ b/docs/system-admin-guide/authentication/openid-providers/README.md @@ -92,7 +92,7 @@ After pressing **CREATE** you will see a following pop-up window. - On the next section, set **Client ID** and **Client Secret** (from step 2) - Enable **Limit self registration** option if you want users that create accounts with this provider to bypass the configured limit for self-registration. -![Add a new OpenID Gogole provider in OpenProject administration](openproject_system-admin-guide_authentication_openid_provider_new_google.png) +![Add a new OpenID Google provider in OpenProject administration](openproject_system-admin-guide_authentication_openid_provider_new_google.png) Press **Finish setup** to save the client and complete. If you go back to the index page of OpenID connect providers, the new provider should be visible. @@ -281,7 +281,7 @@ The option takes a space-separated list of ACR values. This is functionally the After entering Claims information, click **Finish setup** to complete the provider creation form. -![Bildschirmfoto 2024-11-06 um 18.34.28](./custom-provider-claims.png) +![Custom provider claims](./custom-provider-claims.png) diff --git a/docs/system-admin-guide/design/README.md b/docs/system-admin-guide/design/README.md index dea2a33f2c21..bfda59f151d0 100644 --- a/docs/system-admin-guide/design/README.md +++ b/docs/system-admin-guide/design/README.md @@ -13,9 +13,9 @@ Navigate to *Administration* -> *Design* in order to customize your OpenProject The design page provides several options to customize your OpenProject Enterprise edition, grouped under three tabs, **Interface, Branding, PDF export styles**. You can [choose a color theme](#choose-a-color-theme) under any of these tabs. -Under **Interface** you can also choose [custom colors](#interface-colors) for elements of the interface such as the primary button colour, accent colour, the background of the top navigation header and the main menu. +Under **Interface** you can also choose [custom colors](#interface-colors) for elements of the interface such as the primary button color, accent color, the background of the top navigation header and the main menu. -![Design interface settings in OpenProject adminstration](openproject_system_guide_design_interface.png) +![Design interface settings in OpenProject administration](openproject_system_guide_design_interface.png) Under the **Branding** tab you can also [upload a custom logo](#upload-a-custom-logo) to replace the default OpenProject logo, [set a custom favicon](#set-a-custom-favicon), which is shown as an icon in your browser window/tab, and [upload a custom touch icon](#set-a-custom-touch-icon), which is shown on your smartphone or tablet when you bookmark OpenProject on your home screen. @@ -47,7 +47,7 @@ Click the *Upload* button to confirm and upload your logo. -![Custom logo updated in OpenProject admistration](openproject_system_guide_design_custom_logo_uploaded.png) +![Custom logo updated in OpenProject administration](openproject_system_guide_design_custom_logo_uploaded.png) ## Set a custom favicon diff --git a/docs/system-admin-guide/integrations/nextcloud/README.md b/docs/system-admin-guide/integrations/nextcloud/README.md index 6d000a6af482..ce03a0575deb 100644 --- a/docs/system-admin-guide/integrations/nextcloud/README.md +++ b/docs/system-admin-guide/integrations/nextcloud/README.md @@ -180,7 +180,7 @@ To add a Nextcloud to a specific project on a project level, navigate to any exi To add a Nextcloud storage to one or multiple projects on an instance level, click on a file storage under *Administration -> Files -> External file storages* and select **Enabled in projects** tab. If the file storage setup was not completed properly, you will see a respective message. -![Storage setup incomplete message in OprnProject file storages administration](openproject_system_guide_nextcloud_integration_setup_incomplete_message.png) +![Storage setup incomplete message in OpenProject file storages administration](openproject_system_guide_nextcloud_integration_setup_incomplete_message.png) If the storage was set up correctly, you will be able activate the file storage for one or multiple projects. To do that click the **+Add projects** button. diff --git a/docs/system-admin-guide/system-settings/languages/README.md b/docs/system-admin-guide/system-settings/languages/README.md index d9ce3c840d3e..a3cf4db9b564 100644 --- a/docs/system-admin-guide/system-settings/languages/README.md +++ b/docs/system-admin-guide/system-settings/languages/README.md @@ -14,6 +14,6 @@ The Languages page lets you select languages you would like to activate from the At the moment there are over 30 languages available. > [!NOTE] -> Many languages are translated by the community. We highly appreciate if you want to [help translating OpenProject to your language](../../../development/translate-openproject). +> Many languages are translated by the community. We highly appreciate if you want to [help translating OpenProject to your language](../../../contributions-guide/translate-openproject). You can [choose your language in your user profile](../../../user-guide/account-settings/#change-your-language). diff --git a/docs/use-cases/safe-framework/README.md b/docs/use-cases/safe-framework/README.md index 5216fc294fb1..77a0e48afe16 100644 --- a/docs/use-cases/safe-framework/README.md +++ b/docs/use-cases/safe-framework/README.md @@ -77,11 +77,13 @@ You can also use [project templates](../../user-guide/projects/project-templates Project portfolios allow you to view, organize, sort and filter through all projects and their hierarchies. Since individual projects represent Agile Release trains, project portfolios can be used to access information at a **Solution train**-level. -![All Features and User Stories across all teams](all_features_across_all_teams.png) +OpenProject offers a new **Project list** view that lets you create and save custom lists of Projects using your own set of filter criteria. These lists can also display custom project attributes. Individual projects can also be favourited for easier access. Project lists allow you to be build very precise and useful dashboards at a solution-train level. -> In a near future release, OpenProject will have dedicated project portfolio features. [View mockups.](https://www.figma.com/file/YCCMdJWkrtP9YSmf49Od0i/Project-lists?type=design&node-id=470%3A13037&mode=design&t=g1EZesuy0Jj0VZFD-1) -> -> For the moment, [global modules](../../user-guide/home/global-modules/) give you an overview of content from all projects, including the ability to view and filter though a **project list**, and view, sort and filter **work packages at a global level**. +![You can create custom project lists](project_list_-_solution_train.png) + +Alternatively, one can also create a meta-project that contains multiple sub-projects (representing ARTs and teams) and create a consolidated custom view. This **work package table** view can be filtered and customised to show particular attributes and custom fields as columns, grouped and sorted. They can also be configured to display epics, features and user stories not just from sub-projects, but from entirely different projects. + +![All Features and User Stories across all teams](all_features_across_all_teams.png) > **Demo:** [Solution train (project list)](https://safe.openproject.com/projects) > diff --git a/docs/use-cases/safe-framework/project_list_-_solution_train.png b/docs/use-cases/safe-framework/project_list_-_solution_train.png new file mode 100644 index 000000000000..b8a8dcac5c80 Binary files /dev/null and b/docs/use-cases/safe-framework/project_list_-_solution_train.png differ diff --git a/docs/user-guide/activity/README.md b/docs/user-guide/activity/README.md index eb8225311e3c..7ceffd6c3dcf 100644 --- a/docs/user-guide/activity/README.md +++ b/docs/user-guide/activity/README.md @@ -16,7 +16,7 @@ The Activity tab within a work package maintains a history of all updates and ch ![The work package Activity tab split screen](Activity-tab.png) -When you first access this tab, you will see the comments and list of changes in a timeline. This timeline can be sorted in either chronological (the newest comments at the bottom) or antichronological order (the newest comments on top): +When you first access this tab, you will see the comments and list of changes in a timeline. This timeline can be sorted in either chronological (the newest comments at the bottom) or anti-chronological order (the newest comments on top): ![You can order the activities to show newest on top or at the bottom](Activity-sortOrder.png) diff --git a/docs/user-guide/notifications/README.md b/docs/user-guide/notifications/README.md index 6d7fda907ef0..eed7300dad35 100644 --- a/docs/user-guide/notifications/README.md +++ b/docs/user-guide/notifications/README.md @@ -73,7 +73,7 @@ In addition to the in-app notifications, you will also get a once-a-day summary Click on the **Mark as read** button represented by the envelope icon on the right side of the notification row. This will mark all the notifications for that work package (indicated by the number on the blue badge) as read. You can also use the **Mark as Read** button at the bottom of the split-screen view of a work package to achieve the same result. -![Mark notifications as read in OpenProject noticification center](openproject_user_guide_notification_center_mark_read_envelope.png) +![Mark notifications as read in OpenProject notifications center](openproject_user_guide_notification_center_mark_read_envelope.png) Additionally, you can mark notifications as read in the work package full screen view by clicking on the envelope icon in the upper right corner of the details view. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index e0e35061dbb9..84ad47af62a9 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -47,11 +47,11 @@ "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", "@openproject/octicons-angular": "^19.19.0", - "@openproject/primer-view-components": "^0.48.2", + "@openproject/primer-view-components": "^0.49.2", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.5.0", "@primer/primitives": "^9.1.2", - "@primer/view-components": "npm:@openproject/primer-view-components@^0.48.2", + "@primer/view-components": "npm:@openproject/primer-view-components@^0.49.2", "@types/hotwired__turbo": "^8.0.1", "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", @@ -1147,9 +1147,9 @@ } }, "node_modules/@appsignal/javascript": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@appsignal/javascript/-/javascript-1.4.1.tgz", - "integrity": "sha512-jdZdXvMWLVdCVtVUbgK45WpxK/FQguQL4EI21ebUib4ySQXU1Hdy2Z6uU8AOcM/CfGtmCIil7EcjEwJMH5UFQg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@appsignal/javascript/-/javascript-1.5.0.tgz", + "integrity": "sha512-Wbf7pzUtksK70ci8kTOhVjd3zgeGFSwXqsGH8Pa/D9b3opJwUwDjbDLhdH7dFSE/lIKWKPoynzOIG+nRHND3vQ==", "dependencies": { "@appsignal/core": "=1.1.24", "@appsignal/types": "=3.0.1", @@ -1157,11 +1157,11 @@ } }, "node_modules/@appsignal/plugin-breadcrumbs-console": { - "version": "1.1.34", - "resolved": "https://registry.npmjs.org/@appsignal/plugin-breadcrumbs-console/-/plugin-breadcrumbs-console-1.1.34.tgz", - "integrity": "sha512-BcfiQ9NEqxVKeZrG/tPWf+VVwwpe/DDZemfYel6X2X2Q5E26fDqmE997dpeo4S5xoPhZnWvs/fMBX6sdTxJ0xg==", + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@appsignal/plugin-breadcrumbs-console/-/plugin-breadcrumbs-console-1.1.35.tgz", + "integrity": "sha512-3dtblBrWDewQZvipBmwEka44Y+pgQpHQpnu/P9kZqtMuNNuRDRom1+0nIL2PV73jsmbxz+En2rwqTRBxahFZxQ==", "dependencies": { - "@appsignal/javascript": "=1.4.1" + "@appsignal/javascript": "=1.5.0" } }, "node_modules/@appsignal/plugin-breadcrumbs-network": { @@ -3910,6 +3910,11 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "node_modules/@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" + }, "node_modules/@ljharb/through": { "version": "2.3.13", "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", @@ -4086,9 +4091,9 @@ } }, "node_modules/@ngx-formly/core": { - "version": "6.3.10", - "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.10.tgz", - "integrity": "sha512-YWS+0ts3aeyX7iQQop3exffmKsub5ZD18EnZPuoHSCCglLRS0tB8ra3kFTaYT0dyc8mXRQyES9TulbX9+ZdRFg==", + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.11.tgz", + "integrity": "sha512-C/k1bbBjIKM5SnpGl9eHe0EcTlXlxYBg9u5JCWuh8GgR2BPXAaBcXfTcsrp4SRDLSXre/GyxWt4iCLjPWCZ/ug==", "dependencies": { "tslib": "^2.0.0" }, @@ -4823,10 +4828,9 @@ } }, "node_modules/@openproject/primer-view-components": { - "version": "0.48.2", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.48.2.tgz", - "integrity": "sha512-mzc2mRRzaMq5h6TJvpvuaJM6wLpYp9kTpRToVEcCTW18SuP8PnV7/M9impsIehn2UQzP2gqFnK89Xa7CUayhjQ==", - "license": "MIT", + "version": "0.49.2", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.49.2.tgz", + "integrity": "sha512-bpzWRsamWLj0H9VD9jSVC7r/VS9dw+ES6w/tCbjmXKrpDUFOD6m4EN7anrZoH/l7ogp0b4ByN2cGR4H5Ucyn5w==", "dependencies": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -4839,7 +4843,11 @@ "@github/remote-input-element": "^0.4.0", "@github/tab-container-element": "^3.1.2", "@oddbird/popover-polyfill": "^0.4.0", - "@primer/behaviors": "^1.3.4" + "@primer/behaviors": "^1.3.4", + "@primer/live-region-element": "^0.7.1" + }, + "peerDependencies": { + "@primer/primitives": "9.x || 10.x" } }, "node_modules/@openproject/reactivestates": { @@ -4898,6 +4906,14 @@ "@primer/primitives": "9.x || 10.x" } }, + "node_modules/@primer/live-region-element": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@primer/live-region-element/-/live-region-element-0.7.2.tgz", + "integrity": "sha512-wdxCHfcJzE1IPPjZNFR4RTwRcSWb7TN0fRdMH5HcxphLEnuZBWy0TAxk3xPA+/6lwiN3uEJ+ZWV4UF/glXh43A==", + "dependencies": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, "node_modules/@primer/primitives": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-9.1.2.tgz", @@ -4909,10 +4925,9 @@ }, "node_modules/@primer/view-components": { "name": "@openproject/primer-view-components", - "version": "0.48.2", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.48.2.tgz", - "integrity": "sha512-mzc2mRRzaMq5h6TJvpvuaJM6wLpYp9kTpRToVEcCTW18SuP8PnV7/M9impsIehn2UQzP2gqFnK89Xa7CUayhjQ==", - "license": "MIT", + "version": "0.49.2", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.49.2.tgz", + "integrity": "sha512-bpzWRsamWLj0H9VD9jSVC7r/VS9dw+ES6w/tCbjmXKrpDUFOD6m4EN7anrZoH/l7ogp0b4ByN2cGR4H5Ucyn5w==", "dependencies": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -4925,7 +4940,11 @@ "@github/remote-input-element": "^0.4.0", "@github/tab-container-element": "^3.1.2", "@oddbird/popover-polyfill": "^0.4.0", - "@primer/behaviors": "^1.3.4" + "@primer/behaviors": "^1.3.4", + "@primer/live-region-element": "^0.7.1" + }, + "peerDependencies": { + "@primer/primitives": "9.x || 10.x" } }, "node_modules/@probe.gl/env": { @@ -5540,9 +5559,9 @@ "dev": true }, "node_modules/@types/hotwired__turbo": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.1.tgz", - "integrity": "sha512-EloDlDDxlicl22+gFc77f7j16b8nCUvy6iyCtpICTlofAJfMCfnXNC8nYXCnVApes3BtWklAc2f3RKQgpaaFRQ==" + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.2.tgz", + "integrity": "sha512-fFWI/JNSTVKTPliSOV4fdeC3Kt3FUTbRYkvtF7QPCkqR51+AJWIiX0T5sJXwUnjL9j43tzfBXPZ2jEsBqw8/Bg==" }, "node_modules/@types/http-errors": { "version": "2.0.1", @@ -8937,9 +8956,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -22773,9 +22792,9 @@ } }, "@appsignal/javascript": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@appsignal/javascript/-/javascript-1.4.1.tgz", - "integrity": "sha512-jdZdXvMWLVdCVtVUbgK45WpxK/FQguQL4EI21ebUib4ySQXU1Hdy2Z6uU8AOcM/CfGtmCIil7EcjEwJMH5UFQg==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@appsignal/javascript/-/javascript-1.5.0.tgz", + "integrity": "sha512-Wbf7pzUtksK70ci8kTOhVjd3zgeGFSwXqsGH8Pa/D9b3opJwUwDjbDLhdH7dFSE/lIKWKPoynzOIG+nRHND3vQ==", "requires": { "@appsignal/core": "=1.1.24", "@appsignal/types": "=3.0.1", @@ -22783,11 +22802,11 @@ } }, "@appsignal/plugin-breadcrumbs-console": { - "version": "1.1.34", - "resolved": "https://registry.npmjs.org/@appsignal/plugin-breadcrumbs-console/-/plugin-breadcrumbs-console-1.1.34.tgz", - "integrity": "sha512-BcfiQ9NEqxVKeZrG/tPWf+VVwwpe/DDZemfYel6X2X2Q5E26fDqmE997dpeo4S5xoPhZnWvs/fMBX6sdTxJ0xg==", + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@appsignal/plugin-breadcrumbs-console/-/plugin-breadcrumbs-console-1.1.35.tgz", + "integrity": "sha512-3dtblBrWDewQZvipBmwEka44Y+pgQpHQpnu/P9kZqtMuNNuRDRom1+0nIL2PV73jsmbxz+En2rwqTRBxahFZxQ==", "requires": { - "@appsignal/javascript": "=1.4.1" + "@appsignal/javascript": "=1.5.0" } }, "@appsignal/plugin-breadcrumbs-network": { @@ -24630,6 +24649,11 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, + "@lit-labs/ssr-dom-shim": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.1.tgz", + "integrity": "sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==" + }, "@ljharb/through": { "version": "2.3.13", "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", @@ -24776,9 +24800,9 @@ "integrity": "sha512-SfTCbplt4y6ak5cf2IfqdoVOsnoNdh/j6Vu+wb8WWABKwZ5yfr2S/Gk6ithSKcdIZhAF8DNBOoyk1EJuf8Xkfg==" }, "@ngx-formly/core": { - "version": "6.3.10", - "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.10.tgz", - "integrity": "sha512-YWS+0ts3aeyX7iQQop3exffmKsub5ZD18EnZPuoHSCCglLRS0tB8ra3kFTaYT0dyc8mXRQyES9TulbX9+ZdRFg==", + "version": "6.3.11", + "resolved": "https://registry.npmjs.org/@ngx-formly/core/-/core-6.3.11.tgz", + "integrity": "sha512-C/k1bbBjIKM5SnpGl9eHe0EcTlXlxYBg9u5JCWuh8GgR2BPXAaBcXfTcsrp4SRDLSXre/GyxWt4iCLjPWCZ/ug==", "requires": { "tslib": "^2.0.0" } @@ -25264,9 +25288,9 @@ } }, "@openproject/primer-view-components": { - "version": "0.48.2", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.48.2.tgz", - "integrity": "sha512-mzc2mRRzaMq5h6TJvpvuaJM6wLpYp9kTpRToVEcCTW18SuP8PnV7/M9impsIehn2UQzP2gqFnK89Xa7CUayhjQ==", + "version": "0.49.2", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.49.2.tgz", + "integrity": "sha512-bpzWRsamWLj0H9VD9jSVC7r/VS9dw+ES6w/tCbjmXKrpDUFOD6m4EN7anrZoH/l7ogp0b4ByN2cGR4H5Ucyn5w==", "requires": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -25279,7 +25303,8 @@ "@github/remote-input-element": "^0.4.0", "@github/tab-container-element": "^3.1.2", "@oddbird/popover-polyfill": "^0.4.0", - "@primer/behaviors": "^1.3.4" + "@primer/behaviors": "^1.3.4", + "@primer/live-region-element": "^0.7.1" } }, "@openproject/reactivestates": { @@ -25320,6 +25345,14 @@ "resolved": "https://registry.npmjs.org/@primer/css/-/css-21.5.1.tgz", "integrity": "sha512-/dw7P2eHbLEq77E6WVhVPud/HtyzAzlQgX6f8HQ/i0l1r5EZeh9r7/THgMUt0MgdSlJb7t+WT+V+zN8EDkU9mw==" }, + "@primer/live-region-element": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@primer/live-region-element/-/live-region-element-0.7.2.tgz", + "integrity": "sha512-wdxCHfcJzE1IPPjZNFR4RTwRcSWb7TN0fRdMH5HcxphLEnuZBWy0TAxk3xPA+/6lwiN3uEJ+ZWV4UF/glXh43A==", + "requires": { + "@lit-labs/ssr-dom-shim": "^1.2.0" + } + }, "@primer/primitives": { "version": "9.1.2", "resolved": "https://registry.npmjs.org/@primer/primitives/-/primitives-9.1.2.tgz", @@ -25330,9 +25363,9 @@ } }, "@primer/view-components": { - "version": "npm:@openproject/primer-view-components@0.48.2", - "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.48.2.tgz", - "integrity": "sha512-mzc2mRRzaMq5h6TJvpvuaJM6wLpYp9kTpRToVEcCTW18SuP8PnV7/M9impsIehn2UQzP2gqFnK89Xa7CUayhjQ==", + "version": "npm:@openproject/primer-view-components@0.49.2", + "resolved": "https://registry.npmjs.org/@openproject/primer-view-components/-/primer-view-components-0.49.2.tgz", + "integrity": "sha512-bpzWRsamWLj0H9VD9jSVC7r/VS9dw+ES6w/tCbjmXKrpDUFOD6m4EN7anrZoH/l7ogp0b4ByN2cGR4H5Ucyn5w==", "requires": { "@github/auto-check-element": "^5.2.0", "@github/auto-complete-element": "^3.6.2", @@ -25345,7 +25378,8 @@ "@github/remote-input-element": "^0.4.0", "@github/tab-container-element": "^3.1.2", "@oddbird/popover-polyfill": "^0.4.0", - "@primer/behaviors": "^1.3.4" + "@primer/behaviors": "^1.3.4", + "@primer/live-region-element": "^0.7.1" } }, "@probe.gl/env": { @@ -25801,9 +25835,9 @@ "dev": true }, "@types/hotwired__turbo": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.1.tgz", - "integrity": "sha512-EloDlDDxlicl22+gFc77f7j16b8nCUvy6iyCtpICTlofAJfMCfnXNC8nYXCnVApes3BtWklAc2f3RKQgpaaFRQ==" + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.2.tgz", + "integrity": "sha512-fFWI/JNSTVKTPliSOV4fdeC3Kt3FUTbRYkvtF7QPCkqR51+AJWIiX0T5sJXwUnjL9j43tzfBXPZ2jEsBqw8/Bg==" }, "@types/http-errors": { "version": "2.0.1", @@ -28299,9 +28333,9 @@ } }, "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", diff --git a/frontend/package.json b/frontend/package.json index 2c8f6372bd4b..98e4b60eab2e 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -99,11 +99,11 @@ "@ngneat/content-loader": "^7.0.0", "@ngx-formly/core": "^6.1.4", "@openproject/octicons-angular": "^19.19.0", - "@openproject/primer-view-components": "^0.48.2", + "@openproject/primer-view-components": "^0.49.2", "@openproject/reactivestates": "^3.0.1", "@primer/css": "^21.5.0", "@primer/primitives": "^9.1.2", - "@primer/view-components": "npm:@openproject/primer-view-components@^0.48.2", + "@primer/view-components": "npm:@openproject/primer-view-components@^0.49.2", "@types/hotwired__turbo": "^8.0.1", "@uirouter/angular": "^13.0.0", "@uirouter/core": "^6.1.0", @@ -176,7 +176,5 @@ "lint:fix": "esprint check --fix", "lint:eslint": "eslint", "generate-typings": "tsc -d -p src/tsconfig.app.json" - }, - "overrides": { } } diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts index a35c22a3565c..51d140173014 100644 --- a/frontend/src/app/app.module.ts +++ b/frontend/src/app/app.module.ts @@ -414,6 +414,8 @@ export class OpenProjectModule implements DoBootstrap { if (root) { appRef.bootstrap(ApplicationBaseComponent, root); } + + document.body.classList.add('__ng2-bootstrap-has-run'); } private registerCustomElements(injector:Injector) { diff --git a/frontend/src/app/core/state/file-links/file-links.service.ts b/frontend/src/app/core/state/file-links/file-links.service.ts index 67735b9b7ed7..c2626f87c193 100644 --- a/frontend/src/app/core/state/file-links/file-links.service.ts +++ b/frontend/src/app/core/state/file-links/file-links.service.ts @@ -88,7 +88,7 @@ export class FileLinksResourceService extends ResourceStoreService { }), tap((fileLinkCollections) => { const storageId = idFromLink(fileLinkCollections.storage); - const collectionKey = `${fileLinksSelfLink}?filters=[{"storage":{"operator":"=","values":["${storageId}"]}}]`; + const collectionKey = `${fileLinksSelfLink}?pageSize=-1&filters=[{"storage":{"operator":"=","values":["${storageId}"]}}]`; const collection = { _embedded: { elements: fileLinkCollections.fileLinks } } as IHALCollection; insertCollectionIntoState(this.store, collection, collectionKey); }), diff --git a/frontend/src/app/core/state/is-array-of.ts b/frontend/src/app/core/state/is-array-of.ts new file mode 100644 index 000000000000..77721cd4de10 --- /dev/null +++ b/frontend/src/app/core/state/is-array-of.ts @@ -0,0 +1,35 @@ +//-- copyright +// OpenProject is an open source project management software. +// Copyright (C) the OpenProject GmbH +// +// 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-2013 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 COPYRIGHT and LICENSE files for more details. +//++ + +export default function isArrayOf(array:unknown, type:new (...args:never[]) => T):array is T[] { + if (!Array.isArray(array)) { + return false; + } + + return array.every((item):item is T => item instanceof type); +} diff --git a/frontend/src/app/core/turbo/turbo-requests.service.ts b/frontend/src/app/core/turbo/turbo-requests.service.ts index da2ecacc0747..fdef90241755 100644 --- a/frontend/src/app/core/turbo/turbo-requests.service.ts +++ b/frontend/src/app/core/turbo/turbo-requests.service.ts @@ -13,19 +13,26 @@ export class TurboRequestsService { public request(url:string, init:RequestInit = {}, suppressErrorToast = false):Promise<{ html:string, headers:Headers }> { return fetch(url, init) .then((response) => { - if (!response.ok) { - throw new Error(`HTTP ${response.status}: ${response.statusText}`); - } return response.text().then((html) => ({ html, headers: response.headers, + response, })); }) .then((result) => { + // the result may contain a primer error banner if any server side error appeared + // thus we need to render the html even for non-ok responses renderStreamMessage(result.html); - return result; + // after rendering the html, check if the response and throw an error if it's not ok + if (!result.response.ok) { + throw new Error(result.response.statusText); + } else { + // enable further processing of the html and headers in the calling function + return { html: result.html, headers: result.headers }; + } }) .catch((error) => { + // this should only catch errors happening in the client side parsing in the above .then() calls if (!suppressErrorToast) { this.toast.addError(error as string); } else { diff --git a/frontend/src/app/features/homescreen/blocks/new-features.component.ts b/frontend/src/app/features/homescreen/blocks/new-features.component.ts index 3b0847db4439..204f008bbee5 100644 --- a/frontend/src/app/features/homescreen/blocks/new-features.component.ts +++ b/frontend/src/app/features/homescreen/blocks/new-features.component.ts @@ -33,9 +33,9 @@ import { I18nService } from 'core-app/core/i18n/i18n.service'; import { imagePath } from 'core-app/shared/helpers/images/path-helper'; // The key used in the I18n files to distinguish between versions. -const OpVersionI18n = '15_0'; +const OpVersionI18n = '15_1'; -const OpReleaseURL = 'https://www.openproject.org/docs/release-notes/15-0-0/'; +const OpReleaseURL = 'https://www.openproject.org/docs/release-notes/15-1-0/'; /** Update the teaser image to the next version */ const featureTeaserImage = `${OpVersionI18n}_features.svg`; diff --git a/frontend/src/app/features/work-packages/components/filters/filter-searchable-multiselect-value/filter-searchable-multiselect-value.component.ts b/frontend/src/app/features/work-packages/components/filters/filter-searchable-multiselect-value/filter-searchable-multiselect-value.component.ts index bf5db2d53ee4..dd259d3ed05d 100644 --- a/frontend/src/app/features/work-packages/components/filters/filter-searchable-multiselect-value/filter-searchable-multiselect-value.component.ts +++ b/frontend/src/app/features/work-packages/components/filters/filter-searchable-multiselect-value/filter-searchable-multiselect-value.component.ts @@ -109,19 +109,29 @@ export class FilterSearchableMultiselectValueComponent extends UntilDestroyedMix switchMap((initialLoad) => { // If we already loaded all values, just compare in the frontend if (initialLoad.count === initialLoad.total) { - return this.matchingItems(initialLoad.elements, matching); + return this.matchingItems(this.filterEmptyElements(initialLoad.elements), matching); } // Otherwise, request the matching API call return this .loadCollection(matching) .pipe( - switchMap((collection) => this.withMeValue(matching, collection.elements)), + switchMap( + (collection) => + this.withMeValue( + matching, + this.filterEmptyElements(collection.elements), + ), + ), ); }), ); } + private filterEmptyElements(elements:HalResource[]):HalResource[] { + return elements.filter((element) => element.name.trim().length !== 0); + } + matchingItems(elements:HalResource[], matching:string):Observable { let filtered:HalResource[]; diff --git a/frontend/src/app/features/work-packages/components/wp-fast-table/handlers/row/wp-state-links-handler.ts b/frontend/src/app/features/work-packages/components/wp-fast-table/handlers/row/wp-state-links-handler.ts index 4eb6bcceadd6..f566f71a38af 100644 --- a/frontend/src/app/features/work-packages/components/wp-fast-table/handlers/row/wp-state-links-handler.ts +++ b/frontend/src/app/features/work-packages/components/wp-fast-table/handlers/row/wp-state-links-handler.ts @@ -48,7 +48,6 @@ export class WorkPackageStateLinksHandler implements TableEventHandler { } // Locate the details link from event - // debugger; const target = evt.target as HTMLElement; const element = target.closest(this.SELECTOR) as HTMLElement & { dataset:DOMStringMap }; const state = element.dataset.wpState; diff --git a/frontend/src/app/features/work-packages/components/wp-relations/embedded/relations/wp-relation-inline-create.service.ts b/frontend/src/app/features/work-packages/components/wp-relations/embedded/relations/wp-relation-inline-create.service.ts index 4895ec71725e..df66e0976a4c 100644 --- a/frontend/src/app/features/work-packages/components/wp-relations/embedded/relations/wp-relation-inline-create.service.ts +++ b/frontend/src/app/features/work-packages/components/wp-relations/embedded/relations/wp-relation-inline-create.service.ts @@ -38,11 +38,14 @@ import { of, } from 'rxjs'; import idFromLink from 'core-app/features/hal/helpers/id-from-link'; +import { HalEventsService } from 'core-app/features/hal/services/hal-events.service'; @Injectable() export class WpRelationInlineCreateService extends WorkPackageInlineCreateService implements WpRelationInlineCreateServiceInterface, OnDestroy { @InjectField() wpRelations:WorkPackageRelationsService; + @InjectField() halEvents:HalEventsService; + constructor(public injector:Injector) { super(injector); } @@ -72,7 +75,13 @@ export class WpRelationInlineCreateService extends WorkPackageInlineCreateServic const relation = this.wpRelations.find(to, from, this.relationType); if (relation !== undefined) { - return this.wpRelations.removeRelation(relation); + return this.wpRelations.removeRelation(relation).then(() => { + this.halEvents.push(from, { + eventType: 'association', + relatedWorkPackage: to.id, + relationType: relation.normalizedType(from), + }); + }); } return Promise.reject(); } diff --git a/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.component.ts b/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.component.ts index 8666214892da..ffd5323c82f9 100644 --- a/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.component.ts +++ b/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.component.ts @@ -27,144 +27,132 @@ //++ import { - ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, + AfterViewInit, + ChangeDetectionStrategy, + Component, + ElementRef, + Input, + OnDestroy, + OnInit, + ViewChild, } from '@angular/core'; -import { I18nService } from 'core-app/core/i18n/i18n.service'; import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; -import { Observable, zip } from 'rxjs'; -import { take, takeUntil } from 'rxjs/operators'; +import { + debounceTime, + filter, +} from 'rxjs/operators'; import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; -import { componentDestroyed } from '@w11k/ngx-componentdestroyed'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; -import { RelationResource } from 'core-app/features/hal/resources/relation-resource'; -import { RelationsStateValue, WorkPackageRelationsService } from './wp-relations.service'; -import { RelatedWorkPackagesGroup } from './wp-relations.interfaces'; +import { WorkPackageRelationsService } from './wp-relations.service'; +import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; +import { TurboRequestsService } from 'core-app/core/turbo/turbo-requests.service'; +import { renderStreamMessage } from '@hotwired/turbo'; +import { + HalEventsService, + RelatedWorkPackageEvent, +} from 'core-app/features/hal/services/hal-events.service'; @Component({ selector: 'wp-relations', changeDetection: ChangeDetectionStrategy.OnPush, templateUrl: './wp-relations.template.html', }) -export class WorkPackageRelationsComponent extends UntilDestroyedMixin implements OnInit { +export class WorkPackageRelationsComponent extends UntilDestroyedMixin implements OnInit, AfterViewInit, OnDestroy { @Input() public workPackage:WorkPackageResource; - public relationGroups:RelatedWorkPackagesGroup = {}; - - public relationGroupKeys:string[] = []; - - public relationsPresent = false; + @ViewChild('frameElement') readonly relationTurboFrame:ElementRef; - public canAddRelation:boolean; + turboFrameSrc:string; - // By default, group by relation type - public groupByWorkPackageType = false; + private turboFrameListener:EventListener = this.updateFrontendData.bind(this); - public text = { - relations_header: this.I18n.t('js.work_packages.tabs.relations'), - }; - - public currentRelations:WorkPackageResource[] = []; - - constructor(private I18n:I18nService, + constructor( private wpRelations:WorkPackageRelationsService, - private cdRef:ChangeDetectorRef, - private apiV3Service:ApiV3Service) { + private apiV3Service:ApiV3Service, + private halEvents:HalEventsService, + private PathHelper:PathHelperService, + private turboRequests:TurboRequestsService, +) { super(); } ngOnInit() { - this.canAddRelation = !!this.workPackage.addRelation; + this.turboFrameSrc = `${this.PathHelper.staticBase}/work_packages/${this.workPackage.id}/relations_tab`; + } - this.wpRelations - .state(this.workPackage.id!) - .values$() - .pipe( - takeUntil(componentDestroyed(this)), - ) - .subscribe((relations:RelationsStateValue) => { - this.loadedRelations(relations); - }); + ngOnDestroy() { + super.ngOnDestroy(); - this.wpRelations.require(this.workPackage.id!); + document.removeEventListener('turbo:submit-end', this.turboFrameListener); + } - // Listen for changes to this WP. + ngAfterViewInit() { + // Listen to any changes to the relations and update the frame this - .apiV3Service - .work_packages - .id(this.workPackage) - .requireAndStream() + .halEvents + .events$ .pipe( - takeUntil(componentDestroyed(this)), + filter((e:RelatedWorkPackageEvent) => { + return e.eventType === 'association' + && e.id.toString() === this.workPackage.id?.toString() + && e.relationType !== 'parent'; + }), + debounceTime(500), + this.untilDestroyed(), ) - .subscribe((wp:WorkPackageResource) => { - this.workPackage = wp; + .subscribe(() => { + this.updateRelationsTab(); }); - } - - private getRelatedWorkPackages(workPackageIds:string[]):Observable { - const observablesToGetZipped:Observable[] = workPackageIds.map((wpId) => this - .apiV3Service - .work_packages - .id(wpId) - .get()); - return zip(...observablesToGetZipped); + /* + We globally listen for turbo:submit-end events to know when a form submission ends. + If the form action URL contains 'relation' or 'child', we know it is a relation or child creation/update. + In this case, we reload the relations state and push an updated event to the Hal resource + and the wpRelations service. + + The reason for this workaround is that the form submissions occur in top layer + as they originate from dialog elements or turbo confirm elements. Because of this, we + cannot listen to the submit end event on the relationTurboFrame element and have + to rely on the form action URL. + */ + document.addEventListener('turbo:submit-end', this.turboFrameListener); } - protected getRelatedWorkPackageId(relation:RelationResource):string { - const involved = relation.ids; - return (relation.to.href === this.workPackage.href) ? involved.from : involved.to; + public updateCounter() { + const url = this.PathHelper.workPackageUpdateCounterPath(this.workPackage.id!, 'relations'); + void this.turboRequests.request(url); } - public toggleGroupBy() { - this.groupByWorkPackageType = !this.groupByWorkPackageType; - this.buildRelationGroups(); - } - - protected buildRelationGroups() { - if (_.isNil(this.currentRelations)) { - return; - } - - this.relationGroups = _.groupBy(this.currentRelations, - (wp:WorkPackageResource) => { - if (this.groupByWorkPackageType) { - return wp.type.name; + private updateFrontendData(event:CustomEvent) { + if (event) { + const form = event.target as HTMLFormElement; + const updateWorkPackage = !!form.dataset?.updateWorkPackage; + + if (updateWorkPackage) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.detail && event.detail.success) { + // Update the work package + void this.apiV3Service + .work_packages + .id(this.workPackage.id!) + .refresh(); + this.halEvents.push(this.workPackage, { eventType: 'updated' }); + + // Refetch relations + void this.wpRelations.require(this.workPackage.id!, true); + + this.updateCounter(); } - const normalizedType = (wp.relatedBy as RelationResource).normalizedType(this.workPackage); - return this.I18n.t(`js.relation_labels.${normalizedType}`); - }); - this.relationGroupKeys = _.keys(this.relationGroups); - this.relationsPresent = _.size(this.relationGroups) > 0; - this.cdRef.detectChanges(); - } - - protected loadedRelations(stateValues:RelationsStateValue):void { - const relatedWpIds:string[] = []; - const relations:{ [wpId:string]:any } = []; - - if (_.size(stateValues) === 0) { - this.currentRelations = []; - return this.buildRelationGroups(); + } } + } - _.each(stateValues, (relation:RelationResource) => { - const relatedWpId = this.getRelatedWorkPackageId(relation); - relatedWpIds.push(relatedWpId); - relations[relatedWpId] = relation; - }); - - this.getRelatedWorkPackages(relatedWpIds) - .pipe( - take(1), - ) - .subscribe((relatedWorkPackages:WorkPackageResource[]) => { - this.currentRelations = relatedWorkPackages.map((wp:WorkPackageResource) => { - wp.relatedBy = relations[wp.id!]; - return wp; - }); - - this.buildRelationGroups(); + private updateRelationsTab() { + void this.turboRequests.requestStream(this.turboFrameSrc) + .then((result) => { + renderStreamMessage(result.html); }); + + this.updateCounter(); } } diff --git a/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.template.html b/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.template.html index ca7f5f4106e7..239502ea2c49 100644 --- a/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.template.html +++ b/frontend/src/app/features/work-packages/components/wp-relations/wp-relations.template.html @@ -1,33 +1,15 @@ -
-
-
-

-
-
+ + - + - + - -
+ + + diff --git a/frontend/src/app/features/work-packages/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts b/frontend/src/app/features/work-packages/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts index 05d78208de17..5233ec01d478 100644 --- a/frontend/src/app/features/work-packages/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts +++ b/frontend/src/app/features/work-packages/components/wp-table/context-menu-helper/wp-context-menu-helper.service.ts @@ -91,7 +91,7 @@ export class WorkPackageContextMenuHelperService { // remove some actions on Gantt if (this.wpViewTimeline.isVisible) { allowedActions = allowedActions.filter((el) => { - const ganttNotAllowedActions = ['log_time', 'copy', 'copy_to_other_project', 'export-pdf', 'export-atom', 'log_costs']; + const ganttNotAllowedActions = ['log_time', 'copy', 'copy_to_other_project', 'export-pdf', 'generate_pdf', 'export-atom', 'log_costs']; return !(ganttNotAllowedActions.includes(el.key)); }); } diff --git a/frontend/src/app/features/work-packages/components/wp-tabs/services/wp-tabs/wp-files-count.function.ts b/frontend/src/app/features/work-packages/components/wp-tabs/services/wp-tabs/wp-files-count.function.ts index 36f6bed47e36..dfc00da48d04 100644 --- a/frontend/src/app/features/work-packages/components/wp-tabs/services/wp-tabs/wp-files-count.function.ts +++ b/frontend/src/app/features/work-packages/components/wp-tabs/services/wp-tabs/wp-files-count.function.ts @@ -27,26 +27,38 @@ //++ import { Injector } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; import { combineLatest, Observable, of } from 'rxjs'; import { map } from 'rxjs/operators'; import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; -import { FileLinksResourceService } from 'core-app/core/state/file-links/file-links.service'; import { AttachmentsResourceService } from 'core-app/core/state/attachments/attachments.service'; +import { IHALCollection } from 'core-app/core/apiv3/types/hal-collection.type'; +import { IFileLink } from 'core-app/core/state/file-links/file-link.model'; export function workPackageFilesCount( workPackage:WorkPackageResource, injector:Injector, ):Observable { const attachmentService = injector.get(AttachmentsResourceService); - const fileLinkService = injector.get(FileLinksResourceService); + const http = injector.get(HttpClient); const attachmentsCollection = workPackage.$links.attachments ? attachmentService.collection(workPackage.$links.attachments.href || '') : of([]); - const fileLinksCollection = fileLinkService.collection(workPackage.$links.fileLinks?.href || ''); + const totalFileLinks = workPackage.$links.fileLinks + ? http.get>(href(workPackage)) + : of({ total: 0 }); return combineLatest([ attachmentsCollection, - fileLinksCollection, - ]).pipe(map(([a, f]) => a.length + f.length)); + totalFileLinks, + ]).pipe(map(([a, f]) => a.length + f.total)); +} + +function href(workPackage:WorkPackageResource):string { + if (!workPackage.$links.fileLinks) { + return ''; + } + + return `${workPackage.$links.fileLinks.href}?pageSize=0`; } diff --git a/frontend/src/app/features/work-packages/routing/split-view-routes.template.ts b/frontend/src/app/features/work-packages/routing/split-view-routes.template.ts index 83c9b26cb378..9b05b51e4761 100644 --- a/frontend/src/app/features/work-packages/routing/split-view-routes.template.ts +++ b/frontend/src/app/features/work-packages/routing/split-view-routes.template.ts @@ -117,7 +117,7 @@ export function makeSplitViewRoutes(baseRoute:string, // Remember the base route so we can route back to it anywhere baseRoute, parent: baseRoute, - mobileAlternative: showMobileAlternative ? 'work-packages.show' : undefined, + mobileAlternative: showMobileAlternative ? 'work-packages.new' : undefined, }, views: { // Retarget and by that override the grandparent views diff --git a/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.html b/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.html index 69fd0b2cb058..6c0a78b56768 100644 --- a/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.html +++ b/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.html @@ -134,6 +134,14 @@
+ + + + +
#{{item.id}} + >#{{ item.id }} + *ngSwitchCase="resource ==='subproject' || resource ==='version' || resource ==='status' || resource ==='default' || (!resource && !item.depth)"> {{ item.name }} @@ -220,6 +228,6 @@ × {{item.name}} + class="ng-value-label">{{ item.name }} diff --git a/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.ts b/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.ts index 202bbee25fd1..40fc8dad28fa 100644 --- a/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.ts +++ b/frontend/src/app/shared/components/autocompleter/op-autocompleter/op-autocompleter.component.ts @@ -24,7 +24,7 @@ import { } from '@angular/core'; import { DropdownPosition, NgSelectComponent } from '@ng-select/ng-select'; import { BehaviorSubject, merge, NEVER, Observable, of, Subject, timer } from 'rxjs'; -import { debounce, distinctUntilChanged, filter, switchMap, tap } from 'rxjs/operators'; +import { debounce, distinctUntilChanged, filter, switchMap, tap, map } from 'rxjs/operators'; import { AddTagFn, GroupValueFn } from '@ng-select/ng-select/lib/ng-select.component'; import { HalResource } from 'core-app/features/hal/resources/hal-resource'; @@ -49,6 +49,10 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ID } from '@datorama/akita'; import { HttpClient } from '@angular/common/http'; import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service'; +import { HalResourceService } from 'core-app/features/hal/services/hal-resource.service'; +import { CollectionResource } from 'core-app/features/hal/resources/collection-resource'; +import { ApiV3FilterBuilder } from 'core-app/shared/helpers/api-v3/api-v3-filter-builder'; +import { addFiltersToPath } from 'core-app/core/apiv3/helpers/add-filters-to-path'; export interface IAutocompleteItem { id:ID; @@ -222,6 +226,8 @@ export class OpAutocompleterComponent(); @Output() public close = new EventEmitter(); @@ -291,6 +297,7 @@ export class OpAutocompleterComponent !!(this.defaultData || this.getOptionsFn)), distinctUntilChanged(), tap(() => this.loading$.next(true)), - // tap(() => console.log('Debounce is ', this.getDebounceTimeout())), debounce(() => timer(this.getDebounceTimeout())), switchMap((queryString:string) => { + if (this.relations && this.url) { + return this.fetchFromUrl(queryString); + } + if (this.defaultData) { return this.opAutocompleterService.loadData(queryString, this.resource, this.filters, this.searchKey); } @@ -479,6 +489,39 @@ export class OpAutocompleterComponent { + // Exit early if the query string is empty as there is no typeahead + if (queryString === null || queryString.length === 0) { + return of([]); + } + + // Build filters if provided + const finalFilters = new ApiV3FilterBuilder(); + this.filters?.forEach((currentFilter) => { + // eslint-disable-next-line @typescript-eslint/no-unsafe-argument + finalFilters.add(currentFilter.name, currentFilter.operator, currentFilter.values); + }); + + const urlWithFilters = addFiltersToPath(this.url, finalFilters); + + // Add default sort parameters if resource is work packages + if (this.resource === 'work_packages') { + urlWithFilters.searchParams.set('sortBy', '[["updatedAt","desc"]]'); + } + + // Add query string to the url if provided + urlWithFilters.searchParams.set('query', queryString); + + const stringifiedBuiltOutUrl = urlWithFilters.toString(); + + return this + .halResourceService + .get(stringifiedBuiltOutUrl) + .pipe( + map((collection:CollectionResource) => collection.elements), + ); + } + private getDebounceTimeout():number { if (this.initialDebounce) { this.initialDebounce = false; diff --git a/frontend/src/app/shared/components/fields/display/field-types/text-display-field.module.ts b/frontend/src/app/shared/components/fields/display/field-types/text-display-field.module.ts index a6dfcda0f327..869580282245 100644 --- a/frontend/src/app/shared/components/fields/display/field-types/text-display-field.module.ts +++ b/frontend/src/app/shared/components/fields/display/field-types/text-display-field.module.ts @@ -27,6 +27,22 @@ //++ import { DisplayField } from 'core-app/shared/components/fields/display/display-field.module'; +import { HalResource } from 'core-app/features/hal/resources/hal-resource'; +import isArrayOf from 'core-app/core/state/is-array-of'; export class TextDisplayField extends DisplayField { + public get valueString():string { + // render a text representation for the assigned attribute, independent of the attribute being a resource, + // an array of resources or a single text value. + + if (this.value instanceof HalResource) { + return this.value.name; + } + + if (isArrayOf(this.value, HalResource)) { + return this.value.map((r) => r.name).join(', '); + } + + return this.value as string; + } } diff --git a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts index 2dfd8da37984..89a8259fc5f0 100644 --- a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts +++ b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts @@ -19,6 +19,7 @@ import { TimeEntryCreateService } from 'core-app/shared/components/time_entries/ import { WpDestroyModalComponent } from 'core-app/shared/components/modals/wp-destroy-modal/wp-destroy.modal'; import { WorkPackageAuthorization } from 'core-app/features/work-packages/services/work-package-authorization.service'; import * as moment from 'moment-timezone'; +import { TurboRequestsService } from 'core-app/core/turbo/turbo-requests.service'; @Directive({ selector: '[wpSingleContextMenu]', @@ -34,6 +35,7 @@ export class WorkPackageSingleContextMenuDirective extends OpContextMenuTrigger readonly PathHelper:PathHelperService, readonly elementRef:ElementRef, readonly opModalService:OpModalService, + readonly turboRequests:TurboRequestsService, readonly opContextMenuService:OPContextMenuService, readonly authorisationService:AuthorisationService, protected copyToClipboardService:CopyToClipboardService, @@ -74,6 +76,9 @@ export class WorkPackageSingleContextMenuDirective extends OpContextMenuTrigger // do nothing, the user closed without changes }); break; + case 'generate_pdf': + void this.turboRequests.requestStream(link as string); + break; case 'copy_link_to_clipboard': { const url = new URL(String(link), window.location.origin); this.copyToClipboardService.copy(url.toString()); diff --git a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions.ts b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions.ts index cd1ae3a3eed3..4a2e0d82f146 100644 --- a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions.ts +++ b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions.ts @@ -35,6 +35,11 @@ export const PERMITTED_CONTEXT_MENU_ACTIONS:WorkPackageAction[] = [ key: 'export-pdf', link: 'pdf', }, + { + key: 'generate_pdf', + link: 'generate_pdf', + icon: 'icon-export-pdf-with-descriptions', + }, { key: 'export-atom', link: 'atom', diff --git a/frontend/src/app/shared/components/storages/storage/storage.component.ts b/frontend/src/app/shared/components/storages/storage/storage.component.ts index dd967426192e..9877227ab475 100644 --- a/frontend/src/app/shared/components/storages/storage/storage.component.ts +++ b/frontend/src/app/shared/components/storages/storage/storage.component.ts @@ -84,6 +84,7 @@ import { IUploadLink } from 'core-app/core/state/storage-files/upload-link.model import { IStorageFile } from 'core-app/core/state/storage-files/storage-file.model'; import { TimezoneService } from 'core-app/core/datetime/timezone.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; +import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource'; import { UploadConflictModalComponent, } from 'core-app/shared/components/storages/upload-conflict-modal/upload-conflict-modal.component'; @@ -546,8 +547,8 @@ export class StorageComponent extends UntilDestroyedMixin implements OnInit, OnD } private fileLinkSelfLink(storage:IStorage):string { - const fileLinks = this.resource.fileLinks as { href:string }; - return `${fileLinks.href}?filters=[{"storage":{"operator":"=","values":["${storage.id}"]}}]`; + const fileLinks = (this.resource as WorkPackageResource).$links.fileLinks; + return `${fileLinks?.href}?pageSize=-1&filters=[{"storage":{"operator":"=","values":["${storage.id}"]}}]`; } public onDropFiles(event:DragEvent):void { diff --git a/frontend/src/assets/images/15_0_features.svg b/frontend/src/assets/images/15_1_features.svg similarity index 100% rename from frontend/src/assets/images/15_0_features.svg rename to frontend/src/assets/images/15_1_features.svg diff --git a/frontend/src/global_styles/content/work_packages/single_view/_single_view.sass b/frontend/src/global_styles/content/work_packages/single_view/_single_view.sass index d5d98b2d7745..34b80a3a9eac 100644 --- a/frontend/src/global_styles/content/work_packages/single_view/_single_view.sass +++ b/frontend/src/global_styles/content/work_packages/single_view/_single_view.sass @@ -94,10 +94,6 @@ textarea resize: vertical -.detail-panel-description - margin: 0 - line-height: 18px - // Let the absolute autocomplete modify the height // of the relation tab so we can scroll to the results .detail-panel--autocomplete-target diff --git a/frontend/src/global_styles/layout/_colors.sass b/frontend/src/global_styles/layout/_colors.sass index 915cc7fbdb39..83b3f1db6698 100644 --- a/frontend/src/global_styles/layout/_colors.sass +++ b/frontend/src/global_styles/layout/_colors.sass @@ -95,8 +95,8 @@ font-weight: var(--base-text-weight-bold) // Inline: all except type -[class^='__hl_inline_']:not([class^='__hl_inline_type']), -[class*=' __hl_inline_']:not([class*='__hl_inline_type']) +[class^='__hl_inline_']:not([class^='__hl_inline_type'], [class^='__hl_inline_life_cycle_step_definition']), +[class*=' __hl_inline_']:not([class*='__hl_inline_type'], [class*='__hl_inline_life_cycle_step_definition']) &::before content: '' display: inline-block diff --git a/frontend/src/global_styles/primer/_overrides.sass b/frontend/src/global_styles/primer/_overrides.sass index 052c77f3b657..2ef53fc4dd50 100644 --- a/frontend/src/global_styles/primer/_overrides.sass +++ b/frontend/src/global_styles/primer/_overrides.sass @@ -28,23 +28,10 @@ // Re-apply the primer styles with higher specificity // as the OpenProject form styles override them. - -.Box - > ul:not(.op-uc-list) - margin-left: 0 - - .FormControl - label - margin-bottom: 0 input border-radius: var(--borderRadius-medium) -action-menu - anchored-position - ul - margin-left: 0 - .UnderlineNav @include no-visible-scroll-bar margin-bottom: 12px @@ -52,19 +39,21 @@ action-menu @media screen and (min-width: $breakpoint-sm) scroll-behavior: smooth -ul.SegmentedControl - margin-left: 0 - /* Remove margin-left: 2rem from Breadcrumbs */ #breadcrumb, page-header, sub-header, .op-work-package-details-tab-component, .tabnav, -.Box-header +.Box-header, +action-menu anchored-position ol, ul margin-left: 0 +ul.SegmentedControl, +.Box > ul:not(.op-uc-list) + margin-left: 0 + #breadcrumb .breadcrumb-item.breadcrumb-item-selected a @@ -114,10 +103,6 @@ sub-header, border-radius: 0px 0px var(--borderRadius-medium) var(--borderRadius-medium) .op-ckeditor--wrapper margin-bottom: 0px - -// Todo: Remove once https://github.com/primer/view_components/pull/3087 is merged -.FormControl-spacingWrapper - row-gap: var(--stack-gap-normal) // When our generic table uses the quick action menu, column headers are cut off and no longer fully readable. // This fix ensures that column headers are always displayed. An example for such a table is the project list. diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 51373fe7ccad..82f7151eae7f 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -44,10 +44,6 @@ void initializeLocale() initializeGlobalListeners(); // Due to the behaviour of the Edge browser we need to wait for 'DOM ready' - void platformBrowserDynamic() - .bootstrapModule(OpenProjectModule) - .then(() => { - jQuery('body').addClass('__ng2-bootstrap-has-run'); - }); + void platformBrowserDynamic().bootstrapModule(OpenProjectModule); }); }); diff --git a/frontend/src/stimulus/controllers/dynamic/admin/custom-fields.controller.ts b/frontend/src/stimulus/controllers/dynamic/admin/custom-fields.controller.ts index 887fe5cece9e..d0d721000777 100644 --- a/frontend/src/stimulus/controllers/dynamic/admin/custom-fields.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/admin/custom-fields.controller.ts @@ -34,6 +34,7 @@ export default class CustomFieldsController extends Controller { static targets = [ 'format', 'dragContainer', + 'submitButton', 'customOptionDefaults', 'customOptionRow', @@ -48,17 +49,23 @@ export default class CustomFieldsController extends Controller { 'regexp', 'searchable', 'textOrientation', + + 'enterpriseBanner', ]; static values = { formatConfig: Array, + enterpriseEdition: Boolean, }; declare readonly formatConfigValue:[string, string, string[]][]; + declare readonly enterpriseEditionValue:boolean; declare readonly formatTarget:HTMLInputElement; declare readonly dragContainerTarget:HTMLElement; declare readonly hasDragContainerTarget:boolean; + declare readonly submitButtonTarget:HTMLButtonElement; + declare readonly hasSubmitButtonTarget:boolean; declare readonly customOptionDefaultsTargets:HTMLInputElement[]; declare readonly customOptionRowTargets:HTMLTableRowElement[]; @@ -74,6 +81,8 @@ export default class CustomFieldsController extends Controller { declare readonly searchableTargets:HTMLInputElement[]; declare readonly textOrientationTargets:HTMLElement[]; + declare readonly enterpriseBannerTarget:HTMLElement; + connect() { if (this.hasDragContainerTarget) { this.setupDragAndDrop(); @@ -242,8 +251,16 @@ export default class CustomFieldsController extends Controller { } private toggleFormat(format:string) { + if (this.hasSubmitButtonTarget) { + this.submitButtonTarget.disabled = format === 'hierarchy' && !this.enterpriseEditionValue; + } + this.formatConfigValue.forEach(([targetsName, operator, formats]) => { - const active = operator === 'only' ? formats.includes(format) : !formats.includes(format); + let active = operator === 'only' ? formats.includes(format) : !formats.includes(format); + if (targetsName === 'enterpriseBanner' && this.enterpriseEditionValue) { + active = false; + } + const targets = this[`${targetsName}Targets` as keyof typeof this] as HTMLElement[]; if (targets) { this.setActive(targets, active); diff --git a/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/index.controller.ts b/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/index.controller.ts index cf2cc74fa9b4..9df5c036f223 100644 --- a/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/index.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/index.controller.ts @@ -355,15 +355,22 @@ export default class IndexController extends Controller { } } - private scrollToActivity(activityId:string) { + private tryScroll(activityId:string, attempts:number, maxAttempts:number) { const scrollableContainer = this.getScrollableContainer(); const activityElement = document.getElementById(`activity-anchor-${activityId}`); if (activityElement && scrollableContainer) { - scrollableContainer.scrollTop = activityElement.offsetTop-70; + scrollableContainer.scrollTop = activityElement.offsetTop - 70; + } else if (attempts < maxAttempts) { + setTimeout(() => this.tryScroll(activityId, attempts + 1, maxAttempts), 1000); } } + private scrollToActivity(activityId:string) { + const maxAttempts = 20; // wait max 20 seconds for the activity to be rendered + this.tryScroll(activityId, 0, maxAttempts); + } + private scrollToBottom() { const scrollableContainer = this.getScrollableContainer(); if (scrollableContainer) { @@ -398,7 +405,7 @@ export default class IndexController extends Controller { } private getScrollableContainer():HTMLElement | null { - if (this.isWithinNotificationCenter()) { + if (this.isWithinNotificationCenter() || this.isWithinSplitScreen()) { // valid for both mobile and desktop return document.querySelector('.work-package-details-tab') as HTMLElement; } @@ -419,6 +426,10 @@ export default class IndexController extends Controller { return window.location.pathname.includes(this.notificationCenterPathNameValue); } + private isWithinSplitScreen():boolean { + return window.location.pathname.includes('work_packages/details'); + } + private addEventListenersToCkEditorInstance() { this.onSubmitBound = () => { void this.onSubmit(); }; this.adjustMarginBound = () => { void this.adjustJournalContainerMargin(); }; @@ -633,7 +644,7 @@ export default class IndexController extends Controller { headers: { 'X-CSRF-Token': (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement).content, }, - }); + }, true); } private handleSuccessfulSubmission(html:string, headers:Headers) { @@ -643,8 +654,8 @@ export default class IndexController extends Controller { if (!this.journalsContainerTarget) return; this.clearEditor(); - this.handleEditorVisibility(); - this.adjustJournalsContainer(); + this.hideEditor(); + this.resetJournalsContainerMargins(); setTimeout(() => { if (this.isMobile() && !this.isWithinNotificationCenter()) { @@ -663,19 +674,11 @@ export default class IndexController extends Controller { this.saveInProgress = false; } - private handleEditorVisibility():void { - if (this.isMobile()) { - this.hideEditorIfEmpty(); - } else { - this.focusEditor(); - } - } - - private adjustJournalsContainer():void { + private resetJournalsContainerMargins():void { if (!this.journalsContainerTarget) return; this.journalsContainerTarget.style.marginBottom = ''; - this.journalsContainerTarget.classList.add('work-packages-activities-tab-index-component--journals-container_with-input-compensation'); + this.journalsContainerTarget.classList.add('work-packages-activities-tab-index-component--journals-container_with-initial-input-compensation'); } private setLastServerTimestampViaHeaders(headers:Headers) { diff --git a/lib/api/v3/activities/activity_eager_loading_wrapper.rb b/lib/api/v3/activities/activity_eager_loading_wrapper.rb index b21a7abc355a..8b7f20a61238 100644 --- a/lib/api/v3/activities/activity_eager_loading_wrapper.rb +++ b/lib/api/v3/activities/activity_eager_loading_wrapper.rb @@ -36,6 +36,7 @@ def wrap(journals) set_journable(journals) set_predecessor(journals) set_data(journals) + set_notifications(journals) end super @@ -72,6 +73,20 @@ def set_data(journals) end end + def set_notifications(journals) + notifications = Notification + .where(journal_id: journals.map(&:id)) + .where(read_ian: false) + .group_by(&:journal_id) + + journals.each do |journal| + journal.instance_variable_set( + :@unread_notifications, + notifications[journal.id] + ) + end + end + def journable_by_type_and_id(journals) journals .group_by(&:journable_type) diff --git a/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer.rb b/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer.rb index c978dd7993c4..fc527c011e99 100644 --- a/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer.rb +++ b/lib/api/v3/custom_fields/hierarchy/hierarchy_item_representer.rb @@ -36,7 +36,13 @@ def _type end self_link path: :custom_field_item, - title_getter: ->(*) { represented.label } + title_getter: ->(*) do + if represented.short.nil? + represented.label + else + "#{represented.label} (#{represented.short})" + end + end property :id diff --git a/lib/api/v3/queries/query_representer.rb b/lib/api/v3/queries/query_representer.rb index 87a70888bf7d..6eeca1ae994e 100644 --- a/lib/api/v3/queries/query_representer.rb +++ b/lib/api/v3/queries/query_representer.rb @@ -344,8 +344,7 @@ def _type def filters represented.filters.map do |filter| - ::API::V3::Queries::Filters::QueryFilterInstanceRepresenter - .new(filter) + ::API::V3::Queries::Filters::QueryFilterInstanceRepresenter.new(filter) end end diff --git a/lib/api/v3/queries/schemas/custom_option_filter_dependency_representer.rb b/lib/api/v3/queries/schemas/custom_option_filter_dependency_representer.rb index b840bcd15e0e..b733effa24f1 100644 --- a/lib/api/v3/queries/schemas/custom_option_filter_dependency_representer.rb +++ b/lib/api/v3/queries/schemas/custom_option_filter_dependency_representer.rb @@ -30,8 +30,7 @@ module API module V3 module Queries module Schemas - class CustomOptionFilterDependencyRepresenter < - FilterDependencyRepresenter + class CustomOptionFilterDependencyRepresenter < FilterDependencyRepresenter schema_with_allowed_collection :values, type: ->(*) { type }, writable: true, diff --git a/lib/api/v3/queries/schemas/filter_dependency_representer_factory.rb b/lib/api/v3/queries/schemas/filter_dependency_representer_factory.rb index 1b90fccb3944..0d4651f2c484 100644 --- a/lib/api/v3/queries/schemas/filter_dependency_representer_factory.rb +++ b/lib/api/v3/queries/schemas/filter_dependency_representer_factory.rb @@ -96,7 +96,7 @@ def cf_representer_class(filter) "API::V3::Queries::Schemas::CustomOptionFilterDependencyRepresenter" when "bool" "API::V3::Queries::Schemas::BooleanFilterDependencyRepresenter" - when "user", "version", "float" + when "user", "version", "float", "hierarchy" "API::V3::Queries::Schemas::#{format.camelize}FilterDependencyRepresenter" when "string", "link" "API::V3::Queries::Schemas::TextFilterDependencyRepresenter" diff --git a/lib/api/v3/queries/schemas/hierarchy_filter_dependency_representer.rb b/lib/api/v3/queries/schemas/hierarchy_filter_dependency_representer.rb new file mode 100644 index 000000000000..e8187e0cb6b2 --- /dev/null +++ b/lib/api/v3/queries/schemas/hierarchy_filter_dependency_representer.rb @@ -0,0 +1,40 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +module API + module V3 + module Queries + module Schemas + class HierarchyFilterDependencyRepresenter < FilterDependencyRepresenter + def type = "[]CustomField::Hierarchy::Item" + def href_callback = api_v3_paths.custom_field_items(filter.custom_field.id) + end + end + end + end +end diff --git a/lib/api/v3/utilities/path_helper.rb b/lib/api/v3/utilities/path_helper.rb index 3a862ac231c5..6f46cffc495a 100644 --- a/lib/api/v3/utilities/path_helper.rb +++ b/lib/api/v3/utilities/path_helper.rb @@ -215,6 +215,11 @@ def self.custom_field_item(id) "#{root}/custom_field_items/#{id}" end + # API::V3::Queries::Filters::QueryFilterInstanceRepresenter need a path derived from a class name. + def self.hierarchy_item_filter_adapter(id) + custom_field_item(id) + end + def self.custom_field_item_branch(id) "#{custom_field_item(id)}/branch" end diff --git a/lib/api/v3/work_packages/work_package_representer.rb b/lib/api/v3/work_packages/work_package_representer.rb index 46c02c3deb4c..20ea4a61abe7 100644 --- a/lib/api/v3/work_packages/work_package_representer.rb +++ b/lib/api/v3/work_packages/work_package_representer.rb @@ -133,6 +133,19 @@ def self_v3_path(*) } end + link :generate_pdf, + cache_if: -> { export_work_packages_allowed? } do + next if represented.new_record? + + next unless OpenProject::FeatureDecisions.generate_pdf_from_work_package_active? + + { + href: generate_pdf_dialog_work_package_path(id: represented.id), + type: "application/pdf", + title: "Generate PDF" + } + end + link :atom, cache_if: -> { export_work_packages_allowed? } do next if represented.new_record? || !Setting.feeds_enabled? diff --git a/lib/custom_field_form_builder.rb b/lib/custom_field_form_builder.rb index ff6181434011..22a7b9b65f92 100644 --- a/lib/custom_field_form_builder.rb +++ b/lib/custom_field_form_builder.rb @@ -57,6 +57,7 @@ def cf_form_field(options = {}) private + # rubocop:disable Metrics/AbcSize def custom_field_input(options = {}) field = custom_field.attribute_name @@ -64,7 +65,7 @@ def custom_field_input(options = {}) name: custom_field_field_name, id: custom_field_field_id) - field_format = OpenProject::CustomFieldFormat.find_by_name(custom_field.field_format) + field_format = OpenProject::CustomFieldFormat.find_by(name: custom_field.field_format) case field_format.try(:edit_as) when "date" @@ -80,6 +81,8 @@ def custom_field_input(options = {}) end end + # rubocop:enable Metrics/AbcSize + def custom_field_input_list(field, input_options) customized = Array(custom_value).first&.customized possible_options = custom_field.possible_values_options(customized) diff --git a/lib/open_project/custom_field_format.rb b/lib/open_project/custom_field_format.rb index 6fd26a94d430..eb76c0496096 100644 --- a/lib/open_project/custom_field_format.rb +++ b/lib/open_project/custom_field_format.rb @@ -63,7 +63,7 @@ def available_formats @@available.keys end - def find_by_name(name) + def find_by(name:) @@available[name.to_s] end diff --git a/lib/open_project/custom_field_format_dependent.rb b/lib/open_project/custom_field_format_dependent.rb index 937920c66063..0843c97f3f52 100644 --- a/lib/open_project/custom_field_format_dependent.rb +++ b/lib/open_project/custom_field_format_dependent.rb @@ -37,8 +37,9 @@ class CustomFieldFormatDependent multiSelect: [:only, %w[list user version hierarchy]], possibleValues: [:only, %w[list]], regexp: [:except, %w[list bool date user version hierarchy]], - searchable: [:except, %w[bool date float int user version]], - textOrientation: [:only, %w[text]] + searchable: [:except, %w[bool date float int user version hierarchy]], + textOrientation: [:only, %w[text]], + enterpriseBanner: [:only, %w[hierarchy]] }.freeze def self.stimulus_config diff --git a/lib/open_project/patches/mailer_controller_preview.rb b/lib/open_project/patches/mailer_controller_preview.rb index 8f516840e246..04090d2d853f 100644 --- a/lib/open_project/patches/mailer_controller_preview.rb +++ b/lib/open_project/patches/mailer_controller_preview.rb @@ -41,6 +41,6 @@ def extend_content_security_policy end end -OpenProject::Patches.patch_gem_version "rails", "7.1.4.1" do +OpenProject::Patches.patch_gem_version "rails", "7.1.5" do Rails::MailersController.include OpenProject::Patches::MailerControllerCsp end diff --git a/lib/open_project/version.rb b/lib/open_project/version.rb index 685b7d7d5ee2..0cc92323beb0 100644 --- a/lib/open_project/version.rb +++ b/lib/open_project/version.rb @@ -32,7 +32,7 @@ module OpenProject module VERSION # :nodoc: MAJOR = 15 - MINOR = 1 + MINOR = 2 PATCH = 0 class << self diff --git a/lookbook/docs/patterns/12-tables.md.erb b/lookbook/docs/patterns/12-tables.md.erb index fd1a2443aa67..cb841e6bf0cf 100644 --- a/lookbook/docs/patterns/12-tables.md.erb +++ b/lookbook/docs/patterns/12-tables.md.erb @@ -33,6 +33,53 @@ end <%= embed OpPrimer::BorderBoxTableComponentPreview, :default, panels: %i[source] %> + + +### Border Box Table specifics + +#### Mobile behavior + +On mobile, the BorderBoxTable does not scroll, but collapse into two columns (content columns and actions). You can control which columns are shown using the `mobile_columns` method. + +As the columns are collapsed, some information might need an additional label, which you can prepend with `mobile_labels`. + +```ruby +# On desktop, show these columns +columns :title, :users, :created_at + +# On mobile, only two columns are visible +mobile_columns :title, :users + +# For users, show the label using the header caption +mobile_labels :users +``` + + + +#### Mobile headers + +On mobile, the usual table headers are replaced with a single `mobile_title` property that you have to set on the table. + +#### Text wrapping behaviour + +By default, text longer than the column width will truncate with ellipsis. Only the main column has text that wraps around to display the full string. + +#### Main column + +Use the `main_column` helper to make a column 2 times as wide as the others and also display the full text: + +```ruby +# On desktop, show these columns +columns :title, :users, :created_at + +# Make title column wider than the others (factor 2 using grid span) +main_column :title +``` +Note: Ideally, one one main column will be present for each table. + + + + ## Best practices **Do** diff --git a/lookbook/docs/patterns/26-work-package-info-line.md.erb b/lookbook/docs/patterns/26-work-package-info-line.md.erb new file mode 100644 index 000000000000..b7045ef53063 --- /dev/null +++ b/lookbook/docs/patterns/26-work-package-info-line.md.erb @@ -0,0 +1,34 @@ +The work package info line is a consistent way to display the most commonly-used set of basic work package attributes. + +## Overview + +<%= embed OpenProject::WorkPackages::InfoLineComponentPreview, :playground %> + +## Anatomy + +The info line consists of three attributes that are displayed together: + +- Type +- ID +- Status + +Only the ID the only interactive element; it is clickable and points the work package. All other interaction has to come from the element using this work component. + +## Best practices + +It's best to not separate these three elements in different lines. The element can, however, be wrapped in multi-line if needed. + +## Used in + +- Hovercard +- Work package relations tab +- Work package header +- ... + +### Code structure + +You can typically call the InfoLineComponent in views where work package details (Type, ID, and Status) need to be displayed in one line. You must pass a work package object containing valid data to it. + +```html + render(WorkPackages::InfoLineComponent.new(work_package: @work_package)) +``` diff --git a/lookbook/previews/op_primer/border_box_table_component_preview/custom_column_widths.html.erb b/lookbook/previews/op_primer/border_box_table_component_preview/custom_column_widths.html.erb index b4b732c3cac7..9066de13c704 100644 --- a/lookbook/previews/op_primer/border_box_table_component_preview/custom_column_widths.html.erb +++ b/lookbook/previews/op_primer/border_box_table_component_preview/custom_column_widths.html.erb @@ -1,16 +1,15 @@ <%= table = Class.new(OpPrimer::BorderBoxTableComponent) do columns :foo, :bar + + main_column :foo + def self.name "MyTable" end - def header_args(column) - if column == :foo - { style: "grid-column: span 3" } - else - super - end + def mobile_title + "Mobile foo" end def row_class @@ -19,14 +18,6 @@ "MyRow" end - def column_args(column) - if column == :foo - { style: "grid-column: span 3" } - else - super - end - end - def foo "foo" end diff --git a/lookbook/previews/op_primer/border_box_table_component_preview/default.html.erb b/lookbook/previews/op_primer/border_box_table_component_preview/default.html.erb index 79a4d5a8d378..9d31891f044b 100644 --- a/lookbook/previews/op_primer/border_box_table_component_preview/default.html.erb +++ b/lookbook/previews/op_primer/border_box_table_component_preview/default.html.erb @@ -1,10 +1,17 @@ <%= table = Class.new(OpPrimer::BorderBoxTableComponent) do columns :foo, :bar + + mobile_labels :bar + def self.name "MyTable" end + def mobile_title + "Mobile foo" + end + ## This method is just a hack used for the preview ## Create your components under your namespace like so instead ## MyNamespace::TableComponent @@ -33,7 +40,7 @@ def foo concat render(Primer::Beta::Link.new(scheme: :primary, href: "#")) { "Some link" } - concat render(Primer::Beta::Text.new(tag: :p, font_size: :small, color: :subtle)) { "Hello there" } + render(Primer::Beta::Text.new(tag: :p, font_size: :small, color: :subtle)) { "Hello there" } end def bar diff --git a/lookbook/previews/op_primer/border_box_table_component_preview/with_action_menu.html.erb b/lookbook/previews/op_primer/border_box_table_component_preview/with_action_menu.html.erb index 68c0415a5c04..0190be02dca5 100644 --- a/lookbook/previews/op_primer/border_box_table_component_preview/with_action_menu.html.erb +++ b/lookbook/previews/op_primer/border_box_table_component_preview/with_action_menu.html.erb @@ -1,10 +1,15 @@ <%= table = Class.new(OpPrimer::BorderBoxTableComponent) do columns :foo, :bar + def self.name "MyTable" end + def mobile_title + "Mobile foo" + end + def row_class @clazz ||= Class.new(OpPrimer::BorderBoxRowComponent) do def self.name @@ -33,7 +38,8 @@ def foo concat render(Primer::Beta::Link.new(scheme: :primary, href: "#")) { "Some link" } - concat render(Primer::Beta::Text.new(tag: :p, font_size: :small, color: :subtle)) { "Hello there" } + + render(Primer::Beta::Text.new(tag: :p, font_size: :small, color: :subtle)) { "Hello there" } end def bar diff --git a/lookbook/previews/open_project/work_packages/info_line_component_preview.rb b/lookbook/previews/open_project/work_packages/info_line_component_preview.rb new file mode 100644 index 000000000000..01219bbb49f1 --- /dev/null +++ b/lookbook/previews/open_project/work_packages/info_line_component_preview.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module OpenProject::WorkPackages + # @logical_path OpenProject/WorkPackages + class InfoLineComponentPreview < ViewComponent::Preview + def playground + render(WorkPackages::InfoLineComponent.new(work_package: WorkPackage.visible.first)) + end + end +end diff --git a/modules/auth_saml/app/components/saml/providers/row_component.rb b/modules/auth_saml/app/components/saml/providers/row_component.rb index 96c140e7d581..b198e02fd6c6 100644 --- a/modules/auth_saml/app/components/saml/providers/row_component.rb +++ b/modules/auth_saml/app/components/saml/providers/row_component.rb @@ -5,14 +5,6 @@ def provider model end - def column_args(column) - if column == :name - { style: "grid-column: span 3" } - else - super - end - end - def name concat render(Primer::Beta::Link.new( font_weight: :bold, @@ -20,23 +12,11 @@ def name )) { provider.display_name || provider.name } render_availability_label - render_idp_sso_service_url end def render_availability_label unless provider.available? - concat render(Primer::Beta::Label.new(ml: 2, scheme: :attention, size: :medium)) { t(:label_incomplete) } - end - end - - def render_idp_sso_service_url - if provider.idp_sso_service_url - concat render(Primer::Beta::Text.new( - tag: :p, - classes: "-break-word", - font_size: :small, - color: :subtle - )) { provider.idp_sso_service_url } + render(Primer::Beta::Label.new(ml: 2, scheme: :attention, size: :medium)) { t(:label_incomplete) } end end diff --git a/modules/auth_saml/app/components/saml/providers/sections/show_component.html.erb b/modules/auth_saml/app/components/saml/providers/sections/show_component.html.erb index f2777b1de598..a747fa58d42f 100644 --- a/modules/auth_saml/app/components/saml/providers/sections/show_component.html.erb +++ b/modules/auth_saml/app/components/saml/providers/sections/show_component.html.erb @@ -33,6 +33,7 @@ tag: :a, scheme: :invisible, href: edit_saml_provider_path(provider, edit_state: @target_state), + test_selector: "saml_provider_#{@target_state}_edit", data: { turbo: true, turbo_stream: true }, aria: { label: I18n.t(disabled ? :label_show : :label_edit) } ) diff --git a/modules/auth_saml/app/components/saml/providers/table_component.rb b/modules/auth_saml/app/components/saml/providers/table_component.rb index fd9d403a57ea..3093d260275e 100644 --- a/modules/auth_saml/app/components/saml/providers/table_component.rb +++ b/modules/auth_saml/app/components/saml/providers/table_component.rb @@ -3,18 +3,16 @@ module Providers class TableComponent < ::OpPrimer::BorderBoxTableComponent columns :name, :users, :creator, :created_at + mobile_columns :name, :users + + mobile_labels :users + + main_column :name + def initial_sort %i[id asc] end - def header_args(column) - if column == :name - { style: "grid-column: span 3" } - else - super - end - end - def sortable? false end @@ -23,6 +21,10 @@ def empty_row_message I18n.t "saml.providers.no_results_table" end + def mobile_title + I18n.t("saml.providers.plural") + end + def headers [ [:name, { caption: I18n.t("attributes.name") }], diff --git a/modules/auth_saml/app/contracts/saml/providers/base_contract.rb b/modules/auth_saml/app/contracts/saml/providers/base_contract.rb index 3e2a24ac82fe..2375f66cfb1c 100644 --- a/modules/auth_saml/app/contracts/saml/providers/base_contract.rb +++ b/modules/auth_saml/app/contracts/saml/providers/base_contract.rb @@ -64,6 +64,8 @@ def self.model attribute :authn_requests_signed validate :valid_certificate_key_pair + attribute :limit_self_registration + %i[mapping_mail mapping_login mapping_firstname mapping_lastname].each do |attr| attribute attr validates_presence_of attr, if: -> { model.public_send(:"#{attr}_changed?") } diff --git a/modules/auth_saml/app/controllers/saml/providers_controller.rb b/modules/auth_saml/app/controllers/saml/providers_controller.rb index fe390734b6ec..f9f51af7d146 100644 --- a/modules/auth_saml/app/controllers/saml/providers_controller.rb +++ b/modules/auth_saml/app/controllers/saml/providers_controller.rb @@ -92,7 +92,7 @@ def update successful_save_response else @provider = call.result - render action: :edit + render action: :edit, status: :unprocessable_entity end end @@ -178,7 +178,7 @@ def create_params def update_params params .require(:saml_provider) - .permit(:display_name, *Saml::Provider.stored_attributes[:options]) + .permit(:display_name, :limit_self_registration, *Saml::Provider.stored_attributes[:options]) end def find_provider diff --git a/modules/auth_saml/app/models/saml/provider.rb b/modules/auth_saml/app/models/saml/provider.rb index 515c3a42d67c..341bc594342c 100644 --- a/modules/auth_saml/app/models/saml/provider.rb +++ b/modules/auth_saml/app/models/saml/provider.rb @@ -97,7 +97,7 @@ def loaded_idp_certificates end def idp_certificate_configured? - idp_cert.present? + idp_cert.present? || idp_cert_fingerprint.present? end def idp_certificate_valid? diff --git a/modules/auth_saml/app/models/saml/provider/hash_builder.rb b/modules/auth_saml/app/models/saml/provider/hash_builder.rb index d6bfc89f6b5c..5cbf13df8d5a 100644 --- a/modules/auth_saml/app/models/saml/provider/hash_builder.rb +++ b/modules/auth_saml/app/models/saml/provider/hash_builder.rb @@ -72,6 +72,7 @@ def to_h # rubocop:disable Metrics/AbcSize name_identifier_format:, certificate:, private_key:, + limit_self_registration:, attribute_statements: formatted_attribute_statements, request_attributes: formatted_request_attributes, uid_attribute: mapping_uid.presence diff --git a/modules/auth_saml/app/services/saml/configuration_mapper.rb b/modules/auth_saml/app/services/saml/configuration_mapper.rb index 748745546989..79edb7ce8a0b 100644 --- a/modules/auth_saml/app/services/saml/configuration_mapper.rb +++ b/modules/auth_saml/app/services/saml/configuration_mapper.rb @@ -39,8 +39,9 @@ def call! { "options" => options, "slug" => options.delete("name"), + "limit_self_registration" => ActiveModel::Type::Boolean.new.cast(options.delete("limit_self_registration")), "display_name" => options.delete("display_name") || "SAML" - } + }.compact end private diff --git a/modules/auth_saml/config/locales/crowdin/hu.yml b/modules/auth_saml/config/locales/crowdin/hu.yml index ca4ee049dda6..01f6d3810abb 100644 --- a/modules/auth_saml/config/locales/crowdin/hu.yml +++ b/modules/auth_saml/config/locales/crowdin/hu.yml @@ -2,15 +2,15 @@ hu: activemodel: attributes: saml/provider: - display_name: Name - identifier: Identifier - secret: Secret - scope: Scope + display_name: Név + identifier: Azonosító + secret: Titkos + scope: Terjedelem assertion_consumer_service_url: ACS (Assertion consumer service) URL limit_self_registration: Limit self registration sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL - name_identifier_format: Name identifier format + name_identifier_format: Névazonosító formátum idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider diff --git a/modules/auth_saml/spec/factories/saml_provider_factory.rb b/modules/auth_saml/spec/factories/saml_provider_factory.rb index a53c2c6857c6..1862fd4adca5 100644 --- a/modules/auth_saml/spec/factories/saml_provider_factory.rb +++ b/modules/auth_saml/spec/factories/saml_provider_factory.rb @@ -43,6 +43,8 @@ idp_sso_service_url { "https://example.com/sso" } idp_slo_service_url { "https://example.com/slo" } + limit_self_registration { true } + mapping_login { Saml::Defaults::MAIL_MAPPING } mapping_mail { Saml::Defaults::MAIL_MAPPING } mapping_firstname { Saml::Defaults::FIRSTNAME_MAPPING } diff --git a/modules/auth_saml/spec/features/administration/saml_crud_spec.rb b/modules/auth_saml/spec/features/administration/saml_crud_spec.rb index d1e62e0468d3..476fdff97f0f 100644 --- a/modules/auth_saml/spec/features/administration/saml_crud_spec.rb +++ b/modules/auth_saml/spec/features/administration/saml_crud_spec.rb @@ -57,6 +57,7 @@ fill_in "Identity provider login endpoint", with: "https://example.com/sso" fill_in "Identity provider logout endpoint", with: "https://example.com/slo" fill_in "Public certificate of identity provider", with: CertificateHelper.valid_certificate.to_pem + check "Limit self registration" click_link_or_button "Continue" @@ -68,11 +69,11 @@ click_link_or_button "Continue" # Mapping form - fill_in "Mapping for: Username", with: "login\nmail", fill_options: { clear: :backspace } - fill_in "Mapping for: Email", with: "mail", fill_options: { clear: :backspace } - fill_in "Mapping for: First name", with: "myName", fill_options: { clear: :backspace } - fill_in "Mapping for: Last name", with: "myLastName", fill_options: { clear: :backspace } - fill_in "Mapping for: Internal user id", with: "uid", fill_options: { clear: :backspace } + fill_in "Mapping for: Username", with: "login\nmail" + fill_in "Mapping for: Email", with: "mail" + fill_in "Mapping for: First name", with: "myName" + fill_in "Mapping for: Last name", with: "myLastName" + fill_in "Mapping for: Internal user id", with: "uid" click_link_or_button "Continue" @@ -105,6 +106,7 @@ expect(provider.mapping_lastname).to eq "myLastName" expect(provider.mapping_uid).to eq "uid" expect(provider.authn_requests_signed).to be true + expect(provider.limit_self_registration).to be true click_link_or_button "Delete" # Confirm the deletion @@ -175,6 +177,19 @@ expect(page).to have_text "Display name has already been taken." end + + it "can toggle limit_self_registration (Regression #59370)" do + visit "/admin/saml/providers" + click_link_or_button "My provider" + + page.find_test_selector("saml_provider_configuration_edit").click + check "Limit self registration" + click_link_or_button "Update" + wait_for_network_idle + + provider.reload + expect(provider.limit_self_registration).to be true + end end end diff --git a/modules/auth_saml/spec/lib/open_project/auth_saml_spec.rb b/modules/auth_saml/spec/lib/open_project/auth_saml_spec.rb index 263cd698e03d..89b3bdaa3bcd 100644 --- a/modules/auth_saml/spec/lib/open_project/auth_saml_spec.rb +++ b/modules/auth_saml/spec/lib/open_project/auth_saml_spec.rb @@ -15,6 +15,7 @@ expect(subject[:assertion_consumer_service_url]).to eq "http://#{Setting.host_name}/auth/my-saml/callback" expect(subject[:idp_sso_service_url]).to eq "https://example.com/sso" expect(subject[:idp_slo_service_url]).to eq "https://example.com/slo" + expect(subject[:limit_self_registration]).to be true attributes = subject[:attribute_statements] expect(attributes[:email]).to eq Saml::Defaults::MAIL_MAPPING.split("\n") @@ -30,5 +31,15 @@ expect(security[:want_assertions_signed]).to be false expect(security[:want_assertions_encrypted]).to be false end + + context "with limit_self_registration: false" do + let!(:provider) do + create(:saml_provider, slug: "my-saml", limit_self_registration: false) + end + + it "includes the false value in the auth hash" do + expect(subject[:limit_self_registration]).to be false + end + end end end diff --git a/modules/auth_saml/spec/requests/saml_provider_callback_spec.rb b/modules/auth_saml/spec/requests/saml_provider_callback_spec.rb index 4069e63b8226..eabbb252d350 100644 --- a/modules/auth_saml/spec/requests/saml_provider_callback_spec.rb +++ b/modules/auth_saml/spec/requests/saml_provider_callback_spec.rb @@ -42,7 +42,8 @@ digest_method: "http://www.w3.org/2001/04/xmlenc#sha256", sp_entity_id: "https://foobar.org", idp_cert:, - idp_cert_fingerprint:) + idp_cert_fingerprint:, + limit_self_registration: false) end let(:idp_cert) { nil } diff --git a/modules/auth_saml/spec/services/saml/configuration_mapper_spec.rb b/modules/auth_saml/spec/services/saml/configuration_mapper_spec.rb index 6cf93f4af3fb..149c734e8429 100644 --- a/modules/auth_saml/spec/services/saml/configuration_mapper_spec.rb +++ b/modules/auth_saml/spec/services/saml/configuration_mapper_spec.rb @@ -50,6 +50,34 @@ end end + describe "limit_self_registration" do + subject { result["limit_self_registration"] } + + context "when provided as string" do + let(:configuration) { { limit_self_registration: "1" } } + + it { is_expected.to be(true) } + end + + context "when provided as false boolean" do + let(:configuration) { { limit_self_registration: false } } + + it { is_expected.to be(false) } + end + + context "when provided as true boolean" do + let(:configuration) { { limit_self_registration: true } } + + it { is_expected.to be(true) } + end + + context "when not provided" do + let(:configuration) { {} } + + it { is_expected.to be_nil } + end + end + describe "slug" do subject { result["slug"] } diff --git a/modules/avatars/config/locales/crowdin/js-lv.yml b/modules/avatars/config/locales/crowdin/js-lv.yml index 1cd3c9447519..f91bc898d02e 100644 --- a/modules/avatars/config/locales/crowdin/js-lv.yml +++ b/modules/avatars/config/locales/crowdin/js-lv.yml @@ -4,12 +4,12 @@ lv: label_preview: 'Priekšskatīt' button_update: 'Atjaunot' avatars: - label_choose_avatar: "Choose Avatar from file" - uploading_avatar: "Uploading your avatar." + label_choose_avatar: "Izvēlieties avataru no faila" + uploading_avatar: "Avatāra augšupielāde." text_upload_instructions: | - Upload your own custom avatar of 128 by 128 pixels. Larger files will be resized and cropped to match. - A preview of your avatar will be shown before uploading, once you selected an image. - error_image_too_large: "Image is too large." - wrong_file_format: "Allowed formats are jpg, png, gif" - empty_file_error: "Please upload a valid image (jpg, png, gif)" + Augšupielādējiet savu pielāgotu avatāru 128 x 128 pikseļi. Lielākiem failiem tiks mainīts izmērs un tie tiks apgriezti. + Kad būsiet izvēlējeis avatur, pirms tā augšupielādes tiks parādīts tā priekšskatījums. + error_image_too_large: "Attēls ir pārāk liels." + wrong_file_format: "Atļautie formāti ir jpg, png, gif" + empty_file_error: "Lūdzu, augšupielādējiet atbilstoša formāta attēlu (jpg, png, gif)" diff --git a/modules/avatars/config/locales/crowdin/js-pl.yml b/modules/avatars/config/locales/crowdin/js-pl.yml index aef4746963b9..55c72afa6802 100644 --- a/modules/avatars/config/locales/crowdin/js-pl.yml +++ b/modules/avatars/config/locales/crowdin/js-pl.yml @@ -7,8 +7,8 @@ pl: label_choose_avatar: "Wybierz awatar z pliku" uploading_avatar: "Przesyłanie tego awatara." text_upload_instructions: | - Prześlij swój własny awatar 128 na 128 pikseli. Rozmiar większych plików zostanie zmieniony i zostaną one odpowiednio przycięte. - Podgląd awatara zostanie wyświetlony przed przesłaniem, po wybraniu obrazu. + Prześlij swój awatar rozmiaru 128 na 128 pikseli. Większe pliki zostaną zmniejszone o dopasowane. + Podgląd awatara zostanie wyświetlony przed przesłaniem po wybraniu obrazu. error_image_too_large: "Obraz jest zbyt duży." wrong_file_format: "Dozwolone są formaty jpg, png, gif" empty_file_error: "Prześlij prawidłowy obraz (jpg, png, gif)" diff --git a/modules/avatars/config/locales/crowdin/lv.yml b/modules/avatars/config/locales/crowdin/lv.yml index 86ddcb29d737..9103ac713a9d 100644 --- a/modules/avatars/config/locales/crowdin/lv.yml +++ b/modules/avatars/config/locales/crowdin/lv.yml @@ -4,23 +4,23 @@ lv: name: "Avatars" description: >- This plugin allows OpenProject users to upload a picture to be used as an avatar or use registered images from Gravatar. - label_avatar: "Avatar" - label_avatar_plural: "Avatars" - label_current_avatar: "Current Avatar" - label_choose_avatar: "Choose Avatar from file" - message_avatar_uploaded: "Avatar changed successfully." - error_image_upload: "Error saving the image." - error_image_size: "The image is too large." - are_you_sure_delete_avatar: "Are you sure you want to delete your avatar?" - avatar_deleted: "Avatar deleted successfully." - unable_to_delete_avatar: "Avatar could not be deleted." + label_avatar: "Avatārs" + label_avatar_plural: "Avatāri" + label_current_avatar: "Pašreizējais avatārs" + label_choose_avatar: "Izvēlieties Avatar no faila" + message_avatar_uploaded: "Avatārs veiksmīgi mainīts." + error_image_upload: "Kļūda, saglabājot attēlu." + error_image_size: "Attēls ir pārāk liels." + are_you_sure_delete_avatar: "Vai tiešām vēlies dzēst savu avatāru?" + avatar_deleted: "Avatārs veiksmīgi izdzēsts." + unable_to_delete_avatar: "Avatāru nevarēja izdzēst." wrong_file_format: "Allowed formats are jpg, png, gif" empty_file_error: "Please upload a valid image (jpg, png, gif)" avatars: - label_avatar: "Avatar" + label_avatar: "Avatārs" label_gravatar: 'Gravatar' - label_current_avatar: 'Current avatar' - label_local_avatar: 'Custom avatar' + label_current_avatar: 'Pašreizējais avatārs' + label_local_avatar: 'Pielāgots avatārs' text_current_avatar: | The following image shows the current avatar. text_upload_instructions: | diff --git a/modules/backlogs/config/locales/crowdin/js-lv.yml b/modules/backlogs/config/locales/crowdin/js-lv.yml index f49b8011f930..273987de6bf2 100644 --- a/modules/backlogs/config/locales/crowdin/js-lv.yml +++ b/modules/backlogs/config/locales/crowdin/js-lv.yml @@ -23,4 +23,4 @@ lv: js: work_packages: properties: - storyPoints: "Novērtējums" + storyPoints: "Stāsta punkti" diff --git a/modules/backlogs/config/locales/crowdin/lv.yml b/modules/backlogs/config/locales/crowdin/lv.yml index 1e4b548aa02b..41bcb336399e 100644 --- a/modules/backlogs/config/locales/crowdin/lv.yml +++ b/modules/backlogs/config/locales/crowdin/lv.yml @@ -85,17 +85,17 @@ lv: backlogs_sprint_notes_missing: "Slēgtie sprinti bez retrospekcijas/pārskatīšanas piezīmēm" backlogs_sprint_unestimated: "Slēgti vai aktīvi sprinti ar nenovērtētiem stāstiem" backlogs_sprint_unsized: "Projektā ir stāsti par aktīviem vai nesen pabeigtiem sprintiem, kuru izmērs nav noteikts." - backlogs_sprints: "Sprints" + backlogs_sprints: "Sprinti" backlogs_story: "Stāsts" - backlogs_story_type: "Story types" + backlogs_story_type: "Lietotājstāstu tipi" backlogs_task: "Uzdevums" - backlogs_task_type: "Task type" + backlogs_task_type: "Pieteikumu tipi" backlogs_velocity_missing: "No velocity could be calculated for this project" backlogs_velocity_varies: "Velocity varies significantly over sprints" backlogs_wiki_template: "Template for sprint wiki page" backlogs_empty_title: "No versions are defined to be used in backlogs" backlogs_empty_action_text: "To get started with backlogs, create a new version and assign it to a backlogs column." - button_edit_wiki: "Edit wiki page" + button_edit_wiki: "Rediģēt wiki lapu" error_backlogs_task_cannot_be_story: "The settings are invalid. The selected task type can not also be a story type." error_intro_plural: "The following errors were encountered:" error_intro_singular: "The following error was encountered:" @@ -103,37 +103,37 @@ lv: event_sprint_description: "%{summary}: %{url}\n%{description}" event_sprint_summary: "%{project}: %{summary}" ideal: "ideal" - inclusion: "is not included in the list" - label_back_to_project: "Back to project page" - label_backlog: "Backlog" + inclusion: "nav iekļauts sarakstā" + label_back_to_project: "Atpakaļ uz projekta lapu" + label_backlog: "Neizpildīti darbi" label_backlogs: "Darbu krātuve" label_backlogs_unconfigured: "You have not configured Backlogs yet. Please go to %{administration} > %{plugins}, then click on the %{configure} link for this plugin. Once you have set the fields, come back to this page to start using the tool." label_blocks_ids: "IDs of blocked work packages" label_burndown: "Burndown" - label_column_in_backlog: "Column in backlog" + label_column_in_backlog: "Atlikušo darbu backlog" label_hours: "stundas" - label_work_package_hierarchy: "Work package Hierarchy" - label_master_backlog: "Master Backlog" - label_not_prioritized: "not prioritized" - label_points: "points" - label_points_burn_down: "Down" - label_points_burn_up: "Up" - label_product_backlog: "product backlog" - label_select_all: "Select all" - label_sprint_backlog: "sprint backlog" - label_sprint_cards: "Export cards" - label_sprint_impediments: "Sprint Impediments" + label_work_package_hierarchy: "Pieteikumu hierarhija" + label_master_backlog: "Viss backlog" + label_not_prioritized: "nav noteikta prioritāte" + label_points: "punkti" + label_points_burn_down: "Lejup" + label_points_burn_up: "Augšup" + label_product_backlog: "produkta backlog" + label_select_all: "Atzīmēt visu" + label_sprint_backlog: "sprinta neizpildīto uzdevumu saraksts" + label_sprint_cards: "Eksporta kartītes" + label_sprint_impediments: "Sprinta šķēršļi" label_sprint_name: "Sprint \"%{name}\"" label_sprint_velocity: "Velocity %{velocity}, based on %{sprints} sprints with an average %{days} days" - label_stories: "Stories" - label_stories_tasks: "Stories/Tasks" - label_task_board: "Task board" + label_stories: "Lietotājstāsti" + label_stories_tasks: "Lietotājstāsti/Pieteikumi" + label_task_board: "Pieteikumu tāfele" label_version_setting: "Versijas" label_version: 'Versija' label_webcal: "Webcal Feed" label_wiki: "Wiki" - permission_view_master_backlog: "View master backlog" - permission_view_taskboards: "View taskboards" + permission_view_master_backlog: "Skatīt visus nepabeigtos darbus" + permission_view_taskboards: "Apskatīt uzdevumu dēļus" permission_select_done_statuses: "Izvēlieties pabeigtības statusu" permission_update_sprints: "Atjaunināt sprintus" points_accepted: "Akceptētais novērtējums" diff --git a/modules/backlogs/config/locales/crowdin/pt-BR.yml b/modules/backlogs/config/locales/crowdin/pt-BR.yml index adca5b204645..c6181178c06c 100644 --- a/modules/backlogs/config/locales/crowdin/pt-BR.yml +++ b/modules/backlogs/config/locales/crowdin/pt-BR.yml @@ -34,12 +34,12 @@ pt-BR: work_package: attributes: blocks_ids: - can_only_contain_work_packages_of_current_sprint: "pode conter somente os IDs dos pacotes de trabalho no sprint atual." + can_only_contain_work_packages_of_current_sprint: "pode conter apenas IDs de pacotes de trabalho na sprint atual." must_block_at_least_one_work_package: "deve conter o ID de pelo menos um tíquete." version_id: task_version_must_be_the_same_as_story_version: "deve ser igual à versão da história dos pais." sprint: - cannot_end_before_it_starts: "Sprint não pode terminar antes de começar." + cannot_end_before_it_starts: "A sprint não pode terminar antes de começar." backlogs: add_new_story: "Nova história" any: "qualquer" @@ -57,7 +57,7 @@ pt-BR: label_versions_default_fold_state: "Mostrar versões em modo fechado" work_package_is_closed: "Pacote de trabalho está pronto, quando" label_is_done_status: "Situação %{status_name} significa pronto" - no_burndown_data: "Não há dados de burndown disponíveis. É necessário ter o conjunto de datas de início e fim de sprint." + no_burndown_data: "Nenhum dado de burndown disponível. É necessário definir as datas de início e fim da sprint." points: "Pontos" positions_could_not_be_rebuilt: "Posições não poderiam ser reconstruídas." positions_rebuilt_successfully: "Posições reconstruídas com sucesso." @@ -82,17 +82,17 @@ pt-BR: backlogs_product_backlog_is_empty: "Backlog do produto está vazio" backlogs_product_backlog_unsized: "O topo do backlog de produto tem histórias não dimensionadas" backlogs_sizing_inconsistent: "Tamanhos das histórias contrastam com suas estimativas" - backlogs_sprint_notes_missing: "Sprints fechados sem notas de revisão/retrospectiva" - backlogs_sprint_unestimated: "Sprints ativos ou fechados com histórias não estimadas" - backlogs_sprint_unsized: "Projeto tem histórias em sprints ativos ou recentemente fechados que não tem tamanho" + backlogs_sprint_notes_missing: "Sprints encerradas sem notas de retrospectiva/revisão" + backlogs_sprint_unestimated: "Sprints encerradas ou ativas com histórias não estimadas" + backlogs_sprint_unsized: "O projeto tem histórias em sprints ativas ou recentemente encerradas que não foram dimensionadas" backlogs_sprints: "Sprints" backlogs_story: "História" backlogs_story_type: "Tipos de história" backlogs_task: "Tarefa" backlogs_task_type: "Tipo de tarefa" backlogs_velocity_missing: "Nenhuma velocidade foi calculada para este projeto" - backlogs_velocity_varies: "Velocidade varia significativamente ao longo de sprints" - backlogs_wiki_template: "Modelo para a página de wiki da sprint" + backlogs_velocity_varies: "A velocidade varia significativamente entre as sprints" + backlogs_wiki_template: "Modelo para página wiki da sprint" backlogs_empty_title: "Não há versões definidas para serem usadas nos backlogs" backlogs_empty_action_text: "Para iniciar com backlogs, crie uma nova versão e atribua a uma coluna de backlogs." button_edit_wiki: "Editar página wiki" @@ -120,9 +120,9 @@ pt-BR: label_points_burn_up: "Acima" label_product_backlog: "Backlog do produto" label_select_all: "Selecionar tudo" - label_sprint_backlog: "Backlog do sprint" + label_sprint_backlog: "backlog da sprint" label_sprint_cards: "Exportar cartões" - label_sprint_impediments: "Impedimentos do Sprint" + label_sprint_impediments: "Impedimentos da Sprint" label_sprint_name: "Sprint \"%{name}\"" label_sprint_velocity: "Velocidade %{velocity}, baseado em %{sprints} sprints, com uma média de %{days} dias" label_stories: "Histórias" diff --git a/modules/bim/app/controllers/bim/bcf/issues_controller.rb b/modules/bim/app/controllers/bim/bcf/issues_controller.rb index 6ae7a6681fa1..b9cb9066c739 100644 --- a/modules/bim/app/controllers/bim/bcf/issues_controller.rb +++ b/modules/bim/app/controllers/bim/bcf/issues_controller.rb @@ -46,10 +46,6 @@ class IssuesController < BaseController def upload; end - def index - redirect_to action: :upload - end - def prepare_import render_next rescue StandardError => e diff --git a/modules/bim/app/seeders/bim/basic_data_seeder.rb b/modules/bim/app/seeders/bim/basic_data_seeder.rb index fd404d89db3b..d153b2e42273 100644 --- a/modules/bim/app/seeders/bim/basic_data_seeder.rb +++ b/modules/bim/app/seeders/bim/basic_data_seeder.rb @@ -37,6 +37,8 @@ def data_seeder_classes ::BasicData::TimeEntryActivitySeeder, ::BasicData::ColorSeeder, ::BasicData::ColorSchemeSeeder, + ::BasicData::LifeCycleColorSeeder, + ::BasicData::LifeCycleStepDefinitionSeeder, ::BasicData::WorkflowSeeder, ::BasicData::PrioritySeeder, ::Bim::BasicData::SettingSeeder, diff --git a/modules/bim/app/views/bim/bcf/issues/index.html.erb b/modules/bim/app/views/bim/bcf/issues/index.html.erb deleted file mode 100644 index 7001d48e0dda..000000000000 --- a/modules/bim/app/views/bim/bcf/issues/index.html.erb +++ /dev/null @@ -1,28 +0,0 @@ - - -<%= toolbar title: t('bcf.issues'), html: {class: '-with-dropdown'} do %> - -
  • - <%= link_to({ action: 'upload' }, - title: I18n.t(:label_import), - class: 'button import-bcf-button') do %> - <%= op_icon('button--icon icon-import') %> - <%= t(:label_import) %> - <% end %> -
  • -
  • - <% query = { f: ['bcfIssueAssociated', '=', ['t']] } %> - <%= link_to(project_work_packages_with_query_path(@project, query, format: :bcf), - title: t('bcf.bcf_xml.export'), - class: 'button export-bcf-button') do %> - <%= op_icon('button--icon icon-export') %> - <%= t('bcf.bcf_xml.export') %> - <% end %> -
  • -<% end %> - -<%= render partial: 'render_issues', locals: { issues: @issues } %> - -<%= pagination_links_full @issues %> diff --git a/modules/bim/bin/setup_dev.sh b/modules/bim/bin/setup_dev.sh index 25104c5e7006..b4484b55f872 100755 --- a/modules/bim/bin/setup_dev.sh +++ b/modules/bim/bin/setup_dev.sh @@ -25,8 +25,8 @@ unzip -q COLLADA2GLTF-v2.1.5-linux.zip mv COLLADA2GLTF-bin "/usr/local/bin/COLLADA2GLTF" # IFCconvert -wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.6.0-517b819-linux64.zip -unzip -q IfcConvert-v0.6.0-517b819-linux64.zip +wget --quiet https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.7.11-fea8e3a-linux64.zip +unzip -q IfcConvert-v0.7.11-fea8e3a-linux64.zip mv IfcConvert "/usr/local/bin/IfcConvert" wget --quiet https://github.com/bimspot/xeokit-metadata/releases/download/1.0.1/xeokit-metadata-linux-x64.tar.gz diff --git a/modules/bim/config/locales/crowdin/js-fa.yml b/modules/bim/config/locales/crowdin/js-fa.yml index c8c3844fdff0..9adfc6ead415 100644 --- a/modules/bim/config/locales/crowdin/js-fa.yml +++ b/modules/bim/config/locales/crowdin/js-fa.yml @@ -12,8 +12,8 @@ fa: show_viewpoint: 'Show viewpoint' delete_viewpoint: 'Delete viewpoint' management: 'BCF management' - refresh: 'Refresh' - refresh_work_package: 'Refresh work package' + refresh: 'بازنشانی' + refresh_work_package: 'بازنشانی بسته کار' ifc_models: empty_warning: "This project does not yet have any IFC models." use_this_link_to_manage: "Use this link to upload and manage your IFC models" diff --git a/modules/bim/config/locales/crowdin/lv.seeders.yml b/modules/bim/config/locales/crowdin/lv.seeders.yml index 378f1afc5008..7865aa8c9f61 100644 --- a/modules/bim/config/locales/crowdin/lv.seeders.yml +++ b/modules/bim/config/locales/crowdin/lv.seeders.yml @@ -7,47 +7,47 @@ lv: bim: priorities: item_0: - name: Low + name: Zema item_1: - name: Normal + name: Parasta item_2: - name: High + name: Augsta item_3: - name: Critical + name: Kritiska statuses: item_0: - name: New + name: Jauns item_1: - name: In progress + name: Izpildē item_2: - name: Resolved + name: Atrisināts item_3: - name: Closed + name: Aizvērts time_entry_activities: item_0: - name: Management + name: Vadība item_1: - name: Specification + name: Prasību definēšana item_2: - name: Other + name: Cits types: item_0: name: Uzdevums item_1: name: Atskaites punkts item_2: - name: Phase + name: Fāze item_3: name: Kļūda item_4: - name: Remark + name: Piezīme item_5: - name: Request + name: Pieprasījums item_6: - name: Clash + name: Konflikts global_queries: item_0: - name: 'Embedded table: Children' + name: 'Iestrādātā tabula: Bērni' type_configuration: item_0: form_configuration: @@ -55,23 +55,23 @@ lv: group_name: Bērni groups: item_0: - name: Architects + name: Arhitekti item_1: - name: BIM Coordinators + name: BIM koordinatori item_2: - name: BIM Managers + name: BIM pārvaldītāji item_3: - name: BIM Modellers + name: BIM modelētāji item_4: - name: Lead BIM Coordinators + name: Vadošie BIM koordinatori item_5: - name: MEP Engineers + name: MEP inženieri item_6: - name: Planners + name: Plānotāji item_7: - name: Structural Engineers + name: Būvinženieri welcome: - title: Welcome to OpenProject BIM edition! + title: Laipni lūgti OpenProject BIM versijā! text: | Checkout the demo projects to get started with some examples. @@ -105,7 +105,7 @@ lv: item_1: name: Milestones item_2: - name: Tasks + name: Pieteikumi item_3: name: Komandas plānotājs boards: @@ -115,10 +115,10 @@ lv: widgets: item_0: options: - name: Welcome + name: Sveicināti item_1: options: - name: Getting started + name: Uzsākot darbu text: | We are glad you joined! We suggest to try a few things to get started in OpenProject. @@ -147,7 +147,7 @@ lv: name: Pieteikumi item_6: options: - name: Milestones + name: Atskaites punkts demo-planning-constructing-project: name: "(Demo) Planning & constructing" status_explanation: All tasks are on schedule. The people involved know their tasks. The system is completely set up. @@ -165,7 +165,7 @@ lv: item_0: name: Project plan item_1: - name: Milestones + name: Atskaites punkti item_2: name: Tasks item_3: @@ -307,7 +307,7 @@ lv: subject: Construction phase children: item_0: - subject: Start constructing + subject: Sākt būvēt description: |- ## Goal @@ -321,7 +321,7 @@ lv: * Get the team together * ... item_1: - subject: Foundation + subject: Pamati description: |- ## Goal @@ -421,7 +421,7 @@ lv: item_1: name: Milestones item_2: - name: Tasks + name: Uzdevumi item_3: name: Komandas plānotājs project-overview: diff --git a/modules/bim/config/locales/crowdin/pt-BR.seeders.yml b/modules/bim/config/locales/crowdin/pt-BR.seeders.yml index 0d82162c385c..f6babbe76fde 100644 --- a/modules/bim/config/locales/crowdin/pt-BR.seeders.yml +++ b/modules/bim/config/locales/crowdin/pt-BR.seeders.yml @@ -459,7 +459,7 @@ pt-BR: name: Pacotes de trabalho item_6: options: - name: Etapas + name: Marcos work_packages: item_0: subject: Kick off do projeto criando modelo BIM diff --git a/modules/bim/config/locales/crowdin/ru.seeders.yml b/modules/bim/config/locales/crowdin/ru.seeders.yml index d709222a3d9a..fc7dd977d2fe 100644 --- a/modules/bim/config/locales/crowdin/ru.seeders.yml +++ b/modules/bim/config/locales/crowdin/ru.seeders.yml @@ -75,16 +75,16 @@ ru: text: | Ознакомьтесь с демонстрационными проектами, чтобы начать работу с некоторыми примерами. - * [(Демонстрационный) Проект разработки]({{Настройка:base_url}}/projects/demo-construction-project): Планирование, BIM-процесс, управление BCF и создание - все с первого взгляда. - * [(Демо) Планирование и разработка]({{{{opSetting:base_url}}Настройка параметров:base_url}}/projects/demo-planning-constructing-project): Классическое планирование и управление разработкой. - * [(Демо) Bim-проект]({{opSetting:base_url}}/projects/demo-bim-project): BIM-процесс и координация. - * [(Демо) Управление BCF]({{opSetting:base_url}}/projects/demo-bcf-management-project): управление BCF. + * [(Demo) Проект постройки]({{opSetting:base_url}}/projects/demo-construction-project): Планирование, BIM процессы, BCF управление и стройка, всё в одном месте. + * [(Demo) Планирование и стройка]({{opSetting:base_url}}/projects/demo-planning-constructing-project): Классическое планирование и управление стройкой. + * [(Demo) BIM проект]({{opSetting:base_url}}/projects/demo-bim-project): BIM процесс и координация. + * [(Demo) BCF управление]({{opSetting:base_url}}/projects/demo-bcf-management-project): BCF управление. - Также вы можете создать пустой [новый проект]({{opSetting:base_url}}/projects/new). + Также, вы можете создать пустой [новый проект]({{opSetting:base_url}}/projects/new). - Никогда не прекращайте сотрудничество. С открытым исходным кодом и непредвзятым мышлением. + Неикогда не прекращайте сотрудничество. С открытым исходным кодом и непредвзятым мышлением. - Вы можете изменить этот текст приветствия [здесь]({{opSetting:base_url}}/admin/settings/general). + Вы можете именить этот текст приветствия [здесь]({{opSetting:base_url}}/admin/settings/general). projects: demo-construction-project: name: "(Демо) Конструкторский проект" @@ -120,7 +120,25 @@ ru: options: name: Приступая к работе text: | - shared with me + Мы рады, что Вы присоединились! Предлагаем Вам попробовать несколько функций для начала работы в OpenProject. + + Но прежде чем приступить к работе, Вам следует знать, что этот демонстрационный проект разделён на два разных проекта: + + 1. [Проект постройки]({{opSetting:base_url}}/projects/demo-planning-constructing-project): Здесь вы найдёте классические роли, некоторые рабочие потоки и пакеты работ вашего проекта стройки. + 2. [Создание BIM модели]({{opSetting:base_url}}/projects/demo-bim-project): Этот проект так же предлагает к ознакомлению роли, рабочие потоки и пакеты работ, но в контексте BIM + + _Попробуйте выполнить следующие шаги:_ + + 1. _Пригласите новых участников в Ваш проект_: → Перейдите [Участники]({{opSetting:base_url}}/projects/demo-construction-project/members) в меню навигации по проекту. + 2. _Посмотрите работы в Вашем проекте_: → Перейдите [Пакеты работ]({{opSetting:base_url}}/projects/demo-construction-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) в меню навигации по проекту. + 3. _Создайте новый пакет работ_: → Перейдите в [Пакет работ → Создать]({{opSetting:base_url}}/projects/demo-construction-project/work_packages/new?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D&type=11). + 4. _Создайте и обновите диаграмму Гантта_: → Перейдите в [Диаграмма Гантта]({{opSetting:base_url}}/projects/demo-construction-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22assignee%22%2C%22responsible%22%5D%2C%22tv%22%3Atrue%2C%22tzl%22%3A%22weeks%22%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) в меню навигации по проекту. + 5. _Активируйте дополнительные модули_: → Перейдите в [Настройки проекта → Модули]({{opSetting:base_url}}/projects/demo-construction-project/settings/modules). + 6. _Проверьте плиточный вид, чтобы получить общее представление о проблемах вашего BCF:_ → Перейдите в [Пакеты работ]({{opSetting:base_url}}/projects/demo-construction-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22id%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22card%22%7D) + 7. _Используете Agile? Посмотрите функционал наших новых досок:_ → Перейдите в [Доски]({{opSetting:base_url}}/projects/demo-construction-project/boards) + + Здесь вы найдёте наши [Инструкции пользователя](https://www.openproject.org/docs/user-guide/). + Пожалуйста, дайте нам знать, если у Вас возникнут вопросы или необходима техническая поддержка. Свяжитесь с нами: [support\[at\]openproject.com](mailto:support@openproject.com). item_4: options: name: Участники @@ -415,24 +433,24 @@ ru: options: name: Приступая к работе text: | - We are glad you joined! We suggest to try a few things to get started in OpenProject. + Мы рады, что Вы присоединились! Мы предлагаем Вам попробовать несколько вещей, чтобы начать работу в OpenProject. - This demo project offers roles, workflows and work packages that are specialized for BIM. + Этот демонстрационный проект предлагает роли, рабочие процессы и рабочие пакеты, специализированные для BIM. - _Try the following steps:_ + _Попробуйте выполнить следующие шаги:_ - 1. _Invite new members to your project:_ → Go to [Members]({{opSetting:base_url}}/projects/demo-bim-project/members) in the project navigation. - 2. _Upload and view 3D-models in IFC format:_ → Go to [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) in the project navigation. - 3. _Create and manage BCF issues linked directly in the IFC model:_ → Go to [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) → Create. - 4. _View the work in your projects:_ → Go to [Work packages]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) in the project navigation. - 5. _Create a new work package:_ → Go to [Work packages → Create]({{opSetting:base_url}}/projects/demo-bim-project/work_packages/new?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D&type=11). - 6. _Create and update a Gantt chart:_ → Go to [Gantt chart]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22assignee%22%2C%22responsible%22%5D%2C%22tv%22%3Atrue%2C%22tzl%22%3A%22weeks%22%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) in the project navigation. - 7. _Activate further modules:_ → Go to [Project settings → Modules]({{opSetting:base_url}}/projects/demo-bim-project/settings/modules). - 8. _Check out the tile view to get an overview of your BCF issues:_ → Go to [Work packages]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22id%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22card%22%7D) - 9. _Working agile? Create a new board:_ → Go to [Boards]({{opSetting:base_url}}/projects/demo-bim-project/boards) + 1. _Пригласите новых участников в Ваш проект:_ → Перейдите в раздел [Участники]({{opSetting:base_url}}/projects/demo-bim-project/members) в навигации проекта. + 2. _Загрузка и просмотр 3D-моделей в формате IFC:_ → Перейдите к разделу [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) в навигации проекта. + 3. _Создание и управление вопросами BCF, связанными непосредственно с моделью IFC:_ → Перейдите к [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) → Создать. + 4. _Просмотр работ в Ваших проектах:_ → Перейдите в раздел [Рабочие пакеты]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) в навигации проекта. + 5. _Создайте новый рабочий пакет:_ → Перейдите в раздел [Рабочие пакеты → Создать]({{opSetting:base_url}}/projects/demo-bim-project/work_packages/new?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22bcfIssueAssociated%22%2C%22o%22%3A%22%3D%22%2C%22v%22%3A%5B%22f%22%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D&type=11). + 6. _Создание и обновление диаграммы Ганта:_ → Перейдите на страницу [Диаграмма Ганта]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22assignee%22%2C%22responsible%22%5D%2C%22tv%22%3Atrue%2C%22tzl%22%3A%22weeks%22%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22list%22%7D) в навигации проекта. + 7. _Активируйте дальнейшие модули:_ → Перейдите в раздел [Настройки проекта → Модули]({{opSetting:base_url}}/projects/demo-bim-project/settings/modules). + 8. _Проверьте плиточный вид, чтобы получить обзор Ваших BCF-проблем:_ → Перейдите в раздел [Рабочие пакеты]({{opSetting:base_url}}/projects/demo-bim-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22priority%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22id%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22card%22%7D) + 9. _Работаете в стиле agile? Создайте новую доску:_ → Перейдите в раздел [Доски]({{opSetting:base_url}}/projects/demo-bim-project/boards) - Here you will find our [User Guides](https://www.openproject.org/docs/user-guide/). - Please let us know if you have any questions or need support. Contact us: [support\[at\]openproject.com](mailto:support@openproject.com). + Здесь Вы найдете наши [Руководства пользователя](https://www.openproject.org/docs/user-guide/). + Пожалуйста, сообщите нам, если у Вас возникнут вопросы или Вам понадобится поддержка. Свяжитесь с нами: [support\[at\]openproject.com](mailto:support@openproject.com). item_4: options: name: Участники @@ -691,23 +709,23 @@ ru: options: name: Приступая к работе text: | - We are glad you joined! We suggest to try a few things to get started in OpenProject. + Мы рады, что Вы присоединились! Мы предлагаем Вам попробовать несколько вещей, чтобы начать работу в OpenProject. - This demo project shows BCF management functionalities. + Этот демо-проект демонстрирует функциональные возможности управления BCF. - _Try the following steps:_ + _Попробуйте выполнить следующие шаги:_ - 1. _Invite new members to your project:_ → Go to [Members]({{opSetting:base_url}}/projects/demo-bcf-management-project/members?show_add_members=true) in the project navigation. - 2. _Upload and view 3D-models in IFC format:_ → Go to [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) in the project navigation. - 3. _Create and manage BCF issues linked directly in the IFC model:_ → Go to [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) → Create. - 4. _View the BCF files in your project:_ → Go to [BCF]({{opSetting:base_url}}/projects/demo-bcf-management-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22status%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22id%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22card%22%7D) in the project navigation. - 5. _Load your BCF files:_ → Go to [BCF → Import.]({{opSetting:base_url}}/projects/demo-bcf-management-project/issues/upload) - 6. _Create and update a Gantt chart:_ → Go to [Gantt chart]({{opSetting:base_url}}/projects/demo-bcf-management-project/work_packages?query_props=%7B%22c%22%3A%5B%22id%22%2C%22subject%22%2C%22startDate%22%2C%22dueDate%22%5D%2C%22tv%22%3Atrue%2C%22tzl%22%3A%22days%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22status%22%2C%22o%22%3A%22o%22%2C%22v%22%3A%5B%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%7D) in the project navigation. - 7. _Activate further modules:_ → Go to [Project settings → Modules.]({{opSetting:base_url}}/projects/demo-bcf-management-project/settings/modules) - 8. _You love the agile approach? Create a board:_ → Go to [Boards]({{opSetting:base_url}}/projects/demo-bcf-management-project/boards). + 1. _Пригласите новых участников в Ваш проект:_ → Перейдите в [Участники]({{opSetting:base_url}}/projects/demo-bcf-management-project/members?show_add_members=true) в навигации проекта. + 2. _Загрузка и просмотр 3D-моделей в формате IFC:_ → Перейдите к [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) в навигации проекта. + 3. _Создание и управление вопросами BCF, связанными непосредственно с моделью IFC:_ → Перейдите к [BCF]({{opSetting:base_url}}/projects/demo-bim-project/bcf) → Создать. + 4. _Просмотр файлов BCF в Вашем проекте:_ → Перейдите к [BCF]({{opSetting:base_url}}/projects/demo-bcf-management-project/work_packages?query_props=%7B%22c%22%3A%5B%22type%22%2C%22id%22%2C%22subject%22%2C%22status%22%2C%22assignee%22%2C%22priority%22%5D%2C%22hl%22%3A%22status%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22id%3Aasc%22%2C%22f%22%3A%5B%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%2C%22dr%22%3A%22card%22%7D) в навигации проекта. + 5. _Загрузите файлы BCF:_ → Перейдите по ссылке [BCF → Импорт.]({{opSetting:base_url}}/projects/demo-bcf-management-project/issues/upload) + 6. _Создание и обновление диаграммы Ганта:_ → Перейдите к [Диаграмма Ганта]({{opSetting:base_url}}/projects/demo-bcf-management-project/work_packages?query_props=%7B%22c%22%3A%5B%22id%22%2C%22subject%22%2C%22startDate%22%2C%22dueDate%22%5D%2C%22tv%22%3Atrue%2C%22tzl%22%3A%22days%22%2C%22hi%22%3Atrue%2C%22g%22%3A%22%22%2C%22t%22%3A%22startDate%3Aasc%22%2C%22f%22%3A%5B%7B%22n%22%3A%22status%22%2C%22o%22%3A%22o%22%2C%22v%22%3A%5B%5D%7D%5D%2C%22pa%22%3A1%2C%22pp%22%3A100%7D) в навигации проекта. + 7. _Активируйте дальнейшие модули:_ → Перейдите в раздел [Настройки проекта → Модули.]({{opSetting:base_url}}/projects/demo-bcf-management-project/settings/modules) + 8. _Вам нравится agile-подход? Создайте доску:_ → Перейдите в раздел [Доски]({{opSetting:base_url}}/projects/demo-bcf-management-project/boards). - Here you will find our [User Guides](https://www.openproject.org/docs/user-guide/). - Please let us know if you have any questions or need support. Contact us: [support\[at\]openproject.com](mailto:support@openproject.com). + Здесь Вы найдете наши [Руководства пользователя](https://www.openproject.org/docs/user-guide/). + Пожалуйста, сообщите нам, если у Вас возникнут вопросы или Вам понадобится поддержка. Свяжитесь с нами: [support\[at\]openproject.com](mailto:support@openproject.com). item_4: options: name: Участники diff --git a/modules/bim/config/routes.rb b/modules/bim/config/routes.rb index 18ced9377ee2..b6e8c749e3af 100644 --- a/modules/bim/config/routes.rb +++ b/modules/bim/config/routes.rb @@ -33,7 +33,7 @@ scope "projects/:project_id", as: "project" do get "bcf/menu" => "bim/menus#show" - resources :issues, controller: "bim/bcf/issues" do + resources :issues, controller: "bim/bcf/issues", except: :index do get :upload, action: :upload, on: :collection post :prepare_import, action: :prepare_import, on: :collection post :configure_import, action: :configure_import, on: :collection diff --git a/modules/bim/lib/open_project/bim/engine.rb b/modules/bim/lib/open_project/bim/engine.rb index fb7deae4ad75..53e9e5a3aff8 100644 --- a/modules/bim/lib/open_project/bim/engine.rb +++ b/modules/bim/lib/open_project/bim/engine.rb @@ -57,12 +57,12 @@ class Engine < ::Rails::Engine dependencies: %i[view_ifc_models], contract_actions: { ifc_models: %i[create update destroy] } permission :view_linked_issues, - { "bim/bcf/issues": %i[index] }, + {}, permissible_on: :project, dependencies: %i[view_work_packages], contract_actions: { bcf: %i[read] } permission :manage_bcf, - { "bim/bcf/issues": %i[index upload prepare_import configure_import perform_import] }, + { "bim/bcf/issues": %i[upload prepare_import configure_import perform_import] }, permissible_on: :project, dependencies: %i[view_linked_issues view_work_packages diff --git a/modules/bim/spec/seeders/root_seeder_bim_edition_spec.rb b/modules/bim/spec/seeders/root_seeder_bim_edition_spec.rb index ab647887a86c..892c1ce4ebce 100644 --- a/modules/bim/spec/seeders/root_seeder_bim_edition_spec.rb +++ b/modules/bim/spec/seeders/root_seeder_bim_edition_spec.rb @@ -98,7 +98,7 @@ def group_name(reference) ) end - include_examples "it creates records", model: Color, expected_count: 144 + include_examples "it creates records", model: Color, expected_count: 149 include_examples "it creates records", model: DocumentCategory, expected_count: 3 include_examples "it creates records", model: IssuePriority, expected_count: 4 include_examples "it creates records", model: Status, expected_count: 4 @@ -249,4 +249,27 @@ def group_name(reference) include_examples "no email deliveries" end + + context "when admin user creation is locked with OPENPROJECT_SEED_ADMIN_USER_LOCKED=true", + :settings_reset do + shared_let(:root_seeder) { described_class.new } + + before_all do + with_env("OPENPROJECT_SEED_ADMIN_USER_LOCKED" => "true") do + with_edition("bim") do + reset(:seed_admin_user_locked) + root_seeder.seed_data! + end + end + ensure + reset(:seed_admin_user_locked) + RequestStore.clear! # resets `User.current` cached result + end + + it "seeds without any errors, but locks the admin user", :aggregate_failures do + expect(Project.count).to eq 4 + expect(WorkPackage.count).to eq 76 + expect(root_seeder.admin_user).to be_locked + end + end end diff --git a/modules/boards/app/views/boards/boards/overview.html.erb b/modules/boards/app/views/boards/boards/overview.html.erb deleted file mode 100644 index 95736aa6903f..000000000000 --- a/modules/boards/app/views/boards/boards/overview.html.erb +++ /dev/null @@ -1,40 +0,0 @@ -<%#-- copyright -OpenProject is an open source project management software. -Copyright (C) the OpenProject GmbH - -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-2013 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 COPYRIGHT and LICENSE files for more details. - -++#%> - -<% html_title(t('boards.label_boards')) -%> - -<%= toolbar title: t('boards.label_boards') do %> - <%= render Boards::AddButtonComponent.new %> -<% end %> - -<% if @board_grids.empty? -%> - <%= no_results_box %> -<% else -%> -<%= render Boards::TableComponent.new(rows: @board_grids, current_user: User.current) %> -<% end -%> diff --git a/modules/boards/config/locales/crowdin/js-ro.yml b/modules/boards/config/locales/crowdin/js-ro.yml index 1d9dbc15c521..bcc598a1e862 100644 --- a/modules/boards/config/locales/crowdin/js-ro.yml +++ b/modules/boards/config/locales/crowdin/js-ro.yml @@ -28,7 +28,7 @@ ro: error_attribute_not_writable: "Nu se poate muta pachetul de lucru, %{attribute} nu este inscriptibil." error_loading_the_list: "Eroare la încărcarea listei: %{error_message}" error_permission_missing: "Lipsește permisiunea de a crea interogări publice" - error_cannot_move_into_self: "Nu puteți muta un pachet de lucru în coloana sa proprie." + error_cannot_move_into_self: "Nu p0ți muta un pachet de lucru în coloana sa proprie." text_hidden_list_warning: "Nu toate listele sunt afișate deoarece nu aveți permisiunea. Contactați administratorul pentru mai multe informații." click_to_remove_list: "Clic pentru a elimina această listă" board_type: diff --git a/modules/boards/spec/features/board_navigation_spec.rb b/modules/boards/spec/features/board_navigation_spec.rb index d82947258daf..f6cbf815b460 100644 --- a/modules/boards/spec/features/board_navigation_spec.rb +++ b/modules/boards/spec/features/board_navigation_spec.rb @@ -129,6 +129,7 @@ # Add a new WP on the board board_page = board_index.open_board board_view + board_page.expect_query "List 1", editable: true board_page.add_card "List 1", "Task 1" board_page.expect_toast message: I18n.t(:notice_successful_create) @@ -138,9 +139,9 @@ # Open the details page with the info icon card = board_page.card_for(wp) split_view = card.open_details_view - split_view.ensure_page_loaded split_view.expect_subject - split_view.switch_to_tab tab: "Relations" + split_view.switch_to_tab tab: :relations + expect(page).to have_current_path /details\/#{wp.id}\/relations/ # Go to full view of WP full_view = split_view.switch_to_fullscreen @@ -159,6 +160,7 @@ # Add a new WP on the board board_page = board_index.open_board board_view + board_page.expect_query "List 1", editable: true board_page.add_card "List 1", "Task 1" board_page.expect_toast message: I18n.t(:notice_successful_create) @@ -168,7 +170,6 @@ # Open the details page with the info icon card = board_page.card_for(wp) split_view = card.open_details_view - split_view.ensure_page_loaded split_view.expect_subject page.driver.refresh diff --git a/modules/budgets/app/controllers/budgets_controller.rb b/modules/budgets/app/controllers/budgets_controller.rb index 7f01d8adf16a..f820b9b9fd80 100644 --- a/modules/budgets/app/controllers/budgets_controller.rb +++ b/modules/budgets/app/controllers/budgets_controller.rb @@ -229,7 +229,7 @@ def find_optional_project def render_item_as_json(element_id, costs, unit, project, permission) response = { "#{element_id}_unit_name" => ActionController::Base.helpers.sanitize(unit), - "#{element_id}_currency" => Setting.plugin_costs["costs_currency"] + "#{element_id}_currency" => Setting.costs_currency } if current_user.allowed_in_project?(permission, project) diff --git a/modules/budgets/app/views/budgets/items/_budget_override_cost_form.html.erb b/modules/budgets/app/views/budgets/items/_budget_override_cost_form.html.erb index b58df02221d3..101ee5b6e8a0 100644 --- a/modules/budgets/app/views/budgets/items/_budget_override_cost_form.html.erb +++ b/modules/budgets/app/views/budgets/items/_budget_override_cost_form.html.erb @@ -12,7 +12,7 @@ ) %>
    - <%= Setting.plugin_costs['costs_currency'] %> + <%= Setting.costs_currency %>
    diff --git a/modules/budgets/config/locales/crowdin/lv.yml b/modules/budgets/config/locales/crowdin/lv.yml index 1d9769c21882..0eef04d5c012 100644 --- a/modules/budgets/config/locales/crowdin/lv.yml +++ b/modules/budgets/config/locales/crowdin/lv.yml @@ -26,8 +26,8 @@ lv: attributes: budget: author: "Autors" - available: "Available" - budget: "Planned" + available: "Pieejams" + budget: "Plānots" budget_ratio: "Spent (ratio)" description: "Apraksts" spent: "Pavadīts" @@ -37,20 +37,20 @@ lv: labor_budget: "Planned labor costs" material_budget: "Planned unit costs" work_package: - budget_subject: "Budget title" + budget_subject: "Budžeta nosaukums" models: budget: "Budžets" - material_budget_item: "Unit" + material_budget_item: "Vienība" activity: filter: budget: "Budžets" attributes: budget: "Budžets" - button_add_budget_item: "Add planned costs" - button_add_budget: "Add budget" - button_add_cost_type: "Add cost type" - button_cancel_edit_budget: "Cancel editing budget" - button_cancel_edit_costs: "Cancel editing costs" + button_add_budget_item: "Pievienot plānotās izmaksas" + button_add_budget: "Pievienot budžetu" + button_add_cost_type: "Pievienot izmaksu veidu" + button_cancel_edit_budget: "Atcelt budžeta rediģēšanu" + button_cancel_edit_costs: "Atcelt izmaksu rediģēšanu" caption_labor: "Labor" caption_labor_costs: "Actual labor costs" caption_material_costs: "Actual unit costs" diff --git a/modules/budgets/spec/features/budgets/update_budget_spec.rb b/modules/budgets/spec/features/budgets/update_budget_spec.rb index 8958488a8d43..5da73d7fae42 100644 --- a/modules/budgets/spec/features/budgets/update_budget_spec.rb +++ b/modules/budgets/spec/features/budgets/update_budget_spec.rb @@ -205,13 +205,7 @@ expect(material_budget_item_2.costs).to eq(543.0) end - context "with a reversed currency format" do - before do - allow(Setting) - .to receive(:plugin_costs) - .and_return({ costs_currency_format: "%u %n", costs_currency: "USD" }.with_indifferent_access) - end - + context "with a reversed currency format", with_settings: { costs_currency_format: "%u %n", costs_currency: "USD" } do it "can still update budgets (Regression test #32664)" do budget_page.visit! click_on "Update" @@ -282,13 +276,7 @@ expect(labor_budget_item_2.costs).to eq(987.0) end - context "with a reversed currency format" do - before do - allow(Setting) - .to receive(:plugin_costs) - .and_return({ costs_currency_format: "%u %n", costs_currency: "USD" }.with_indifferent_access) - end - + context "with a reversed currency format", with_settings: { costs_currency_format: "%u %n", costs_currency: "USD" } do it "can still update budgets (Regression test #32664)" do budget_page.visit! click_on "Update" diff --git a/modules/calendar/config/locales/crowdin/js-ro.yml b/modules/calendar/config/locales/crowdin/js-ro.yml index ced4dcf1b8f6..c970dc3245a2 100644 --- a/modules/calendar/config/locales/crowdin/js-ro.yml +++ b/modules/calendar/config/locales/crowdin/js-ro.yml @@ -2,7 +2,7 @@ ro: js: calendar: - create_new: 'Creați un calendar nou' + create_new: 'Creează un calendar nou' title: 'Calendar' too_many: 'Există %{count} pachete de lucru în total, dar numai %{max} poate fi afișat.' unsaved_title: 'Calendar fără nume' diff --git a/modules/calendar/config/locales/crowdin/ro.yml b/modules/calendar/config/locales/crowdin/ro.yml index e17a56839dc5..bb0848980691 100644 --- a/modules/calendar/config/locales/crowdin/ro.yml +++ b/modules/calendar/config/locales/crowdin/ro.yml @@ -7,6 +7,6 @@ ro: label_calendar_plural: "Calendare" label_new_calendar: "New calendar" permission_view_calendar: "Vezi calendarele" - permission_manage_calendars: "Gestionare calendare" + permission_manage_calendars: "Gestionează calendare" permission_share_calendars: "Subscribe to iCalendars" project_module_calendar_view: "Calendare" diff --git a/modules/costs/app/controllers/costs_settings_controller.rb b/modules/costs/app/controllers/costs_settings_controller.rb new file mode 100644 index 000000000000..737541a38b4f --- /dev/null +++ b/modules/costs/app/controllers/costs_settings_controller.rb @@ -0,0 +1,31 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) the OpenProject GmbH +# +# 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-2013 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 COPYRIGHT and LICENSE files for more details. +#++ + +class CostsSettingsController < Admin::SettingsController + menu_item :admin_costs +end diff --git a/modules/costs/app/models/time_entry.rb b/modules/costs/app/models/time_entry.rb index 1388a2379932..7ca7f424c695 100644 --- a/modules/costs/app/models/time_entry.rb +++ b/modules/costs/app/models/time_entry.rb @@ -36,6 +36,9 @@ class TimeEntry < ApplicationRecord belongs_to :rate, -> { where(type: %w[HourlyRate DefaultHourlyRate]) }, class_name: "Rate" belongs_to :logged_by, class_name: "User" + MIN_TIME = 0 # => 00:00 + MAX_TIME = (60 * 24) - 1 # => 23:59 + acts_as_customizable acts_as_journalized @@ -44,6 +47,14 @@ class TimeEntry < ApplicationRecord validates_presence_of :hours, if: -> { !ongoing? } validates_numericality_of :hours, allow_nil: true, message: :invalid + validates :start_time, :hours, + presence: true, + if: -> { TimeEntry.must_track_start_and_end_time? } + + validates :start_time, + numericality: { only_integer: true, greater_than_or_equal_to: MIN_TIME, less_than_or_equal_to: MAX_TIME }, + allow_blank: true + scope :on_work_packages, ->(work_packages) { where(work_package_id: work_packages) } extend ::TimeEntries::TimeEntryScopes @@ -101,9 +112,41 @@ def costs_visible_by?(usr) (user_id == usr.id && usr.allowed_in_project?(:view_own_hourly_rate, project)) end + def start_timestamp + return nil if start_time.blank? + return nil if time_zone.blank? + + time_zone_object.local(spent_on.year, spent_on.month, spent_on.day, start_time / 60, start_time % 60) + end + + def end_timestamp + return nil if start_time.blank? + return nil if time_zone.blank? + return nil if hours.blank? + + start_timestamp + hours.hours + end + + class << self + def can_track_start_and_end_time?(_project: nil) + OpenProject::FeatureDecisions.track_start_and_end_times_for_time_entries_active? && + Setting.allow_tracking_start_and_end_times? + # TODO: Add project check when we have decided if we also want a project specific flag + end + + def must_track_start_and_end_time?(_project: nil) + can_track_start_and_end_time? && Setting.enforce_tracking_start_and_end_times? + # TODO: Add project check when we have decided if we also want a project specific flag + end + end + private def cost_attribute hours end + + def time_zone_object + ActiveSupport::TimeZone[time_zone] + end end diff --git a/modules/costs/app/views/cost_types/_list.html.erb b/modules/costs/app/views/cost_types/_list.html.erb index 0e721aa73901..f5c50f77d51c 100644 --- a/modules/costs/app/views/cost_types/_list.html.erb +++ b/modules/costs/app/views/cost_types/_list.html.erb @@ -98,7 +98,7 @@ See COPYRIGHT and LICENSE files for more details. placeholder: t(:label_example_placeholder, decimal: unitless_currency_number(1000.50)), id: "rate_field_#{cost_type.id}" %> - <%= Setting.plugin_costs['costs_currency'] %> + <%= Setting.costs_currency %>