diff --git a/.github/workflows/continuous-delivery.yml b/.github/workflows/continuous-delivery.yml index 24d6f427c1b..aefdc7c153d 100644 --- a/.github/workflows/continuous-delivery.yml +++ b/.github/workflows/continuous-delivery.yml @@ -5,6 +5,8 @@ on: - dev - release/* - stable/* + tags: + - 'v*.*.*' permissions: contents: read @@ -12,7 +14,7 @@ jobs: trigger_downstream_workflow: permissions: contents: none - if: github.repository == 'opf/openproject' + if: github.repository == 'opf/openproject' && github.ref_type == 'branch' runs-on: ubuntu-latest steps: - name: Trigger Flavours workflow @@ -29,3 +31,30 @@ jobs: -XPOST -H"Accept: application/vnd.github.v3+json" \ https://api.github.com/repos/$REPOSITORY/actions/workflows/$WORKFLOW_ID/dispatches \ -d "$PAYLOAD" + + trigger_stable_tag_workflow: + permissions: + contents: none + if: github.repository == 'opf/openproject' && github.ref_type == 'tag' + runs-on: ubuntu-latest + steps: + - name: Trigger Flavours stable workflow for tag + env: + TOKEN: ${{ secrets.OPENPROJECTCI_FLAVOUR_TRIGGER_TOKEN }} + REPOSITORY: opf/openproject-flavours + WORKFLOW_ID: ci-stable.yml + TAG_NAME: ${{ github.ref_name }} + THIS_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + TAG="${TAG_NAME#v}" # strip leading 'v': 17.3.1 + MINOR="${TAG%.*}" # strip patch: 17.3 + BRANCH="release/$MINOR" # release/17.3 + PAYLOAD=$(jq -n \ + --arg ref "$BRANCH" \ + --arg tag "$TAG" \ + --arg triggered_by_url "$THIS_RUN_URL" \ + '{"ref": "dev", "inputs": {"ref": $ref, "tag": $tag, "triggered_by_url": $triggered_by_url}}') + curl -i --fail-with-body -H"authorization: Bearer $TOKEN" \ + -XPOST -H"Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/$REPOSITORY/actions/workflows/$WORKFLOW_ID/dispatches \ + -d "$PAYLOAD" diff --git a/.github/workflows/erb-lint-core.yml b/.github/workflows/erb-lint-core.yml new file mode 100644 index 00000000000..5432af20e0c --- /dev/null +++ b/.github/workflows/erb-lint-core.yml @@ -0,0 +1,31 @@ +name: ERB lint + +on: + pull_request: + paths: + - '**/*.erb' + - '.erb_lint.yml' + - '.erb_linters/**' + +jobs: + erb-lint: + name: ERB lint + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + steps: + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - name: Set up Ruby + uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 + with: + bundler-cache: true + - name: Run ERB lint + uses: opf/action-erblint@49c54b56c60d0c50885065468cf149b61d5c2a60 # main + with: + reporter: github-pr-annotations + fail_level: any + use_bundler: true diff --git a/.github/workflows/eslint-core.yml b/.github/workflows/eslint-core.yml index 556be271976..ea7ba16eb06 100644 --- a/.github/workflows/eslint-core.yml +++ b/.github/workflows/eslint-core.yml @@ -1,4 +1,5 @@ -name: eslint +name: ESLint + on: pull_request: branches: @@ -11,24 +12,28 @@ on: jobs: eslint: - name: eslint + name: ESLint runs-on: ubuntu-latest permissions: contents: read checks: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - name: Checkout code + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 persist-credentials: false - - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 + - name: Set up Node + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: '22.22.3' package-manager-cache: false cache: npm cache-dependency-path: frontend/package-lock.json - - uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1 + - name: Run ESLint + uses: reviewdog/action-eslint@556a3fdaf8b4201d4d74d406013386aa4f7dab96 # v1 with: - reporter: github-pr-check + reporter: github-pr-annotations + fail_level: any workdir: 'frontend/' eslint_flags: 'src/' diff --git a/.github/workflows/rubocop-core.yml b/.github/workflows/rubocop-core.yml index 11e8d647c7f..8906c1a9dbb 100644 --- a/.github/workflows/rubocop-core.yml +++ b/.github/workflows/rubocop-core.yml @@ -1,4 +1,4 @@ -name: rubocop +name: RuboCop on: pull_request: @@ -7,22 +7,23 @@ on: jobs: rubocop: - name: rubocop + name: RuboCop runs-on: ubuntu-latest permissions: contents: read checks: write steps: - name: Checkout code - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - name: Set up Ruby uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1 - - name: Run Rubocop + - name: Run RuboCop uses: reviewdog/action-rubocop@b6d5e953a5fc0bf3ab65254e77730ea2174d6d6d # v2 with: - github_token: ${{ secrets.github_token }} + reporter: github-pr-annotations + fail_level: any rubocop_version: gemfile rubocop_extensions: > rubocop-capybara:gemfile @@ -32,13 +33,4 @@ jobs: rubocop-rails:gemfile rubocop-rspec:gemfile rubocop-rspec_rails:gemfile - reporter: github-pr-check only_changed: true - - name: Install erb_lint - run: gem install -N erb_lint erblint-github - - name: Run erb-lint - uses: tk0miya/action-erblint@44c5fe3552356fe8bff23f30d534aa4258aa3f7b # v1 - with: - github_token: ${{ secrets.github_token }} - reporter: github-pr-check - fail_on_error: true diff --git a/.github/workflows/yamllint-core.yml b/.github/workflows/yamllint-core.yml index 496f8006a1a..0e756d43eb3 100644 --- a/.github/workflows/yamllint-core.yml +++ b/.github/workflows/yamllint-core.yml @@ -1,4 +1,4 @@ -name: yamllint +name: Yamllint on: pull_request: @@ -9,23 +9,23 @@ on: - 'modules/*/config/locales/en.yml' - 'modules/*/config/locales/js-en.yml' -permissions: {} - jobs: - rubocop: - name: yamllint + yamllint: + name: Yamllint runs-on: ubuntu-latest + permissions: + contents: read + checks: write steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Run Yamllint uses: reviewdog/action-yamllint@f01d8a48fd8d89f89895499fca2cff09f9e9e8c0 # v1.21.0 with: - github_token: ${{ secrets.github_token }} - fail_level: error + reporter: github-pr-annotations + fail_level: any yamllint_flags: > .yamllint.yml config/locales/en.yml diff --git a/Gemfile b/Gemfile index ff9b6d8f7bf..ead46f54662 100644 --- a/Gemfile +++ b/Gemfile @@ -125,10 +125,10 @@ gem "sys-filesystem", "~> 1.5.0", require: false gem "bcrypt", "~> 3.1.22" gem "multi_json", "~> 1.20.0" -gem "oj", "~> 3.17.0" +gem "oj", "~> 3.17.3" gem "daemons" -gem "good_job", "~> 4.18.2" # update should be done manually in sync with saas-openproject version. +gem "good_job", "~> 4.19.0" # update should be done manually in sync with saas-openproject version. gem "rack-protection", "~> 3.2.0" @@ -276,7 +276,7 @@ group :test do gem "rspec-rails", "~> 8.0.4", group: :development # Retry failures within the same environment - gem "retriable", "~> 3.5.0" + gem "retriable", "~> 3.8.0" gem "rspec-retry", "~> 0.6.1" # Accessibility tests diff --git a/Gemfile.lock b/Gemfile.lock index 538e19e15ec..7e5d31f5ed3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -634,7 +634,7 @@ GEM glob (0.5.0) globalid (1.3.0) activesupport (>= 6.1) - good_job (4.18.2) + good_job (4.19.0) activejob (>= 6.1.0) activerecord (>= 6.1.0) concurrent-ruby (>= 1.3.1) @@ -755,7 +755,7 @@ GEM jmespath (1.6.2) job-iteration (1.14.0) activejob (>= 7.1) - json (2.19.7) + json (2.19.8) json-jwt (1.17.1) activesupport (>= 4.2) aes_key_wrap @@ -853,7 +853,7 @@ GEM mustermann (>= 1.0.0) net-http (0.9.1) uri (>= 0.11.1) - net-imap (0.6.4) + net-imap (0.6.4.1) date net-protocol net-ldap (0.20.0) @@ -882,7 +882,7 @@ GEM racc (~> 1.4) nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) - oj (3.17.1) + oj (3.17.3) bigdecimal (>= 3.0) ostruct (>= 0.2) okcomputer (1.19.2) @@ -1184,7 +1184,7 @@ GEM pry-rescue (1.6.0) interception (>= 0.5) pry (>= 0.12.0) - psych (5.3.1) + psych (5.4.0) date stringio public_suffix (7.0.5) @@ -1303,7 +1303,7 @@ GEM responders (3.2.0) actionpack (>= 7.0) railties (>= 7.0) - retriable (3.5.0) + retriable (3.8.0) rexml (3.4.4) rinku (2.0.6) roar (1.2.0) @@ -1630,7 +1630,7 @@ DEPENDENCIES friendly_id (~> 5.7.0) fuubar (~> 2.5.0) globalid (~> 1.3) - good_job (~> 4.18.2) + good_job (~> 4.19.0) google-apis-gmail_v1 googleauth grape (~> 3.2.0) @@ -1665,7 +1665,7 @@ DEPENDENCIES my_page! net-ldap (~> 0.20.0) nokogiri (~> 1.19.2) - oj (~> 3.17.0) + oj (~> 3.17.3) okcomputer (~> 1.19.1) omniauth! omniauth-openid-connect! @@ -1733,7 +1733,7 @@ DEPENDENCIES redis (~> 5.4.0) request_store (~> 1.7.0) responders (~> 3.2) - retriable (~> 3.5.0) + retriable (~> 3.8.0) rinku (~> 2.0.4) roar (~> 1.2.0) rouge (~> 4.7.0) @@ -1948,7 +1948,7 @@ CHECKSUMS fuubar (2.5.1) sha256=b272a7804b282661c7fab583a3764f92543cb482c365ae39c685cd218fdd4880 glob (0.5.0) sha256=6397ae620b2f71b00424ec6c880c92d5ddcf6c44e6035c0b610a59efe16418fd globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11 - good_job (4.18.2) sha256=7e557a15865fc7b7ad4ab71644cf1d4189a2a1869d3b381e5e88741c540beca6 + good_job (4.19.0) sha256=7fad3ce174d2c1b4bfde4e84056076b00ac81719b5d679900c53671a721284b9 google-apis-core (1.0.2) sha256=ba4579aaadc902d6cc7bc8db88f566ab00f5e31ea87ab41e9f9a032c470f2629 google-apis-gmail_v1 (0.51.0) sha256=cec89406ee645e71697a0eb0237e972df213d4dde86a772b05979175c48a6d11 google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7 @@ -1992,7 +1992,7 @@ CHECKSUMS iso8601 (0.13.0) sha256=298c2b15b7be5fa95a1372813d36a2257656cd8e906dfbc1f5cb409851425aa2 jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1 job-iteration (1.14.0) sha256=f154f978109acc838c0359ecde2fdd4dccc3382f95a22e03a58ac561a3615224 - json (2.19.7) sha256=fe432c8639f6efff69f9d73b518a3705d9581ab93156f981ea72806e1e5bcc3e + json (2.19.8) sha256=6354310fd76ef69b87d5bd1f38b40d730613baf90b6803d2d0a48f618d32dfaa json-jwt (1.17.1) sha256=5e1ced0f7b206b4c567efee19e6503c1426a819749132926cda579ec013d1f46 json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666 json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396 @@ -2030,7 +2030,7 @@ CHECKSUMS mustermann-grape (1.1.0) sha256=8d258a986004c8f01ce4c023c0b037c168a9ed889cf5778068ad54398fa458c5 my_page (1.0.0) net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996 - net-imap (0.6.4) sha256=9a5598c67a3022c284d98430ef1d4948e7dbdb62596f61081ea8ca933270a02b + net-imap (0.6.4.1) sha256=29f0360d75a7efd3539f16ac1957dea5c0a51ddeceb348db4553c3120914ea0d net-ldap (0.20.0) sha256=b2080b350753a9ac4930869ded8e61a1d2151c01e03b0bf07b4675cbd9ce5372 net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 @@ -2044,7 +2044,7 @@ CHECKSUMS nokogiri (1.19.3-x86_64-darwin) sha256=77f3fba57d46c53ab31e62fc6c28f705109d1bf6264356c76f132b2be5728d4d nokogiri (1.19.3-x86_64-linux-gnu) sha256=2f5078620fe12e83669b5b17311b32532a8153d02eee7ad06948b926d6080976 nokogiri (1.19.3-x86_64-linux-musl) sha256=248c906d2166eca5efb56d52fdee5f9a1f51d69a72e2b64fdac647b4ce39ea3f - oj (3.17.1) sha256=b00687f10bf68a32bfb633b87624174faf0989a5c96aff2f3f96f992717ce782 + oj (3.17.3) sha256=ebe3967b0bb7ac4f206561d0d9ac8875b9973f778600d7b61b5c355662a707ed okcomputer (1.19.2) sha256=d069aedf1e31b8ebe7e1fdf9e327dee158ea49b9fbdebebc2f1bed4690cb7a6d omniauth (1.9.2) omniauth-openid-connect (0.5.0) @@ -2175,7 +2175,7 @@ CHECKSUMS pry-byebug (3.12.0) sha256=594e094ae8a8390a7ad4c7b36ae36e13304ed02664c67417d108dc5f7213d1b7 pry-rails (0.3.11) sha256=a69e28e24a34d75d1f60bcf241192a54253f8f7ef8a62cba1e75750a9653593d pry-rescue (1.6.0) sha256=985bfd506d9866b587fd86790cf8445266a41b7f92c627fc5b21ec7d92aba6db - psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974 + psych (5.4.0) sha256=14f72d69a611af663d7d70e4a7b67d9eb1f3ae9f8d916b478961d5a0075ba5b7 public_suffix (7.0.5) sha256=1a8bb08f1bbea19228d3bed6e5ed908d1cb4f7c2726d18bd9cadf60bc676f623 puffing-billy (4.0.4) sha256=87015b0c41e0722b2171a0c5aa8130fd3f58aa1c016a1dc6dc569b2028aa846f puma (8.0.2) sha256=c8ed871dfbbe66448ea9ffd46692342d9804d4071522b52b5331b7b6e7b686fb @@ -2217,7 +2217,7 @@ CHECKSUMS representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb responders (3.2.0) sha256=89c2d6ac0ae16f6458a11524cae4a8efdceba1a3baea164d28ee9046bd3df55a - retriable (3.5.0) sha256=2e48ab1256ab2f18713f08786d2a58ec7b8a42bb5c791efa7e965f7bd2b915c0 + retriable (3.8.0) sha256=9f2f1b0207594c7817f17f671587b8ec7587387ac6cebda6c941a802bb98a8e5 rexml (3.4.4) sha256=19e0a2c3425dfbf2d4fc1189747bdb2f849b6c5e74180401b15734bc97b5d142 rinku (2.0.6) sha256=8b60670e3143f3db2b37efa262971ce3619ec23092045498ef9f077d82828d7d roar (1.2.0) sha256=8db4d1ca79c57a5fb746c16c0d5661d7c3e0de3d9553dc016a88d2dba2929d08 diff --git a/app/components/op_primer/quick_filter/boolean_component.rb b/app/components/op_primer/quick_filter/boolean_component.rb index 2de711821b4..b5149afb90e 100644 --- a/app/components/op_primer/quick_filter/boolean_component.rb +++ b/app/components/op_primer/quick_filter/boolean_component.rb @@ -30,7 +30,7 @@ module OpPrimer module QuickFilter - class BooleanComponent < SegmentedComponent + class BooleanComponent < SegmentedControlComponent def initialize(name:, query:, filter_key:, path_args:, true_label: t(:general_text_Yes), false_label: t(:general_text_No), orders: nil) super(name:, query:, filter_key:, path_args:, orders:) diff --git a/app/components/op_primer/quick_filter/segmented_component/item.rb b/app/components/op_primer/quick_filter/item.rb similarity index 83% rename from app/components/op_primer/quick_filter/segmented_component/item.rb rename to app/components/op_primer/quick_filter/item.rb index 604aa78e3ff..1cc41d343a9 100644 --- a/app/components/op_primer/quick_filter/segmented_component/item.rb +++ b/app/components/op_primer/quick_filter/item.rb @@ -26,20 +26,18 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # See COPYRIGHT and LICENSE files for more details. -#++ +# ++ module OpPrimer module QuickFilter - class SegmentedComponent < ApplicationComponent - class Item < ApplicationComponent - attr_reader :label, :value + class Item < ApplicationComponent + attr_reader :label, :value - def initialize(label:, value:) - super + def initialize(label:, value:) + super - @label = label - @value = value - end + @label = label + @value = value end end end diff --git a/app/components/op_primer/quick_filter/segmented_component.html.erb b/app/components/op_primer/quick_filter/segmented_control_component.html.erb similarity index 100% rename from app/components/op_primer/quick_filter/segmented_component.html.erb rename to app/components/op_primer/quick_filter/segmented_control_component.html.erb diff --git a/app/components/op_primer/quick_filter/segmented_component.rb b/app/components/op_primer/quick_filter/segmented_control_component.rb similarity index 95% rename from app/components/op_primer/quick_filter/segmented_component.rb rename to app/components/op_primer/quick_filter/segmented_control_component.rb index 0ead8fbb7fc..daa0fa332c9 100644 --- a/app/components/op_primer/quick_filter/segmented_component.rb +++ b/app/components/op_primer/quick_filter/segmented_control_component.rb @@ -30,11 +30,11 @@ module OpPrimer module QuickFilter - class SegmentedComponent < ApplicationComponent + class SegmentedControlComponent < ApplicationComponent include ApplicationHelper include OpTurbo::Streamable - renders_many :items, Item + renders_many :items, OpPrimer::QuickFilter::Item def initialize(name:, query:, filter_key:, path_args:, orders: nil) super diff --git a/app/components/op_primer/quick_filter/select_panel_component.html.erb b/app/components/op_primer/quick_filter/select_panel_component.html.erb new file mode 100644 index 00000000000..e0f15707a1a --- /dev/null +++ b/app/components/op_primer/quick_filter/select_panel_component.html.erb @@ -0,0 +1,72 @@ +<%#-- 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. + +++#%> + +
+ <%= render( + Primer::Alpha::SelectPanel.new( + select_variant: @select_variant, + fetch_strategy: fetch_strategy, + src: panel_src, + title: @name + ) + ) do |panel| %> + <% panel.with_show_button(scheme: :secondary, data: { test_selector: "quick-filter-select-panel-button" }) do |button| + button.with_trailing_visual_counter(count: current_values.size) if current_values.any? + button.with_trailing_action_icon(icon: :"triangle-down", color: current_values.empty? ? :muted : :default) + button_label + end %> + <% if local? %> + <% items.each do |item| %> + <% panel.with_item( + label: item.label, + active: current_values.include?(item.value.to_s), + href: @select_variant == :single ? item_href(item.value) : nil, + content_arguments: { data: { value: item.value.to_s } } + ) %> + <% end %> + <% end %> + <% if @select_variant == :multiple || current_values.any? %> + <% panel.with_footer(show_divider: true) do %> + <% if current_values.any? %> + <%= render(Primer::Beta::Button.new(scheme: :secondary, data: { action: "click->quick-filter--select-panel#clear", test_selector: "quick-filter-clear-button" })) do %> + <%= t(:button_clear) %> + <% end %> + <% end %> + <% if @select_variant == :multiple %> + <%= render(Primer::Beta::Button.new(scheme: :primary, data: { action: "click->quick-filter--select-panel#apply", test_selector: "quick-filter-apply-button" })) do %> + <%= t(:button_apply) %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> +
diff --git a/app/components/op_primer/quick_filter/select_panel_component.rb b/app/components/op_primer/quick_filter/select_panel_component.rb new file mode 100644 index 00000000000..456171b3d85 --- /dev/null +++ b/app/components/op_primer/quick_filter/select_panel_component.rb @@ -0,0 +1,148 @@ +# 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 OpPrimer + module QuickFilter + class SelectPanelComponent < ApplicationComponent + include ApplicationHelper + + renders_many :items, OpPrimer::QuickFilter::Item + + def initialize(name:, query:, filter_key:, path_args:, operator: "=", src: nil, label_method: :name, + select_variant: :multiple) + super + + @name = name + @query = query + @filter_key = filter_key + @path_args = path_args + @operator = operator + @src = src + @label_method = label_method + @select_variant = select_variant + end + + def before_render + if async? && local? + raise ArgumentError, "Use `src` for async loading or inline items for local rendering, not both." + end + + if async? && @select_variant == :single + raise ArgumentError, "Async mode is not supported with select_variant: :single." + end + + if async? && + @query.filter_for(@filter_key).method(:value_objects).owner == Queries::Filters::Base + raise ArgumentError, + "#{@query.filter_for(@filter_key).class} does not implement #value_objects. " \ + "This is required when using the async version." + end + end + + def render? + async? || local? + end + + private + + def async? + @src.present? + end + + def local? + items.any? + end + + def active_filter + @active_filter ||= @query.find_active_filter(@filter_key) + end + + def current_values + active_filter&.values&.map(&:to_s) || [] + end + + def button_label + return render(Primer::Beta::Text.new(color: :muted)) { @name } if current_values.empty? + + @name + end + + def panel_src + return unless async? + + uri = URI.parse(@src) + uri.query = panel_src_params(uri).to_query + uri.to_s + end + + def panel_src_params(uri) + Rack::Utils.parse_nested_query(uri.query.to_s).tap do |params| + # Pass other active filters (e.g. time=past) so the fragment endpoint builds + # the same query scope as the current page, not its own default + params["filters"] = other_filters.to_json if other_filters.any? + # Pass currently selected ids so the right items can be marked in the response + params["selected"] = current_values.join(",") if current_values.any? + end + end + + def fetch_strategy + async? ? :eventually_local : :local + end + + def base_url + polymorphic_path(@path_args, base_url_params) + end + + def base_url_params + {}.tap do |params| + params[:filters] = other_filters.to_json if other_filters.any? + params[:sortBy] = sort.to_json if sort.any? + end + end + + def item_href(value) + filters = other_filters + [{ @filter_key.to_s => { "operator" => @operator, "values" => [value.to_s] } }] + params = { filters: filters.to_json } + params[:sortBy] = sort.to_json if sort.any? + polymorphic_path(@path_args, params) + end + + def other_filters + @query.filters + .reject { |f| f.name == @filter_key } + .map { |f| { f.class.key.to_s => { "operator" => f.operator.to_s, "values" => f.values } } } + end + + def sort + @query.orders.map { |order| [order.name, order.direction.to_s] } + end + end + end +end diff --git a/app/components/work_packages/info_line_component.sass b/app/components/work_packages/info_line_component.sass index 365c23227f4..b1d65da4f1d 100644 --- a/app/components/work_packages/info_line_component.sass +++ b/app/components/work_packages/info_line_component.sass @@ -4,6 +4,9 @@ @include text-shortener min-width: 25px max-width: 66% + // The label has a height of 18.5px. Half pixels are resolved differently by each OS/browser combination, + // resulting in cases where the bottom of the label was cut off + min-height: 19px &--id white-space: nowrap diff --git a/app/models/queries/filters/shared/project_filter/optional.rb b/app/models/queries/filters/shared/project_filter/optional.rb index 95de9205222..9884c0b0c15 100644 --- a/app/models/queries/filters/shared/project_filter/optional.rb +++ b/app/models/queries/filters/shared/project_filter/optional.rb @@ -40,6 +40,10 @@ module Queries::Filters::Shared::ProjectFilter::Optional @allowed_values ||= ::Project.visible.pluck(:id).map { |id| [id, id.to_s] } end + def value_objects + Project.visible.where(id: values) + end + def type :list_optional end diff --git a/app/services/work_packages/activities_tab/paginator.rb b/app/services/work_packages/activities_tab/paginator.rb index f0c3c7a7497..305a1ccdfec 100644 --- a/app/services/work_packages/activities_tab/paginator.rb +++ b/app/services/work_packages/activities_tab/paginator.rb @@ -114,9 +114,7 @@ class WorkPackages::ActivitiesTab::Paginator # package's journals plus the journals written for its changesets — changesets # are journalized, so each carries a journal timestamped with its committed_on. def activities_scope(filter: self.filter) - scope = filtered_journals(filter) - scope = scope.or(changeset_journals) if include_changesets?(filter) - scope.reorder(created_at: :desc, id: :desc) + filtered_journals(filter).reorder(created_at: :desc, id: :desc) end def pagy_options @@ -160,8 +158,8 @@ class WorkPackages::ActivitiesTab::Paginator def filtered_journals(filter) case filter when Filters::ONLY_COMMENTS then apply_comments_only_filter(visible_journals) - when Filters::ONLY_CHANGES then apply_changes_only_filter(visible_journals) - else visible_journals + when Filters::ONLY_CHANGES then apply_changes_only_filter(with_changesets(visible_journals)) + else with_changesets(visible_journals) end end @@ -170,11 +168,12 @@ class WorkPackages::ActivitiesTab::Paginator journable_id: work_package.changesets.except(:order).select(:id)) end - # Most work packages have no changesets (revisions are a legacy feature), so - # the changeset leg is merged in only when one exists — keeping the common - # query scoped to the work package's own journals. - def include_changesets?(filter) - filter != Filters::ONLY_COMMENTS && work_package.changesets.exists? + # Most work packages have no changesets (revisions are a legacy feature). Merging + # the changeset leg in only when one exists keeps the common query scoped to the + # work package's own journals; always merging the empty leg pushes the planner + # onto a slower global scan. + def with_changesets(scope) + work_package.changesets.exists? ? scope.or(changeset_journals) : scope end def page_journals(page_relation) diff --git a/app/services/work_packages/activities_tab/paginator/journal_changes_filter.rb b/app/services/work_packages/activities_tab/paginator/journal_changes_filter.rb index 0c5075b04a2..e8cc333ac87 100644 --- a/app/services/work_packages/activities_tab/paginator/journal_changes_filter.rb +++ b/app/services/work_packages/activities_tab/paginator/journal_changes_filter.rb @@ -38,34 +38,63 @@ # * Cause metadata (system-triggered changes) # * Attribute/data changes (compares work_package_journals columns with immediate predecessor) # -# This heuristic compares association records with the predecessor journal to detect actual changes, -# not just the presence of snapshot records. +# Each journal's immediate predecessor is resolved once, in a CTE named `journals` that +# shadows the table and exposes `predecessor_id` / `predecessor_data_id` columns. Every +# change-detection branch then reads those columns instead of re-seeking the predecessor. +# Changeset journals carry no detectable attribute history and are always included. class WorkPackages::ActivitiesTab::Paginator::JournalChangesFilter class << self - def apply(scope) - sql = <<~SQL.squish - version = 1 - OR (cause IS NOT NULL AND cause != '{}') + # @param membership [ActiveRecord::Relation] the activity feed's journals + # (visible work package journals, optionally unioned with changeset journals) + def apply(membership) + Journal + .with(journals: Arel.sql(enriched_journals_sql(membership))) + .where(OpenProject::SqlSanitization.sanitize(changes_condition_sql)) + end + + private + + # Enrich each journal row with its immediate predecessor's id and data_id. The + # predecessor is the highest version below the current one, located through the + # (journable_type, journable_id, version) index; versions are incremental but may + # have gaps, so the seek matches on `< version` rather than `version - 1`. A LEFT + # JOIN keeps initial (version = 1) journals, whose predecessor columns stay NULL. + def enriched_journals_sql(membership) + <<~SQL.squish + SELECT curr.*, + predecessor.id AS predecessor_id, + predecessor.data_id AS predecessor_data_id + FROM (#{membership.to_sql}) curr + LEFT JOIN LATERAL ( + SELECT p.id, p.data_id + FROM journals p + WHERE p.journable_id = curr.journable_id + AND p.journable_type = curr.journable_type + AND p.version < curr.version + ORDER BY p.version DESC + LIMIT 1 + ) predecessor ON TRUE + SQL + end + + def changes_condition_sql + <<~SQL.squish + journals.journable_type = '#{Changeset.name}' + OR journals.version = 1 + OR (journals.cause IS NOT NULL AND journals.cause != '{}') OR EXISTS (#{attribute_data_changes_condition_sql}) OR EXISTS (#{attachment_changes_condition_sql}) OR EXISTS (#{custom_field_changes_condition_sql}) OR EXISTS (#{file_link_changes_condition_sql}) SQL - - scope.where(OpenProject::SqlSanitization.sanitize(sql)) end - private - def attribute_data_changes_condition_sql <<~SQL.squish SELECT 1 - FROM journals predecessor - INNER JOIN work_package_journals pred_data ON predecessor.data_id = pred_data.id - INNER JOIN work_package_journals curr_data ON journals.data_id = curr_data.id - WHERE predecessor.journable_id = journals.journable_id - AND predecessor.journable_type = journals.journable_type - AND predecessor.version = (#{max_predecessor_version_sql}) + FROM work_package_journals pred_data + INNER JOIN work_package_journals curr_data ON curr_data.id = journals.data_id + WHERE pred_data.id = journals.predecessor_data_id AND (#{data_changes_condition_sql}) SQL end @@ -98,18 +127,6 @@ class WorkPackages::ActivitiesTab::Paginator::JournalChangesFilter ) end - # Identify the immediate predecessor journal for comparison. - # NB: Journal versions are incremental but not guaranteed to be sequential. - def max_predecessor_version_sql - <<~SQL.squish - SELECT MAX(version) - FROM journals p2 - WHERE p2.journable_id = journals.journable_id - AND p2.journable_type = journals.journable_type - AND p2.version < journals.version - SQL - end - def data_changes_condition_sql data_change_columns = Journal::WorkPackageJournal.column_names - ["id"] @@ -154,12 +171,8 @@ class WorkPackages::ActivitiesTab::Paginator::JournalChangesFilter <<~SQL.squish SELECT 1 FROM #{table} curr - LEFT JOIN journals predecessor - ON predecessor.journable_id = journals.journable_id - AND predecessor.journable_type = journals.journable_type - AND predecessor.version = (#{max_predecessor_version_sql}) LEFT JOIN #{table} pred - ON pred.journal_id = predecessor.id + ON pred.journal_id = journals.predecessor_id AND #{join_conditions} WHERE curr.journal_id = journals.id AND (#{where_clause}) @@ -175,15 +188,11 @@ class WorkPackages::ActivitiesTab::Paginator::JournalChangesFilter <<~SQL.squish SELECT 1 - FROM journals predecessor - INNER JOIN #{table} pred - ON pred.journal_id = predecessor.id + FROM #{table} pred LEFT JOIN #{table} curr ON curr.journal_id = journals.id AND #{join_conditions} - WHERE predecessor.journable_id = journals.journable_id - AND predecessor.journable_type = journals.journable_type - AND predecessor.version = (#{max_predecessor_version_sql}) + WHERE pred.journal_id = journals.predecessor_id AND curr.id IS NULL SQL end diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml index d3fe58758d2..bb1f96f7cee 100644 --- a/config/locales/crowdin/af.yml +++ b/config/locales/crowdin/af.yml @@ -2107,17 +2107,14 @@ af: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ af: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: moet groter as of gelyk wees aan die begindatum. greater_than_start_date: moet groter wees as die begindatum. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is ’n ongeldige bronadres. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ af: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ af: button_login: Teken in button_move: Skuif button_move_and_follow: Skuif en volg + button_next: Next button_print: Print button_quote: Haal aan button_remove: Remove @@ -3475,6 +3476,12 @@ af: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ af: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: gister label_zen_mode: Zen mode label_role_type: Soort diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml index c9e2fcdfdc1..f672ef62423 100644 --- a/config/locales/crowdin/ar.yml +++ b/config/locales/crowdin/ar.yml @@ -2191,17 +2191,14 @@ ar: before: يجب أن يكون قبل %{date}. before_or_equal_to: يجب أن يكون قبل أو يساوي %{date}. blank: لا يمكن أن يكون فارغا. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: حزمة العمل لا يمكن أن تكون مرتبطة إلى واحدة من المهام الفرعية. circular_dependency: ان هذه العلاقة خلق تبعية دائرية. confirmation: لا يتطابق مع %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: غير موجود. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2222,36 +2219,38 @@ ar: greater_than_or_equal_to: يجب أن يكون أكبر أو يساوي%{count}. greater_than_or_equal_to_start_date: يجب أن يكون أكبر أو يساوي تاريخ البدء. greater_than_start_date: يجب أن يكون أكبر من تاريخ البدء. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: لم يتم تعيين إلى واحدة من القيم المسموح بها. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: غير صالح. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: يجب أن يكون أقل من أو يساوي %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: ليس رقماً. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: ليس عدداً صحيحاً. not_an_iso_date: 'ليس تاريخًا صالحًا. الشكل المطلوب: YYYY-MM-DD.' not_same_project: لا ينتمي إلى نفس المشروع. - datetime_must_be_in_future: must be in the future. odd: يجب أن يكون فردي. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: يجب أن يكون أصغر أو يساوي الطول الأعظم. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: قد اتخذت بالفعل. too_long: طويل جداً (الحد الأقصى من الأحرف %{count}). too_short: قصيرة جداً (الحد الأدنى هو الأحرف %{count}). @@ -2264,6 +2263,7 @@ ar: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: هو طول خاطئ (يجب أن تكون الأحرف %{count}). models: group: @@ -3008,6 +3008,7 @@ ar: button_login: تسجيل الدخول button_move: نقل button_move_and_follow: نقل ومتابعة + button_next: Next button_print: طباعة button_quote: اقتباس button_remove: إزالة @@ -3721,6 +3722,12 @@ ar: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4791,6 +4798,13 @@ ar: few: 'Time off: %{count} working days' many: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + zero: "%{count} items selected" + one: One item selected + two: "%{count} items selected" + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: الأمس label_zen_mode: Zen mode label_role_type: النّوع diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml index 67fdec3d498..282e971eaac 100644 --- a/config/locales/crowdin/az.yml +++ b/config/locales/crowdin/az.yml @@ -2107,17 +2107,14 @@ az: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ az: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ az: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ az: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Sitat button_remove: Remove @@ -3475,6 +3476,12 @@ az: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ az: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml index f391eec0147..f41e07f5763 100644 --- a/config/locales/crowdin/be.yml +++ b/config/locales/crowdin/be.yml @@ -2149,17 +2149,14 @@ be: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2180,36 +2177,38 @@ be: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2222,6 +2221,7 @@ be: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2928,6 +2928,7 @@ be: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3599,6 +3600,12 @@ be: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4659,6 +4666,11 @@ be: few: 'Time off: %{count} working days' many: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml index ee767431afb..aa6eea74dff 100644 --- a/config/locales/crowdin/bg.yml +++ b/config/locales/crowdin/bg.yml @@ -2107,17 +2107,14 @@ bg: before: трябва да бъде преди %{date}. before_or_equal_to: трябва да бъде преди или е равно на %{date}. blank: не може да бъде празно. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: трябва да бъде зададено свойството '%{property}'. cannot_delete_mapping: е необходимо. Не може да бъде изтрит. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Работния пакет не може да бъде свързан с една от неговите подзадачи. circular_dependency: Тази връзка ще доведе до циклична зависимост. confirmation: не съвпада с %{attribute}. could_not_be_copied: "%{dependency} не може да бъде (напълно) копирана." + datetime_must_be_in_future: must be in the future. does_not_exist: не съществува. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: не може да бъде осъществен достъп. error_readonly: направен е неуспешен опит за запис @@ -2138,36 +2135,38 @@ bg: greater_than_or_equal_to: трябва да бъде по-голямо от или равно на %{count}. greater_than_or_equal_to_start_date: трябва да бъде по-голяма от или равна на началната дата. greater_than_start_date: трябва да бъде по-голяма от началната дата. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: не е зададена, като позволена стойност. inclusion_nested: не е зададена на една от разрешените стойности в пътя '%{path}'. invalid: е невалиден. invalid_uri: must be a valid URI. invalid_url: невалиден URL адрес. invalid_url_scheme: 'не е поддържан протокол (разрешен: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: трябва да бъде по-малка или равна на %{count}. not_available: не е наличен поради системна конфигурация. + not_before_start_date: must not be before the start date. not_deletable: не може да бъде изтрито. not_editable: cannot be edited because it is already in effect. not_current_user: не е текущият потребител. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: е невалидна дата not_a_datetime: не е валидна дата и час. not_a_number: не е число. not_allowed: е невалиден поради липса на достъп. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: не е цяло число. not_an_iso_date: 'не е валидна дата. Изискван формат: ГГГГ-ММ-ДД.' not_same_project: не принадлежат към един и същ проект. - datetime_must_be_in_future: must be in the future. odd: трябва да бъде нечетен. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: не съответства на регулярния израз %{expression}. regex_invalid: не може да бъде валидиран със съответния регулярен израз. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: трябва да бъде по-малка от или равна на максималната дължина. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: вече съществува. too_long: е твърде дълго (максимума е %{count} знаци). too_short: е твърде кратък (минимум е %{count} знаци). @@ -2180,6 +2179,7 @@ bg: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: е грешна дължина (трябва да бъде %{count} знаци). models: group: @@ -2844,6 +2844,7 @@ bg: button_login: Влизане button_move: Премести button_move_and_follow: Преместване и последване + button_next: Next button_print: Отпечатване button_quote: Цитат button_remove: Премахване @@ -3473,6 +3474,12 @@ bg: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4523,6 +4530,9 @@ bg: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: вчера label_zen_mode: Режим Дзен label_role_type: Тип diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml index 4be4f3ee57a..c6d06ea2bc5 100644 --- a/config/locales/crowdin/ca.yml +++ b/config/locales/crowdin/ca.yml @@ -2106,17 +2106,14 @@ ca: before: ha de ser abans de %{date}. before_or_equal_to: ha de ser igual o abans de %{date}. blank: no pot estar en blanc. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: és necessari de definir la propietat '%{property}' . cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Un paquet de treball no es pot enllaçar a una de les seves subtasques. circular_dependency: Aquesta relació crearia una dependència circular. confirmation: no coincideix amb el %{attribute}. could_not_be_copied: "%{dependency} no s'ha pogut copiar (completament)." + datetime_must_be_in_future: must be in the future. does_not_exist: no existeix. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: no és possible accedir. error_readonly: es va intentar d'escriure-hi però no és modificable. @@ -2137,36 +2134,38 @@ ca: greater_than_or_equal_to: ha de ser més gran o igual a %{count}. greater_than_or_equal_to_start_date: ha de ser major o igual a la data d'inici. greater_than_start_date: ha de ser major que la data d'inici. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: no està establert a un dels valors permesos. inclusion_nested: no correspon a un dels valors permesos a la ruta '%{path}'. invalid: no és vàlid. invalid_uri: must be a valid URI. invalid_url: no és una URL vàlida. invalid_url_scheme: 'no és un protocal suportat (permès: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: ha de ser menor o igual a %{count}. not_available: no és disponible degut a la configuració del sistema. + not_before_start_date: must not be before the start date. not_deletable: no es pot eliminar. not_editable: cannot be edited because it is already in effect. not_current_user: no és l'usuari actual. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: no és una data vàlida. not_a_datetime: no és una data-i-hora vàlida. not_a_number: no és un número. not_allowed: és invàlid perquè falten permisos. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: no és un enter. not_an_iso_date: 'no és una data vàlida. Format requerit: AAAA-MM-DD.' not_same_project: no pertany al mateix projecte. - datetime_must_be_in_future: must be in the future. odd: ha de ser senar. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: no coincideix amb l'expressió regular %{expression}. regex_invalid: no s'ha pogut validar amb l'expressió regular associada. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: ha de ser inferior o igual a la longitud màxima. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: ja s'està utilitzant. too_long: és massa llarg (el màxim són %{count} caràcters). too_short: és massa curt (el mínim són %{count} caràcters). @@ -2179,6 +2178,7 @@ ca: url_not_secure_context: 'no està proveint un "Context Segur". Utilitza HTTPS o bé una adreça de retroalimentació, com un host local. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: la longitud és incorrecta (haurien de ser %{count} caràcters). models: group: @@ -2843,6 +2843,7 @@ ca: button_login: Iniciar sessió button_move: Moure button_move_and_follow: Moure i continuar + button_next: Next button_print: Imprimir button_quote: Citar button_remove: Suprimir @@ -3472,6 +3473,12 @@ ca: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4522,6 +4529,9 @@ ca: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ahir label_zen_mode: Zen mode label_role_type: Classe diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml index ec73a7a7ed8..3297bc1cae1 100644 --- a/config/locales/crowdin/ckb-IR.yml +++ b/config/locales/crowdin/ckb-IR.yml @@ -2107,17 +2107,14 @@ ckb-IR: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ ckb-IR: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ ckb-IR: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ ckb-IR: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ ckb-IR: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ ckb-IR: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml index fb4378b22f0..fea41f1dabb 100644 --- a/config/locales/crowdin/cs.yml +++ b/config/locales/crowdin/cs.yml @@ -56,12 +56,12 @@ cs: lede_html: Při přejmenování identifikátoru projektu zůstane předchozí identifikátor rezervován, aby stávající odkazy a integrace fungovaly i nadále.
Zde můžete rezervované identifikátory uvolnit, aby je mohly využít jiné projekty. col_identifier: Identifikátor col_project: Projekt - col_reserved: Reserved - not_available_in_semantic_mode: Reserved project identifiers are only available in numeric identifier mode. - filter_label: Search identifiers + col_reserved: Rezervován + not_available_in_semantic_mode: Rezervované identifikátory projektu jsou k dispozici pouze v numerickém režimu. + filter_label: Hledat identifikátory btn_release: Uvolnit released_notice: Identifikátor "%{identifier}" byl uvolněn. - identifier_not_found: The reserved identifier could not be found. It may have already been released or the project may have been deleted. Please refresh the page. + identifier_not_found: Rezervovaný identifikátor nebyl nalezen. Možná již byl uvolněn nebo projekt byl odstraněn. Obnovte prosím stránku. dialog: title: Uvolnit identifikátor heading: Uvolnit "%{identifier}"? @@ -69,8 +69,8 @@ cs: checkbox_label: Beru na vědomí, že tento úkon nelze vzít zpět. confirm_button: Uvolnit identifikátor empty_heading: Žádné rezervované identifikátory - reserved_ago: "%{time} ago" - empty_body: When a project's identifier changes, the previous one will appear here so you can release it once it's safe to do so. + reserved_ago: "%{time} nazpět" + empty_body: Když se identifikátor projektu změní, předchozí se objeví zde, abyste jej mohli uvolnit, jakmile je to bezpečné. plugins: no_results_title_text: V současné době nejsou nainstalovány žádné pluginy. no_results_content_text: Pro více informací se podívejte na stránku pro integraci a pluginy. @@ -99,14 +99,14 @@ cs: theme_warning: Změna motivu přepíše váš vlastní styl. Vzhled pak bude ztracen. Jste si jisti, že chcete pokračovat? enterprise: delete_dialog: - title: Delete enterprise token - heading: Delete this enterprise token? - confirmation: Are you sure you want to delete this Enterprise edition support token? + title: Odstranit Enterprise token + heading: Odstranit tento Enterprise token? + confirmation: Jste si jisti, že chcete odstranit tento Enterprise token? create_dialog: - title: Add Enterprise token - type_token_text: Your Enterprise token text - token_placeholder: Paste your Enterprise edition support token here - token_caption: To learn more about how to activate Enterprise edition check our [documentation](docs_url). + title: Přidat Enterprise token + type_token_text: Váš Enterprise token + token_placeholder: Zde vložte svůj Enterprise token + token_caption: Další informace o aktivaci edice Enterprise najdete v naší [dokumentaci](docs_url). add_token: Nahrát podpůrný token Enterprise Edition replace_token: Nahradit aktuální podpůrný token order: Objednat Enterprise Edici @@ -125,7 +125,7 @@ cs: in_grace_period: In grace period invalid_domain: Neplatná doména not_active: Neaktivní - trial: Trial + trial: Zkušební verze jemalloc_allocator: Jemalloc alokátor paměti journal_aggregation: caption: 'User actions on a work package (changing description, status, values, or writing comments) are grouped if performed within this period. It also controls notification and [webhook](webhook_link) delays. @@ -146,7 +146,7 @@ cs: title: No Jira hosts configured yet description: Configure a Jira host to start importing items from Jira to this OpenProject instance. configuration: - title: Jira configuration + title: Konfigurace Jira new: Nová konfigurace banner: title: Beta verze - Vyzkoušejte si ji! @@ -157,7 +157,7 @@ cs: supported_versions: '' form: fields: - name: Name + name: Název url: Jira Server/Data Center URL personal_access_token: Personal Access Token button_add: Přidat konfiguraci @@ -190,12 +190,12 @@ cs: columns: projects: Projekty last_change: Poslední změna - added: Added - label_ago: "%{amount} ago" + added: Přidáno + label_ago: před %{amount} run: - title: Import run + title: Běh importu history: Historie - remove_error: A Jira import run cannot be removed while it is running + remove_error: Běh Jira importu nemůže být odstraněn za běhu import_blocked_error: Another Jira import run is currently in progress or awaiting review. Please complete or revert it before starting a new import. project_identifier_taken: 'You are trying to import a project with an already used identifier: %{taken_identifier}. Please update the project identifier in Jira then click on Retry.' blank: @@ -203,8 +203,8 @@ cs: description: Create an import run to start importing information from this Jira instance index: description: You can import different sets of data with each import run. It is possible to undo an import run immediately after in review mode but not after finalizing. - button_import_run: Import run - button_edit_configuration: Edit configuration + button_import_run: Běh importu + button_edit_configuration: Upravit konfiguraci status: initial: Start instance_meta_fetching: Fetching meta data @@ -212,11 +212,11 @@ cs: instance_meta_done: Meta data fetched import_scope: Zvolte rozsah configuring: Select scope - projects_meta_fetching: Fetching project data - projects_meta_error: Error fetching project data - projects_meta_done: Data gathered + projects_meta_fetching: Načítání dat projektu + projects_meta_error: Chyba při načítání dat projektu + projects_meta_done: Shromážděná data importing: Probíhá - import_error: Error during import + import_error: Chyba při importu imported: Review mode reverting: Reverting revert_error: Error during revert @@ -230,10 +230,10 @@ cs: button_retry: Retry parts: projects: - one: 1 project - few: "%{count} projects" - many: "%{count} projects" - other: "%{count} projects" + one: 1 projekt + few: "%{count} projektů" + many: "%{count} projektů" + other: "%{count} projektů" issues: one: 1 issue few: "%{count} issues" @@ -241,65 +241,65 @@ cs: other: "%{count} issues" work_packages: one: 1 pracovní balíček - few: "%{count} work packages" - many: "%{count} work packages" - other: "%{count} work packages" + few: "%{count} pracovních balíčků" + many: "%{count} pracovních balíčků" + other: "%{count} pracovních balíčků" types: - one: 1 type - few: "%{count} types" - many: "%{count} types" - other: "%{count} types" + one: 1 typ + few: "%{count} typy" + many: "%{count} typy" + other: "%{count} typy" statuses: one: 1 status - few: "%{count} statuses" - many: "%{count} statuses" - other: "%{count} statuses" + few: "%{count} stavů" + many: "%{count} stavů" + other: "%{count} stavů" users: one: 1 uživatel - few: "%{count} users" - many: "%{count} users" - other: "%{count} users" + few: "%{count} uživatelů" + many: "%{count} uživatelů" + other: "%{count} uživatelů" groups: fetch: - title: Get base data + title: Získat základní data groups_and_users: - title: Groups and Users + title: Skupiny a uživatelé configuration: - title: Configure import + title: Nastavit import confirming: - title: Confirm and import + title: Potvrdit a importovat review: title: Review import sections: fetch_data: - title: Fetch instance meta data - caption_done: Completed + title: Načíst metadata instance + caption_done: Dokončeno description: Check what data is available for import in the host Jira instance. button_fetch: Check available data - label_progress: Fetching data from Jira... + label_progress: Načítání dat z Jira... groups_and_users: - title: Groups and Users + title: Skupiny a uživatelé import_scope: - title: Import scope - caption: Choose what you want to import into OpenProject - caption_done: Completed + title: Rozsah importu + caption: Vyberte, co chcete importovat do OpenProjectu + caption_done: Dokončeno label_info: Please note that this import tool is in beta and cannot import all types of data. Here is a summary of what the host Jira instance offers for import and what this tool is able to import right now. description: Select what data you want to import from the available data fetched from the host Jira instance. label_supported_data: Supported data - label_coming_soon: Coming soon (Q2 2026) + label_coming_soon: Již brzy (Q2 2026) label_coming_later: Coming later label_available_server_data: Available data on %{server_info} button_select_projects: Select projects to import - button_continue: Continue + button_continue: Pokračovat label_import: Select which projects you would like to import. - button_select: Select projects - label_selected_data: Selected data for import - label_progress: Fetching data from Jira... + button_select: Vybrat projekty + label_selected_data: Vybraná data pro import + label_progress: Načítání dat z Jira... elements: - relations: Relations between issues + relations: Vztahy mezi issues project_ids: Project identifiers - issue_ids: Issue identifiers - sprints: Sprint assignments + issue_ids: Identifikátory issues + sprints: Přiřazení sprintu workflows: Project-level workflows schemes: Schémata permissions: Permissions @@ -311,27 +311,27 @@ cs: confirm_import: title: Import dat caption: Review your import settings and start the import - caption_done: Completed + caption_done: Dokončeno label_available_data: Data k importu - label_users_import_explanation: Users that are involved in selected projects (group memberships included) - button_start: Start import - description: You are about to start an import run with the following settings. - label_progress: Import in progress... - label_import_data: Currently importing + label_users_import_explanation: Uživatelé, kteří jsou zapojeni do vybraných projektů (včetně členství ve skupinách) + button_start: Spustit import + description: Chystáte se spustit import s následujícím. nastavením. + label_progress: Probíhá import... + label_import_data: Momentálně importováno import_result: - title: Import run results - caption: Review import run or revert import + title: Výsledky importu + caption: Zkontrolovat spuštění importu nebo revertovat import info: Import proběhl úspěšně. label_results: Importováno - label_revert: Revert import - button_revert: Revert import + label_revert: Revert importu + button_revert: Revertovat import button_done: Schválit import preview_description: The imported data is currently in review mode. Click "Approve import" to make the import permanent or "Revert import" to undo all changes made in this import run. label_finalize_import: Approve import label_finalizing: Approving import... label_finalizing_done: Import approved. - label_revert_progress: Reverting import... - label_reverted: Import reverted. + label_revert_progress: Revertování importu... + label_reverted: Import byl revertován. select_dialog: filter_projects: Filtrovat podle textu import_dialog: @@ -342,18 +342,18 @@ cs: ' confirm: I understand and have a backup revert_dialog: - title: Permanently revert this import? + title: Trvale revertovat tento import? description: This will delete all imported objects (including whole projects). - confirm: I understand that this reversion will delete data permanently + confirm: Chápu, že tento revert trvale odstraní data finalize_dialog: title: Approve this import? description: Once approved, this import can no longer be reverted. All imported data will become permanent. confirm: Beru na vědomí, že tento úkon nelze vzít zpět confirm_button: Rozumím select_projects: - title: Select projects + title: Výběr projektů user: - unknown_name: Unknown + unknown_name: Neznámý mcp_configurations: index: description: The model context protocol allows AI agents to provide its users with tools and resources exposed by this OpenProject instance. This feature is still in beta. @@ -440,7 +440,7 @@ cs: settings: new_project: project_creation: Project creation - notification_text_default: "

Hello,

A new project has been created: projectValue:name

Thank you

\n" + notification_text_default: "

Dobrý den,

Byl vytvořen nový projekt: projectValue:name

Děkujeme

\n" work_packages_identifier: page_header: description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID. @@ -497,10 +497,10 @@ cs: statuses_removal_dialog: title: Remove statuses heading: - one: Remove 1 status? - few: Remove %{count} statuses? - many: Remove %{count} statuses? - other: Remove %{count} statuses? + one: Odstranit 1 stav? + few: Odstranit %{count} stavy? + many: Odstranit %{count} stavů? + other: Odstranit %{count} stavů? description: Removing these statuses will make them unavailable to this type and delete existing workflows. Are you sure you want to proceed? confirm: Odstranit leave_confirmation: @@ -716,7 +716,7 @@ cs: all: Allows the user to assign multiple values to this custom field. project: Allows the user to assign multiple values to this attribute. searchable: - all: Include the field values when using the global search functionality. + all: Zahrnout hodnoty polí při použití globální funkce vyhledávání. project: Check to make this attribute available as a filter in project lists. editable: all: Allow the field to be editable by users themselves. @@ -754,36 +754,36 @@ cs: confirmation_live_message_checked: The button to proceed is now active. confirmation_live_message_unchecked: The button to proceed is now inactive. You need to tick the checkbox to continue. departments: - edit: Edit department - add_user: Add user - add_department: Add department + edit: Upravit oddělení + add_user: Přidat uživatele + add_department: Přidat oddělení blankslate: - heading: Your organization has no departments - description: 'Start by adding departments or users to the organization. Each department can be used to create a hierarchy below it, to navigate and create sub-department inside a hierarchy click on the created item. + heading: Vaše organizace nemá žádná oddělení + description: 'Začněte přidáním oddělení nebo uživatelů do organizace. Každé oddělení lze použít k vytvoření hierarchie pod ním, pro navigaci a vytvoření pododdělení uvnitř hierarchie klikněte na vytvořenou položku. ' - add_button: Add + add_button: Přidat detail_blankslate: - heading: This department doesn’t have any hierarchy level below + heading: Toto oddělení nemá žádnou úroveň hierarchie pod ním description: Add departments or users to create sub-items inside another one. - add_button: Add + add_button: Přidat add_department_form: - name_label: Department name - name_placeholder: Enter department name + name_label: Název oddělení + name_placeholder: Zadejte název oddělení move_user_dialog: - title: User already in a department - heading: Move user to this department? - description: "%{user} is currently a member of %{from_department}. Moving them will remove them from that department." - confirm: Move user + title: Uživatel je již v oddělení + heading: Přesunout uživatele do tohoto oddělení? + description: "%{user} je v současné době členem %{from_department}. Jejich přesunutím dojde k jejich odstranění z tohoto oddělení." + confirm: Přesunout uživatele context_menu: - add_sub_department: Add sub-department - add_user: Add user + add_sub_department: Přidat dílčí oddělení + add_user: Přidat uživatele flash: - user_added: User was successfully added to the department. - user_removed: User was successfully removed from the department. - department_created: Department was successfully created. + user_added: Uživatel byl úspěšně přidán do oddělení. + user_removed: Uživatel byl úspěšně odstraněn z oddělení. + department_created: Oddělení bylo úspěšně vytvořeno. errors: - move_user_failed: Failed to move user between departments. + move_user_failed: Přesun uživatele mezi odděleními se nezdařil. pagination: label: Stránkování prev: Předchozí @@ -819,9 +819,9 @@ cs: respond_to?: neimplementuje požadovanou metodu. rules: copy_workflow_from: - workflow_missing: has no own workflow. + workflow_missing: nemá vlastní pracovní postup. custom_field: - format_not_supported: format '%{field_format}' is unsupported. + format_not_supported: formát '%{field_format}' není podporován. item: root_item: nemůže být kořenová položka. not_persisted: musí být již existující položka. @@ -857,13 +857,13 @@ cs: wiki_pages: Wiki groups: edit: - synchronized_groups: Synchronized groups + synchronized_groups: Synchronizované skupiny index: description: Seskupováním uživatelů je můžete přidat jako členy do stejných projektů nebo jim přiřadit stejné globální role. table_component: blank_slate: description: You can define named groups of users with specific permissions. - title: No groups set up yet + title: Zatím nebyly vytvořeny žádné skupiny user_count: User count users: no_results_title_text: Momentálně nejsou žádní uživatelé součástí této skupiny. @@ -882,12 +882,12 @@ cs: index: search: label: Filtr názvů portfolia - placeholder: Search portfolios + placeholder: Hledat portfolia sub_items_html: - one: "1 sub-item" - few: "%{count} sub-items" - many: "%{count} sub-items" - other: "%{count} sub-items" + one: "1 dílčí položka" + few: "%{count} dílčích položek" + many: "%{count} dílčích položek" + other: "%{count} dílčích položek" lists: active: Aktivní portfolia my: Moje portfolia @@ -936,7 +936,7 @@ cs: text: Tato akce neodstraní žádný projekt, který seznam obsahuje. Opravdu chcete tento seznam projektů smazat? settings: header_details: Základní údaje - header_identifier: Identifier + header_identifier: Identifikátor header_status: Stav header_relations: Vztahy projektu button_update_details: Aktualizovat podrobnosti @@ -954,14 +954,14 @@ cs: private_confirmation: checkbox: Chápu, že tím se dříve veřejný obsah stane soukromým. title: Nastavit tento projekt jako soukromý? - description: 'The project will only be visible to project members depending on their role and associated permissions. Sub-projects are not affected and have their own settings. + description: 'Projekt bude viditelný pouze pro členy projektu v závislosti na jejich úloze a souvisejících povoleních. Dílčí projekty nejsou ovlivněny a mají vlastní nastavení. ' change_identifier: Změnit identifikátor change_identifier_dialog_title: Změnit identifikátor projektu change_identifier_format_hint_semantic: Pouze velká písmena (A-Z), číslice nebo podtržítka. Maximálně 10 znaků. Musí začínat písmenem. change_identifier_format_hint_legacy: Pouze malá písmena (a-z), číslice, pomlčky nebo podtržítka. - change_identifier_warning: 'This will permanently change identifiers and URLs of all work packages in this project. The previous identifiers and URLs will nevertheless continue to work. + change_identifier_warning: 'Tímto se trvale změní identifikátory a adresy URL všech pracovních balíčků v tomto projektu. Předchozí identifikátory a adresy URL budou nicméně nadále správně přesměrovány. ' subitems: @@ -1877,7 +1877,7 @@ cs: identifier: Identifikátor latest_activity_at: Poslední aktivita parent: Podprojekt - project_creation_wizard_enabled: Project initiation request + project_creation_wizard_enabled: Zahajovatel projektu public_value: title: Viditelnost true: veřejný @@ -2109,7 +2109,7 @@ cs: relatable: Relatable to remaining_hours: Zbývající práce remaining_time: Zbývající práce - sequence_number: Sequence number + sequence_number: Sekvenční číslo shared_with_users: Sdíleno s schedule_manually: Manuální plánování spent_hours: Strávený čas @@ -2120,13 +2120,13 @@ cs: version: Verze watcher: Sledující ordered_persisted_query_entity: - persisted_query: Persisted query - entity: Entity - position: Position + persisted_query: Trvalý dotaz + entity: Entita + position: Pozice persisted_query: - name: Name - views: Views - filters: Filters + name: Název + views: Pohledy + filters: Filtry orders: Orders selects: Selects persisted_view: @@ -2151,17 +2151,14 @@ cs: before: musí být před %{date}. before_or_equal_to: musí být před nebo rovno %{date}. blank: nemůže být prázdné. - not_before_start_date: nesmí být před datem zahájení. - overlapping_range: se překrývá se stávajícím rozsahem nepracovního dne. blank_nested: musí mít nastavenou vlastnost '%{property}'. cannot_delete_mapping: je povinné. Nelze odstranit. - is_for_all_cannot_modify: je pro všechny projekty, a proto je nelze měnit. cant_link_a_work_package_with_a_descendant: Pracovní balíček nemůže být propojen s jedním z jeho podúkolů. circular_dependency: Tento vztah by vytvořil kruhovou závislost. confirmation: neshoduje se s %{attribute}. could_not_be_copied: "%{dependency} nemůže být (zcela) zkopírován." + datetime_must_be_in_future: musí být v budoucnosti. does_not_exist: neexistuje. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: není přístupný. error_readonly: se pokusil být napsán, ale není zapisovatelný. @@ -2182,36 +2179,38 @@ cs: greater_than_or_equal_to: musí být větší než nebo rovno %{count}. greater_than_or_equal_to_start_date: musí být větší nebo rovno počátečnímu datu. greater_than_start_date: musí být větší než počáteční datum. + hexcode_invalid: není platným 6-místným hexadecimálním barevným kódem. inclusion: není nastavena na jednu z povolených hodnot. inclusion_nested: není nastavena na jednu z povolených hodnot na cestě '%{path}'. invalid: je neplatné. invalid_uri: must be a valid URI. invalid_url: není platná adresa URL. invalid_url_scheme: 'není podporovaný protokol (povoleny: %{allowed_schemes}).' + is_for_all_cannot_modify: je pro všechny projekty, a proto je nelze měnit. less_than_or_equal_to: musí být menší než nebo rovno %{count}. not_available: není k dispozici kvůli konfiguraci systému. + not_before_start_date: nesmí být před datem zahájení. not_deletable: nelze odstranit not_editable: nelze upravit, protože již platí. not_current_user: není aktuální uživatel. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: nenalezeno. not_a_date: není platné datum. not_a_datetime: není platný čas. not_a_number: není číslo. not_allowed: je neplatný z důvodu chybějících oprávnění. - host_not_allowed: is not an allowed host. not_json: nelze přečíst jako JSON. not_json_object: není platným JSON objektem. not_an_integer: není celé číslo. not_an_iso_date: 'není platné datum. Požadovaný formát: RRRR-MM-DD.' not_same_project: nepatří do stejného projektu. - datetime_must_be_in_future: musí být v budoucnosti. odd: musí být liché. + overlapping_range: se překrývá se stávajícím rozsahem nepracovního dne. regex_match_failed: neodpovídá regulárnímu výrazu %{expression}. regex_invalid: nelze ověřit s přidruženým regulárním výrazem. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: není platným 6-místným hexadecimálním barevným kódem. smaller_than_or_equal_to_max_length: musí být menší než nebo rovno maximální délce. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: je již použito. too_long: je příliš dlouhý (maximum je %{count} znaků). too_short: je příliš krátký (minimum je %{count} znaků). @@ -2224,6 +2223,7 @@ cs: url_not_secure_context: 'neposkytuje "bezpečný kontext". Buď použijte HTTPS nebo adresu pro smyčku, jako je localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: má chybnou délku (měla by být %{count} znaků). models: group: @@ -2528,7 +2528,7 @@ cs: attribute_unknown_name: 'Použitý neplatný atribut pracovního balíčku: %{attribute}' duplicate_group: Název skupiny '%{group}' je použit více než jednou. Názvy skupin musí být jedinečné. query_invalid: 'Vložený dotaz ''%{group}'' je neplatný: %{details}' - group_without_name: Group name can't be blank. + group_without_name: Název skupiny nesmí být prázdný. patterns: invalid_tokens: One or more attributes inside the field are not valid. Please, fix the attributes before saving. user: @@ -2620,7 +2620,7 @@ cs: other: Priorities meeting_participant: Účastník schůzky member: Člen - message: Message + message: Zpráva news: Novinky notification: one: Oznámení @@ -2646,10 +2646,10 @@ cs: many: Role other: Role scim_client: - one: SCIM client - few: SCIM clients - many: SCIM clients - other: SCIM clients + one: Klient SCIM + few: Klienti SCIM + many: Klienti SCIM + other: Klienti SCIM jira: one: Jira few: Jira @@ -2667,10 +2667,10 @@ cs: many: RSS tokenů other: RSS tokenů type: - one: Type - few: Types - many: Types - other: Types + one: Typ + few: Typy + many: Typy + other: Typy user: Uživatel version: Verze workflow: Pracovní postup @@ -2696,7 +2696,7 @@ cs: unsupported_storage_type: není podporovaným typem úložiště. storage_error: Došlo k chybě při připojení k úložišti. invalid_input: Vstup je neplatný. - invalid_child_for_parent: is not allowed as a parent for this view type. + invalid_child_for_parent: není pro tento typ zobrazení povolen jako nadřazený. activity: item: created_by_on: vytvořil %{user} dne %{datetime} @@ -2743,9 +2743,9 @@ cs: changed_date: změněno z %{from} na %{to} deactivated: Deaktivováno deleted_project_phase: Smazaná fáze projektu - phase_and_both_gates: "%{phase_message}. %{start_gate_message}, and %{finish_gate_message}" + phase_and_both_gates: "%{phase_message}. %{start_gate_message}, a %{finish_gate_message}" phase_and_one_gate: "%{phase_message}. %{gate_message}" - removed_date: date deleted %{date} + removed_date: datum smazání %{date} attributes: active: Aktivní assigned_to: Řešitel @@ -2811,8 +2811,8 @@ cs: priority: Priorita project: Projekt project_ids: ID Projektu - project_phase: Project phase - project_phase_definition: Project phase + project_phase: Fáze projektu + project_phase_definition: Fáze projektu reason: Důvod responsible: Odpovědný required: Požadováno @@ -2930,6 +2930,7 @@ cs: button_login: Přihlásit se button_move: Přesunout button_move_and_follow: Přesunout a pokračovat + button_next: Next button_print: Tisk button_quote: Citovat button_remove: Odstranit @@ -2974,7 +2975,7 @@ cs: button_revoke_all: Zrušit vše button_revoke_only: Zrušit pouze %{shared_role_name} button_publish: Zveřejnit - button_unpublish: Nastavit jako soukromé + button_unpublish: Nastavit jako soukromý consent: checkbox_label: Zaznamenal(a) jsem a souhlasím s výše uvedeným. failure_message: Souhlas se nezdařil, nelze pokračovat. @@ -3085,9 +3086,9 @@ cs: distance_in_words: about_x_hours: one: přibližně 1 hodinu - few: přibližně %{count} hodin - many: přibližně %{count} hodin - other: přibližně %{count} hodin + few: přibližně %{count} hodinami + many: přibližně %{count} hodinami + other: přibližně %{count} hodinami about_x_months: one: přibližně 1 měsíc few: přibližně %{count} měsíce @@ -3222,7 +3223,7 @@ cs: board_view: Advanced Boards calculated_values: Calculated values capture_external_links: Capture External Links - internal_comments: Internal Comments + internal_comments: Interní komentáře custom_actions: Custom Actions custom_field_hierarchies: Hierarchie customize_life_cycle: Přizpůsobit životní cyklus @@ -3253,14 +3254,14 @@ cs: plans_title: Podnikové plány title: Doplňky podnikových plánů plan_title: Enterprise %{plan} add-on - plan_name: "%{plan} enterprise plan" - trial_text: This feature is included in your active Enterprise trial. + plan_name: Enterprise plán %{plan} + trial_text: Tato funkce je zahrnuta v aktivní zkušební verzi Enterprise. plan_text_html: K dispozici od plánu %{plan_name}. unlimited: Bez omezení - already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan. + already_have_token: 'Už máte token? Přidejte jej pomocí níže uvedeného tlačítka a přejděte na rezervovaný plán Enterprise. ' - hide_banner: Hide this banner + hide_banner: Skrýt tento banner homescreen_description: 'Plán Enterprise rozšiřuje komunitní edici OpenProject o další [Enterprise doplňky](enterprise_url) a profesionální podporu, což je ideální pro organizace provozující OpenProject v kritickém prostředí. ' @@ -3320,10 +3321,10 @@ cs: title: Jednotné přihlášení (SSO) pro úložiště Nextcloud description: Enable seamless and secure authentication for your Nextcloud storage with Single Sign-On. Simplify access management and enhance user convenience. scim_api: - title: SCIM clients + title: Klienti SCIM description: Automatizujte správu uživatelů v OpenProject pomocí integrace externích služeb identit, jako je Microsoft Entra nebo Keycloak, prostřednictvím našeho SCIM Server API. K dispozici od plánu Enterprise. sso_auth_providers: - title: Single Sign-On (SSO) + title: Jednotné přihlášení (SSO) description: Enable users to log in via external SSO providers using SAML or OpenID Connect for seamless access and integration with existing identity systems. virus_scanning: description: Zajistěte, aby nahrané soubory v OpenProjectu byly před zpřístupněním ostatním uživatelům zkontrolovány na přítomnost virů. @@ -3348,15 +3349,15 @@ cs: few: "%{count} days left of %{trial_plan} trial token" many: "%{count} days left of %{trial_plan} trial token" other: "%{count} days left of %{trial_plan} trial token" - description_html: You have access to all %{trial_plan} features. + description_html: Máte přístup ke všem funkcím %{trial_plan}. trial: - not_found: You have requested a trial token, but that request is no longer available. Please try again. - wait_for_confirmation: We sent you an email to confirm your address in order to retrieve a trial token. - already_retrieved: 'Your trial enterprise token was already retrieved. Please check your emails for the token being attached. Please reach out to our support team if you need a new one. + not_found: Požádali jste o zkušební token, ale tento požadavek již není k dispozici. Zkuste to prosím znovu. + wait_for_confirmation: Poslali jsme vám e-mail s žádostí o potvrzení vaší adresy, abyste mohli získat zkušební token. + already_retrieved: 'Váš zkušební Enterprise token byl již načten. Zkontrolujte prosím své e-maily, zda je token přiložen. Pokud potřebujete nový, obraťte se na náš tým podpory. ' - successfully_saved: Your trial enterprise token has been successfully retrieved. - token_sent: Trial token requested + successfully_saved: Váš zkušební Enterprise token byl úspěšně načten. + token_sent: Enterprise token vyžádán request_again: Znovu požádat resend_action: Znovu odeslat potvrzovací e‑mail welcome_title: Stručný přehled funkcí @@ -3364,7 +3365,7 @@ cs: confirmation_info: 'We sent you an email on %{date} to %{email} with all the information to start the free trial of OpenProject Enterprise. Please check your inbox and click the confirmation link provided to start your 14-day free trial. ' - confirmation_subline: 'Please, check your inbox and follow the steps to start your 14-day free trial. + confirmation_subline: 'Zkontrolujte prosím svou doručenou poštu a postupujte podle kroků, abyste zahájili 14-denní bezplatnou zkušební verzi. ' domain_caption: The token will be valid for your currently configured host name. @@ -3601,6 +3602,12 @@ cs: selected: Vybráno include_sub_items: Zahrnout dílčí položky no_results_text: Žádné výsledky + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Zap. label_off: Vyp. @@ -3665,7 +3672,7 @@ cs: line_0: Project-based work package identifiers for clearer references. line_1: Jira Migrator support for Jira identifiers, due dates, and more. line_2: Option to exclude work package types from Backlogs. - line_3: Redesigned sprint views. + line_3: Přepracované zobrazení sprintu. line_4: Improved work package linking across Documents and text editors. line_5: More flexible meeting schedules and reduced email notification noise. line_6: Nested groups for organizational structures and inherited permissions. @@ -3702,7 +3709,7 @@ cs: header: změny od %{author} field_changed: "%{field} změněno z %{old_value} na %{new_value}" field_set: "%{field} nastaveno na %{value}" - field_removed: "%{field} removed" + field_removed: "%{field} odstraněno" field_updated: "%{field} aktualizováno" deleted_with_diff: "%{field} deleted (%{link})" changed_with_diff: "%{field} changed (%{link})" @@ -3734,7 +3741,7 @@ cs: progress_calculation_adjusted: Progress calculation automatically adjusted with version update. scheduling_mode_adjusted: Scheduling mode automatically adjusted with version update. totals_removed_from_childless_work_packages: Work and progress totals automatically removed for non-parent work packages with version update. This is a maintenance task and can be safely ignored. - sprint_migration: Version '%{version_name}' has been copied as a sprint. + sprint_migration: Verze '%{version_name}' byla zkopírována jako sprint. total_percent_complete_mode_changed_to_work_weighted_average: Podřízené pracovní balíčky bez položky Práce jsou ignorovány. total_percent_complete_mode_changed_to_simple_average: Pracovní hodnoty podřízených pracovních balíčků jsou ignorovány. links: @@ -3837,8 +3844,8 @@ cs: title: Receive email reminders on these days submit_button: Update reminder days pause_reminders: - title: Pause email notifications - enabled: Temporarily pause daily email reminders + title: Pozastavit e-mailová oznámení + enabled: Dočasně pozastavit e-mailová oznámení date_range: Pause period email_alerts: title: Email alerts for other items that are not work packages @@ -3847,7 +3854,7 @@ cs: news_commented: Comment on a news item document_added: Document added forum_messages: Forum message posted - wiki_page_added: Wiki page added + wiki_page_added: Přidána wiki stránka wiki_page_updated: Wiki stránka aktualizována membership_added: Membership added membership_updated: Členství bylo aktualizováno @@ -3871,14 +3878,14 @@ cs: overdue: Overdue times: same_day: On the same day - one_day_before: 1 day before - three_days_before: 3 days before - seven_days_before: 7 days before - one_day_after: 1 day after - three_days_after: 3 days after - seven_days_after: 7 days after + one_day_before: 1 den předem + three_days_before: 3 dny předem + seven_days_before: 7 dní předem + one_day_after: 1 den po + three_days_after: 3 dny po + seven_days_after: 7 dní po non_participating: - title: Non-participating + title: Neúčastnící se description: Additional notifications for activities in all projects. submit_button: Update preferences work_package_created: New work packages @@ -3947,7 +3954,7 @@ cs: label_age: Věk label_ago: dnů před label_all: vše - label_all_uppercase: All + label_all_uppercase: Vše label_all_time: celkový čas label_all_words: Všechna slova label_all_open_wps: Všechny otevřené @@ -3965,7 +3972,7 @@ cs: label_ical_access_key_generation_hint: Automaticky vygenerováno při odebírání kalendáře. label_ical_access_key_latest: poslední label_ical_access_key_revoke: Revoke - label_integrations: Integrations + label_integrations: Integrace label_add_column: Přidat sloupec label_applied_status: Přiřazený stav label_archive_project: Archivovat projekt @@ -4049,7 +4056,7 @@ cs: label_commits_per_month: Commitů za měsíc label_confirmation: Potvrzení label_contains: obsahuje - label_starts_with: starts with + label_starts_with: začíná na label_content: Obsah label_color_plural: Barvy label_copied: zkopírováno @@ -4057,8 +4064,8 @@ cs: label_copy_source: Zdroj label_copy_target: Cíl label_copy_workflow_from: Kopírovat pracovní postup z - label_copy_workflow_from_type: Copy to another type - label_copy_workflow_from_role: Copy to other roles + label_copy_workflow_from_type: Kopírovat do jiného typu + label_copy_workflow_from_role: Kopírovat do dalších rolí label_copy_project: Kopírovat projekt label_core_version: Verze jádra label_core_build: Build jádra @@ -4183,7 +4190,7 @@ cs: label_home: Domů label_subject_or_id: Předmět nebo ID label_calendar_subscriptions: Odběr kalendáře - label_identifier: Identifiers + label_identifier: Identifikátory label_project_identifier: Identifikátor projektu label_in: v label_in_less_than: za méně než @@ -4216,11 +4223,11 @@ cs: label_journal_diff: Popis porovnání label_language: Jazyk label_languages: Jazyky - label_export_plural: Exports + label_export_plural: Exporty label_external_links: Externí odkazy label_locale: Jazyk a region label_jump_to_a_project: Přejít na projekt... - label_jira_import: Jira Migrator + label_jira_import: Jira Migrátor label_keyword_plural: Klíčová slova label_language_based: Na základě jazyka uživatele label_last_activity: Poslední aktivita @@ -4249,16 +4256,16 @@ cs: label_custom_export_logo: Vlastní logo exportu label_custom_export_cover: Vlastní exportní obal pozadí label_custom_export_footer: Custom export footer image - label_custom_export_font_regular: Regular - label_custom_export_font_bold: Bold + label_custom_export_font_regular: Běžný + label_custom_export_font_bold: Tučný label_custom_export_font_italic: Kurzíva - label_custom_export_font_bold_italic: Bold Italic + label_custom_export_font_bold_italic: Tučná kurzíva label_custom_export_cover_overlay: Překrytí obalu vlastního exportu label_custom_export_cover_text_color: Barva textu label_custom_pdf_export_settings: Vlastní nastavení exportu PDF label_custom_favicon: Vlastní favicon label_custom_touch_icon: Vlastní ikona dotyku - label_departments: Organization + label_departments: Organizace label_departments_description_html: 'Define your company’s structure by creating departments and sub-departments in a hierarchical way. This allows you to reflect reporting lines and maintain a clear, structured overview of your organization within OpenProject. You can also import an existing organization structure through [LDAP group synchronisation](ldap_docs_article). ' @@ -4268,7 +4275,7 @@ cs: label_manage: Spravovat label_manage_groups: Spravovat skupiny label_managed_repositories_vendor: Spravováno %{vendor} repozitářů - label_mathematical_operators: Mathematical operators + label_mathematical_operators: Matematické operátory label_max_size: Maximální velikost label_me: já label_member_new: Nový člen @@ -4329,7 +4336,7 @@ cs: label_no_due_date: žádné datum dokončení label_no_start_date: žádné datum začátku label_no_parent_page: Žádná nadřazená stránka - label_no_parent_group: "(No parent group)" + label_no_parent_group: "(Žádná nadřazená skupina)" label_notification_center_plural: Notifikace label_nothing_display: Nic k zobrazení label_nobody: nikdo @@ -4391,7 +4398,7 @@ cs: label_preview_not_available: Náhled není k dispozici label_previous: Předchozí label_previous_week: Předchozí týden - label_previous_year: Previous year + label_previous_year: Předchozí rok label_principal_invite_via_email: " nebo pozvat nové uživatele e-mailem" label_principal_search: Přidat existující uživatele nebo skupiny label_privacy_policy: Zásady ochrany soukromí a bezpečnosti údajů @@ -4405,7 +4412,7 @@ cs: label_project_attribute_manage_link: Správa atributů produktu label_project_count: Celkový počet projektů label_project_copy_notifications: Během kopie projektu odeslat oznámení e-mailem - label_project_initiation_export_pdf: Export PDF for %{project_creation_name} + label_project_initiation_export_pdf: Export PDF pro %{project_creation_name} label_project_latest: Nejnovější projekty label_project_default_type: Povolit prázdný typ label_project_hierarchy: Hierarchie projektu @@ -4413,14 +4420,14 @@ cs: label_project_new: Nový projekt label_project_plural: Projekty label_project_list_plural: Seznamy projektů - label_reserved_identifiers: Reserved project identifiers + label_reserved_identifiers: Rezervované identifikátory projektů label_project_life_cycle: Životní cyklus projektu label_project_attributes_plural: Atributy projektu label_project_custom_field_plural: Atributy projektu label_project_settings: Nastavení projektu label_project_attributes_settings: '' label_project_storage_plural: Úložiště souborů - label_project_storage_project_folder: 'File storages: Project folders' + label_project_storage_project_folder: 'Úložiště souborů: Složky projektů' label_projects_disk_usage_information: "%{count} projekty využívající diskový prostor %{used_disk_space}" label_project_view_all: Zobrazit všechny projekty - seznam label_project_show_details: Zobrazit detail projektu @@ -4454,7 +4461,7 @@ cs: label_report: Hlášení label_report_bug: Nahlásit chybu label_report_plural: Hlášení - label_reported_work_packages: Nahlášené pracovní balíčky + label_reported_work_packages: Hlášené pracovní balíčky label_reporting: Hlášení label_reporting_plural: Hlášení label_repository: Repozitář @@ -4477,7 +4484,7 @@ cs: label_role_new: Nová role label_role_grantable: Udělitelná role label_role_plural: Role - label_role_missing_permissions: "%{role} (missing required permissions)" + label_role_missing_permissions: "%{role} (chybí požadovaná oprávnění)" label_role_search: Přiřadit roli novým členům label_scm: SCM label_scroll_left: Rolovat vlevo @@ -4580,7 +4587,7 @@ cs: label_what_is_this: Co to je? label_week: Týden label_widget: Widget - label_widget_new: New widget + label_widget_new: Nový widget label_wiki_content_added: Přidána stránka wiki label_wiki_content_updated: Wiki stránka aktualizována label_wiki_toc: Obsah @@ -4627,9 +4634,9 @@ cs: other: "%{count} komentáře" zero: žádné komentáře label_x_items: - one: 1 item - other: "%{count} items" - zero: no items + one: 1 položka + other: "%{count} položek" + zero: žádné položky label_x_open_work_packages_abbr: one: 1 otevřený other: "%{count} otevřených" @@ -4647,20 +4654,25 @@ cs: other: "%{count} souborů" zero: žádné soubory label_x_days: - one: 1 day - few: "%{count} days" - many: "%{count} days" - other: "%{count} days" + one: 1 den + few: "%{count} dny" + many: "%{count} dní" + other: "%{count} dní" label_x_working_days: - one: 1 working day - few: "%{count} working days" - many: "%{count} working days" - other: "%{count} working days" + one: 1 pracovní den + few: "%{count} pracovních dnů" + many: "%{count} pracovních dnů" + other: "%{count} pracovních dnů" label_x_working_days_time_off: - one: 'Time off: 1 working day' - few: 'Time off: %{count} working days' - many: 'Time off: %{count} working days' - other: 'Time off: %{count} working days' + one: 'Volno: 1 pracovní den' + few: 'Volno: %{count} pracovních dní' + many: 'Volno: %{count} pracovních dní' + other: 'Volno: %{count} pracovních dní' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: včera label_zen_mode: Zen mód label_role_type: Typ @@ -4668,7 +4680,7 @@ cs: label_global_role: Globální role label_not_changeable: "(neměnitelné)" label_global: Globální - label_seeded_from_env_warning: This record has been created through a setting environment variable. It is not editable through UI. + label_seeded_from_env_warning: Tento záznam byl vytvořen prostřednictvím proměnné prostředí. Nelze jej upravovat prostřednictvím uživatelského rozhraní. label_schedule_and_availability: Rozvrh a dostupnost label_working_hours: Pracovní rozvrh label_non_working_days: Kalendář dostupnosti @@ -4678,8 +4690,8 @@ cs: button_edit_non_working_time: Upravit volno label_continued_from_previous_year: pokračování z předchozího roku label_continues_into_next_year: pokračování do dalšího roku - label_end_date: Finish date - label_working_days: Working days + label_end_date: Datum ukončení + label_working_days: Pracovní dny label_non_working_times_with_count: Volna v roce %{year} (%{count}) label_non_working_times_summary: Souhrn roku %{year} label_total_user_non_working_times: Osobní nepracovní dny @@ -4687,7 +4699,7 @@ cs: label_total_days_off: Celkový počet dnů volna macro_execution_error: Chyba při provádění makra %{macro_name} macro_unavailable: Makro %{macro_name} nelze zobrazit. - macro_unknown: Unknown or unsupported macro. + macro_unknown: Neznámé nebo nepodporované makro. macros: placeholder: "[Placeholder] Macro %{macro_name}" errors: @@ -4755,7 +4767,7 @@ cs: allowed_actions_html: 'You have the following permissions on this work package: %{allowed_actions}. This can change depending on your project role and permissions.' create_account: Pro přístup k tomuto pracovnímu balíčku musíte vytvořit a aktivovat účet na %{instance}. open_work_package: Otevřít pracovní balíček - subject: Work package %{id} was shared with you + subject: Pracovní balíček %{id} byl s vámi sdílen enterprise_text: Sdílejte pracovní balíčky s uživateli, kteří nejsou členy projektu. summary: user: "%{user} s vámi sdílel pracovní balíček s právy %{role_rights}" @@ -4770,12 +4782,12 @@ cs: recommendation: Budeme i nadále monitorovat systém, abychom zajistili, že zůstane v dobrém stavu. V případě jakýchkoli nesrovnalostí vás budeme informovat. details: Pro více podrobností nebo pro provedení nezbytných změn můžete navštívit konfiguraci úložiště unhealthy: - summary: The status of your storage, %{storage_name}, is currently displaying as "Error". We've detected an issue that might require your attention. + summary: Stav vašeho úložiště, %{storage_name}, se aktuálně zobrazuje jako "Chybný". Zjistili jsme problém, který by mohl vyžadovat vaši pozornost. error-details: Podrobnosti o chybě error-message: '' error-occurred-on: Vyskytlo se - recommendation: We recommend heading over to the storage configuration page to address this issue - unsubscribe: If you would no longer like to receive these notifications, you can unsubscribe at any time. To unsubscribe, please follow the instructions on this page + recommendation: Doporučujeme přejít na stránku konfigurace úložiště a tento problém vyřešit + unsubscribe: Pokud si již nepřejete dostávat tato oznámení, můžete se z odběru kdykoli odhlásit. Chcete-li se odhlásit, postupujte podle pokynů na této stránce email_notification_settings: Nastavení e-mailových oznámení o úložišti see_storage_settings: Zobrazit nastavení úložiště healthy: @@ -4971,11 +4983,11 @@ cs: common: work_package_card_component: drag_handle: - label: Drag to reorder + label: Přesuňte tažením menu: - label_actions: Work package actions - parent: Parent - undisclosed: Undisclosed + label_actions: Operace na pracovním balíčku + parent: Nadřazený + undisclosed: Nezveřejněno permission_add_work_package_comments: Přidat komentáře permission_add_work_packages: Přidat pracovní balíčky permission_add_messages: Odesílat zprávy @@ -5011,12 +5023,12 @@ cs: permission_edit_work_package_comments_explanation: 'Caution: Users with this permission are able to edit anyone''s comment.' permission_edit_work_packages: Upravit pracovní balíčky permission_edit_messages: Upravit zprávy - permission_edit_own_internal_comments: Edit own internal comments + permission_edit_own_internal_comments: Úprava vlastních interních komentářů permission_edit_own_work_package_comments: Upravit vlastní komentáře permission_edit_own_messages: Upravit vlastní zprávy permission_edit_own_time_entries: Upravit vlastní časové záznamy - permission_edit_others_internal_comments: Moderate internal comments - permission_edit_others_internal_comments_explanation: 'Caution: Users with this permission are able to edit other users'' internal comments.' + permission_edit_others_internal_comments: Moderování interních komentářů + permission_edit_others_internal_comments_explanation: 'Upozornění: Uživatelé s tímto oprávněním mohou upravovat interní komentáře jiných uživatelů.' permission_edit_project: Upravit projekt permission_edit_project_attributes: Úprava atributů projektu permission_edit_project_phases: Upravit fáze projektu @@ -5138,9 +5150,9 @@ cs: warning_one: Členové projektu budou muset přemístit úložiště projektu. warning_two: Existující odkazy na projekt nebudou nadále fungovat. title: Změnit identifikátor projektu - not_available: Project N/A + not_available: Projekt N/A template: - copying_title: Applying template + copying_title: Aplikování šablony copying: 'Váš projekt se vytváří z vybranéhé šablony. Budete upozorněni e-mailem, jakmile bude projekt k dispozici. ' @@ -5153,7 +5165,7 @@ cs: project_module_news: Novinky project_module_repository: Repozitář project_module_wiki: Wiki - permission_header_for_project_module_work_package_tracking: Pracovní balíčky a Gantt diagramy + permission_header_for_project_module_work_package_tracking: Pracovní balíčky a Ganttovy diagramy query: attribute_and_direction: "%{attribute} (%{direction})" query_fields: @@ -5617,7 +5629,7 @@ cs: label: Boční panel description: Add all the project attributes in a section inside the right side panel in the project overview. project_initiation_request: - header_description: 'OpenProject can generate a step-by-step wizard to help project managers fill out a project initiation request. You can choose which project attributes should be included and create a PDF artifact as a result. + header_description: 'OpenProject umí vygenerovat průvodce krok za krokem, který projektovým manažerům pomůže vyplnit žádost o zahájení projektu. Můžete si vybrat, které atributy projektu se mají zahrnout, a jako výstup vytvořit PDF dokument. ' status: @@ -5699,8 +5711,8 @@ cs: work_package_identifier: Work package identifiers not_allowed_text: You do not have the necessary permissions to view this page. activities: - enable_internal_comments: Enable internal comments - helper_text_html: 'Internal comments allow an internal team to communicate amongst themselves privately. These are only visible to selected roles that have the necessary permissions and will not be visible publicly. [Click here to learn more](docs_url) + enable_internal_comments: Povolit interní komentáře + helper_text_html: 'Interní komentáře umožňují internímu týmu komunikovat mezi sebou soukromě. Jsou viditelné pouze pro vybrané role, které mají potřebná oprávnění, a nejsou viditelné veřejně. [Klikněte zde pro více informací](docs_url) ' text_formatting: @@ -5847,13 +5859,13 @@ cs: text_plugin_assets_writable: Zapisovatelný adresář aktiv pluginu text_powered_by: Běží na %{link} text_project_identifier_info: Jsou povolena pouze malá písmena (a-z), číslice, pomlčky a podtržítka. Musí začínat malým písmenem. - text_project_identifier_description: The project identifier is prepended to all work package IDs. If the identifier is "PROJ" for example, the work package identifier will be "PROJ-12" or "PROJ-246". + text_project_identifier_description: Identifikátor projektu je připojen ke všem ID pracovních balíčků. Např. Pokud je identifikátor "PROJ", bude identifikátor pracovního balíčku "PROJ-12" nebo "PROJ-246". text_project_identifier_url_description: The project identifier is included in the URL of the project. text_project_identifier_handle_format: Must start with a letter and contain only uppercase letters, numbers, and underscores (max 10 characters). text_project_identifier_format: Must start with a lowercase letter. Only lowercase letters (a-z), numbers, dashes and underscores are allowed. text_reassign: 'Přiřadit k pracovnímu balíčku:' text_regexp_multiline: 'regex je použit v režimu více řádků. např.: ^---\s+' - text_rename_wiki_page: Rename wiki page + text_rename_wiki_page: Přejmenovat wiki stránku text_repository_usernames_mapping: |- Vyberte nebo aktualizujte mapovaný uživatel OpenProject ke každému uživatelskému jménu nalezenému v protokolu repozitáře. Uživatelé se stejným OpenProject a repozitářovým jménem nebo e-mailem jsou automaticky mapováni. diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml index b2016dab9c7..b9204856ebe 100644 --- a/config/locales/crowdin/da.yml +++ b/config/locales/crowdin/da.yml @@ -2106,17 +2106,14 @@ da: before: skal være før %{date}. before_or_equal_to: skal være senest %{date}. blank: må ikke være tomt. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: En arbejdspakke kan ikke knyttes til en af dens underopgaver. circular_dependency: Denne relation vil skabe en cirkulær afhængighed. confirmation: matcher ikke %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: findes ikke. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: kan muligvis ikke tilgås. error_readonly: was attempted to be written but is not writable. @@ -2137,36 +2134,38 @@ da: greater_than_or_equal_to: skal være større end eller lig med %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: er ikke sat til en tilladt værdi. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: er ugyldig. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: skal være mindre end eller lig med %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: Kan ikke slettes not_editable: cannot be edited because it is already in effect. not_current_user: er ikke den aktuelle bruger. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: er ikke et tal. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: er ikke et heltal. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: hører ikke til samme projekt. - datetime_must_be_in_future: must be in the future. odd: skal være ulige. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: skal være mindre end eller lig den maksimale længde. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: er allerede taget. too_long: 'er for lang (maks.: %{count} tegn).' too_short: 'er for kort (min.: %{count} tegn).' @@ -2179,6 +2178,7 @@ da: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: har forkert længde (burde være %{count} tegn). models: group: @@ -2845,6 +2845,7 @@ da: button_login: Log ind button_move: Flyt button_move_and_follow: Flyt og følg + button_next: Next button_print: Print button_quote: Citer button_remove: Fjern @@ -3474,6 +3475,12 @@ da: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4524,6 +4531,9 @@ da: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: I går label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml index ffe4404868e..ae5aa7ccef6 100644 --- a/config/locales/crowdin/de.yml +++ b/config/locales/crowdin/de.yml @@ -52,25 +52,25 @@ de: confirm_button_text: Veröffentlichen admin: reserved_identifiers: - title: Reserved project identifiers - lede_html: When a project's identifier is renamed, the previous identifier is kept reserved so that existing links and integrations keep working.
Here you can release reserved identifiers so that they may be used by other projects. + title: Reservierte Projektkennungen + lede_html: Wenn eine Kennung eines Projekts umbenannt wird, bleibt die vorherige Kennung reserviert, damit bestehende Links und Integrationen weiterhin funktionieren.
Hier können reservierten Kennungen freigegeben werden, sodass sie von anderen Projekten verwendet werden können. col_identifier: Kennung col_project: Projekt - col_reserved: Reserved - not_available_in_semantic_mode: Reserved project identifiers are only available in numeric identifier mode. - filter_label: Search identifiers - btn_release: Release - released_notice: Identifier "%{identifier}" has been released. - identifier_not_found: The reserved identifier could not be found. It may have already been released or the project may have been deleted. Please refresh the page. + col_reserved: Reserviert + not_available_in_semantic_mode: Reservierte Projektkennungen sind nur im numerischen Modus verfügbar. + filter_label: Kennung suchen + btn_release: Freigeben + released_notice: Die Kennung "%{identifier}" wurde freigegeben. + identifier_not_found: Die reservierte Kennung konnte nicht gefunden werden. Möglicherweise wurde diese bereits freigegeben oder das Projekt wurde gelöscht. Bitte aktualisieren Sie die Seite. dialog: - title: Release identifier - heading: Release "%{identifier}"? - description: Releasing this identifier cannot be undone. External links and integrations using it will stop resolving, and the name becomes available for any new project to claim. - checkbox_label: I understand that this cannot be undone. - confirm_button: Release identifier - empty_heading: No reserved identifiers + title: Kennung freigeben + heading: '"%{identifier}" freigeben?' + description: Die Freigabe dieser Kennung kann nicht rückgängig gemacht werden. Externe Links und Integrationen, die diese Kennung verwenden, werden nicht mehr aufgelöst, und der Name wird für neue Projekte verfügbar, die ihn beansprucht. + checkbox_label: Ich verstehe, dass dies nicht rückgängig gemacht werden kann. + confirm_button: Kennung freigeben + empty_heading: Keine reservierten Kennungen reserved_ago: vor %{time} - empty_body: When a project's identifier changes, the previous one will appear here so you can release it once it's safe to do so. + empty_body: Wenn sich die Projektkennung ändert, wird die vorherige Kennung hier angezeigt, damit Sie diese freigeben können, sobald es sicher ist. plugins: no_results_title_text: Es sind derzeit keine Plugins installiert. no_results_content_text: Weitere Informationen finden Sie auf unserer Seite für Integrationen und Plugins. @@ -140,8 +140,8 @@ de: cannot_delete_with_imports: Jira-Hosts mit laufenden Importen können nicht gelöscht werden custom_field_creation_failed: 'Das nutzerdefinierte Feld ''%{name}'' konnte nicht erstellt werden: %{message}' semantic_identifiers_must_be_enabled: - title: Project-based semantic identifiers must be enabled. - description: Jira uses issue identifiers consisting of a project key and a sequence number (PRJ-123). OpenProject also supports it, but it needs to be enabled [here](link). + title: Projektspezifische semantische Kennungen müssen aktiviert sein. + description: Jira verwendet Ticketkennungen, die aus einem Projektschlüssel und einer Sequenznummer bestehen (PRJ-123). OpenProject unterstützt dies ebenfalls, die Funktion muss aber [hier aktiviert werden](link). blank: title: Noch keine Jira-Hosts konfiguriert description: Konfigurieren Sie einen Jira-Host, um mit dem Import von Elementen aus Jira in diese OpenProject-Instanz zu beginnen. @@ -180,7 +180,7 @@ de: client: connection_error: 'Verbindung zum Jira-Server fehlgeschlagen: %{message}' connection_timeout: 'Die Verbindung zum Jira-Server wurde unterbrochen: %{message}' - ssrf_blocked: 'Connection blocked: the Jira host resolves to a private IP address. If your Jira instance runs on an internal network, allow its IP via the OPENPROJECT_SSRF__PROTECTION__IP__ALLOWLIST environment variable.' + ssrf_blocked: 'Verbindung blockiert: Der Jira-Host wird zu einer privaten IP-Adresse aufgelöst. Wenn Ihre Jira-Instanz in einem internen Netzwerk läuft, erlauben Sie ihre IP über die OPENPROJECT_SSRF__PROTECTION__IP__ALLOWLIST Umgebungsvariable.' ssrf_block_doc_link: Bitte sehen Sie sich unsere [Dokumentation](docs_url) an. ssl_error: 'SSL-Fehler bei der Verbindung zum Jira-Server: %{message}' parse_error: 'Die Jira API-Antwort konnte nicht gelesen werden: %{message}' @@ -286,7 +286,7 @@ de: elements: relations: Beziehungen zwischen Tickets project_ids: Projektkennungen - issue_ids: Issue identifiers + issue_ids: Ticketkennungen sprints: Sprint-Zuweisungen workflows: Workflows auf Projektebene schemes: Schemas @@ -433,11 +433,11 @@ de: page_header: description: Wählen Sie zwischen einfachen numerischen Arbeitspaket- oder projektspezifischen Kennungen, bei denen die Projektkennung der Arbeitspaket-ID vorangestellt wird. banner: - existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based semantic identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Convert identifiers'' to update identifiers for all projects in this manner and enable project-based semantic identifiers. + existing_identifiers_notice: 'Vorhandene Kennungen für %{project_count} Projekte entsprechen nicht den Anforderungen für projektbasierte alphanumerische Bezeichner. OpenProject kann diese automatisch aktualisieren, so dass sie wie in den folgenden Beispielen gültig sind. Klicken Sie auf ''Kennung konvertieren'', um die Kennungen für alle Projekte auf diese Weise zu aktualisieren und projektbasierte alphanumerische Bezeichner zu aktivieren. ' box_header: - table_title: Projects with identifiers to update + table_title: Projekte mit Kennungen zum Aktualisieren label_project: Projekt label_previous_identifier: Vorherige Kennung label_autofixed_suggestion: Zukünftige Kennung @@ -455,21 +455,21 @@ de: remaining_projects: one: "... 1 weiteres Projekt" other: "... %{count} weitere Projekte" - button_autofix: Convert identifiers - button_save: Convert identifiers + button_autofix: Kennungen konvertieren + button_save: Kennungen konvertieren dialog: title: Arbeitspaket-Kennungen ändern heading: Aktivieren Sie projektspezifische Arbeitspaket-Kennungen? - description: 'This will change IDs for all work packages in all projects in this instance. Previous identifiers and URLs will continue to work. This change will take some time to complete. + description: 'Dadurch werden die IDs für alle Arbeitspakete in allen Projekten in diesem Fall geändert. Die bisherigen Identifikatoren und URLs werden weiterhin funktionieren. Diese Änderung wird einige Zeit in Anspruch nehmen. ' confirm_button: Kennungen ändern checkbox_label: Mir ist bewusst, dass dies alle Arbeitspaket-Kennungen dauerhaft ändern wird success_banner: Das Format der Arbeitspaket-Kennung wurde erfolgreich aktualisiert. in_progress: - header_semantic: Converting to project-based identifiers - header_classic: Converting to numeric identifiers - footer_message: Background conversion is in progress. You can safely leave this page. + header_semantic: Zu projektbasierten Kennungen konvertieren + header_classic: Zu numerischen Kennungen konvertieren + footer_message: Die Hintergrundkonvertierung ist im Gange. Sie können diese Seite sicher verlassen. workflows: tabs: default_transitions: Standard-Übergänge @@ -915,7 +915,7 @@ de: text: Diese Aktion löscht keine Projekte, die in der Liste enthalten sind. Sind Sie sicher, dass Sie diese Projektliste löschen möchten? settings: header_details: Allgemeine Informationen - header_identifier: Identifier + header_identifier: Kennung header_status: Status header_relations: Projektbeziehungen button_update_details: Einstellungen aktualisieren @@ -940,7 +940,7 @@ de: change_identifier_dialog_title: Projektkennung ändern change_identifier_format_hint_semantic: Nur Großbuchstaben (A-Z), Zahlen oder Unterstriche erlaubt. Maximal 10 Zeichen. Muss mit einem Buchstaben beginnen. change_identifier_format_hint_legacy: Nur Kleinbuchstaben (a-z), Zahlen, Bindestriche oder Unterstriche erlaubt. - change_identifier_warning: 'This will permanently change identifiers and URLs of all work packages in this project. The previous identifiers and URLs will nevertheless continue to work. + change_identifier_warning: 'Dies wird die Kennungen und URLs aller Arbeitspakete in diesem Projekt dauerhaft ändern. Die bisherigen Werte werden jedoch weiterhin funktionieren. ' subitems: @@ -1368,12 +1368,12 @@ de: edit: form_configuration: tab: Formularkonfiguration - label_group: Section - reset_to_defaults: Reset form - add_attribute_group: Section - add_query_group: Related work packages table - delete_group: Delete section - remove_attribute: Remove from section + label_group: Abschnitt + reset_to_defaults: Formular zurücksetzen + add_attribute_group: Abschnitt + add_query_group: Zugehörige Arbeitspaket-Tabelle + delete_group: Abschnitt löschen + remove_attribute: Aus Abschnitt entfernen drag_to_activate: Felder aus diesem Bereich herausziehen, um sie zu aktivieren drag_to_reorder: Ziehen zum Neuordnen edit_query: Abfrage bearbeiten @@ -1383,12 +1383,12 @@ de: no_inactive_attributes: Keine inaktiven Attribute blankslate_title: Noch keine Gruppen blankslate_description: Fügen Sie Gruppen über die Schaltfläche oben hinzu oder ziehen Sie Attribute aus dem linken Bereich. - group_actions: Section actions - rename_group: Rename section - confirm_delete_group: Are you sure you want to delete this section? This action cannot be automatically reversed. - group_name_label: Section name + group_actions: Abschnittsoptionen + rename_group: Abschnitt umbenennen + confirm_delete_group: Sind Sie sicher, dass Sie diesen Abschnitt löschen möchten? Diese Aktion kann nicht automatisch rückgängig gemacht werden. + group_name_label: Name des Abschnitts row_actions: Weitere Aktionen - query_group_label: Related work packages table + query_group_label: Zugehörige Arbeitspaket-Tabelle empty_group_hint: Attribute hierher ziehen invalid_attribute_groups: Die abgesendeten Daten der Formularkonfiguration sind ungültig. invalid_query: Die eingebettete Abfrage ist ungültig. @@ -1396,7 +1396,7 @@ de: untitled_group: Unbenannte Gruppe reset_title: Formularkonfiguration zurücksetzen confirm_reset: Sind Sie sicher, dass Sie die Konfiguration des Formulars zurücksetzen möchten? - builtin_field: Built-in field + builtin_field: Internes Attribut reset_description: 'Dadurch werden die Attribute auf ihre Standardgruppe zurückgesetzt und ALLE benutzerdefinierten Felder deaktiviert. ' @@ -1717,7 +1717,7 @@ de: attachment: attachment_content: Inhalt des Anhangs attachment_file_name: Dateiname des Anhangs - charset: Character set + charset: Zeichensatz content_type: Medien-Typ downloads: Downloads file: Datei @@ -1812,7 +1812,7 @@ de: title: Titel description: Beschreibung member: - blocked: Blocked + blocked: Gesperrt roles: Rollen notification: read_ian: In-App lesen @@ -2058,10 +2058,10 @@ de: priority: Priorität progress: "% abgeschlossen" readonly: Nur Lesezugriff - relatable: Relatable to + relatable: Beziehbar auf remaining_hours: Verbleibender Aufwand remaining_time: Verbleibender Aufwand - sequence_number: Sequence number + sequence_number: Sequenznummer shared_with_users: Geteilt mit schedule_manually: Manuelle Planung spent_hours: Aufgewendete Zeit @@ -2103,17 +2103,14 @@ de: before: muss vor %{date} sein. before_or_equal_to: muss vor oder gleich %{date} sein. blank: muss ausgefüllt werden. - not_before_start_date: darf nicht vor dem Startdatum liegen. - overlapping_range: überschneidet sich mit einem bereits existierenden arbeitsfreien Zeitraum. blank_nested: muss die Eigenschaft '%{property}' gesetzt haben. cannot_delete_mapping: ist erforderlich. Kann nicht gelöscht werden. - is_for_all_cannot_modify: gilt für alle Projekte und kann daher nicht geändert werden. cant_link_a_work_package_with_a_descendant: Ein Arbeitspaket kann nicht mit einer seiner Unteraufgaben verlinkt werden. circular_dependency: Diese Beziehung würde eine zyklische Abhängigkeit erzeugen. confirmation: stimmt nicht mit %{attribute} überein. could_not_be_copied: "%{dependency} konnte nicht (vollständig) kopiert werden." + datetime_must_be_in_future: muss in der Zukunft liegen. does_not_exist: existiert nicht. - user_already_in_department: Der Benutzer %{user_id} ist bereits Mitglied der Abteilung %{department_id}. error_enterprise_only: "%{action} ist nur in der OpenProject Enterprise Edition verfügbar." error_unauthorized: kann nicht zugegriffen werden. error_readonly: wurde versucht zu beschreiben, ist aber nicht beschreibbar. @@ -2134,36 +2131,38 @@ de: greater_than_or_equal_to: muss größer oder gleich %{count} sein. greater_than_or_equal_to_start_date: muss größer als oder gleich dem Anfangsdatum sein. greater_than_start_date: muss größer als das Anfangsdatum sein. + hexcode_invalid: ist kein gültiger 6-stelliger hexadezimaler Farbcode. inclusion: ist nicht auf einen erlaubten Wert gesetzt. inclusion_nested: ist nicht auf einen der erlaubten Werte im Pfad '%{path} ' gesetzt. invalid: ist ungültig. invalid_uri: muss eine gültige URI sein. invalid_url: ist keine gültige URL. invalid_url_scheme: 'ist kein unterstütztes Protokoll (erlaubt: %{allowed_schemes}).' + is_for_all_cannot_modify: gilt für alle Projekte und kann daher nicht geändert werden. less_than_or_equal_to: muss kleiner oder gleich %{count} sein. not_available: ist aufgrund einer Systemkonfiguration nicht verfügbar. + not_before_start_date: darf nicht vor dem Startdatum liegen. not_deletable: kann nicht entfernt werden. not_editable: kann nicht bearbeitet werden, da sie bereits in Kraft ist. not_current_user: ist nicht der aktuelle Benutzer. - system_wide_non_working_day_exists: widerspricht einem systemweiten Nicht-Arbeitstag für dieses Datum. not_found: nicht gefunden. not_a_date: ist kein gültiges Datum. not_a_datetime: ist kein gültiges Datum. not_a_number: ist keine Zahl. not_allowed: ist ungültig aufgrund fehlender Berechtigungen. - host_not_allowed: ist kein erlaubter Host. not_json: konnte nicht als JSON gelsen werden. not_json_object: ist kein gültiges JSON-Objekt. not_an_integer: ist keine ganzzahlige Zahl. not_an_iso_date: 'ist kein gültiges Datum - Erwartetes Format: YYY-MM-DD.' not_same_project: gehört nicht zum selben Projekt. - datetime_must_be_in_future: muss in der Zukunft liegen. odd: muss ungerade sein. + overlapping_range: überschneidet sich mit einem bereits existierenden arbeitsfreien Zeitraum. regex_match_failed: stimmt nicht mit dem regulären Ausdruck %{expression} überein. regex_invalid: konnte nicht mit dem zugehörigen regulären Ausdruck überprüft werden. regex_list_invalid: Die Zeilen %{invalid_lines} konnten nicht als regulärer Ausdruck gelesen werden. - hexcode_invalid: ist kein gültiger 6-stelliger hexadezimaler Farbcode. smaller_than_or_equal_to_max_length: muss kleiner als oder gleich der maximalen Länge sein. + ssrf_filtered: verstößt gegen die SSRF-Richtlinien dieser OpenProject Instanz. + system_wide_non_working_day_exists: widerspricht einem systemweiten Nicht-Arbeitstag für dieses Datum. taken: ist bereits vergeben. too_long: ist zu lang (nicht mehr als %{count} Zeichen). too_short: ist zu kurz (nicht weniger als %{count} Zeichen). @@ -2176,6 +2175,7 @@ de: url_not_secure_context: 'stellt keinen "Secure Context" zur Verfügung: Benutzen Sie entweder HTTPS oder eine Loopback-Adresse, wie z.B. localhost. ' + user_already_in_department: Der Benutzer %{user_id} ist bereits Mitglied der Abteilung %{department_id}. wrong_length: hat die falsche Länge (muss genau %{count} Zeichen haben). models: group: @@ -2421,7 +2421,7 @@ de: cannot_add_child_because_of_lack_of_permission: Sie können keine Unteraufgabe hinzufügen, weil Sie keine Berechtigung haben, das ausgewählte Arbeitspaket zu bearbeiten. blank: ID darf nicht leer sein. identifier: - semantic_identifier_incomplete: and sequence_number must both be set at the same time. + semantic_identifier_incomplete: und sequence_number müssen beide gleichzeitig gesetzt werden. assigned_to: format: "%{message}" done_ratio: @@ -2610,7 +2610,7 @@ de: unsupported_storage_type: ist kein unterstützter Speichertyp. storage_error: Es ist ein Fehler bei der Speicherverbindung aufgetreten. invalid_input: Die Eingabe ist ungültig. - invalid_child_for_parent: is not allowed as a parent for this view type. + invalid_child_for_parent: ist als übergeordnetes Element für diesen Ansichtstyp nicht zulässig. activity: item: created_by_on: erstellt von %{user} am %{datetime} @@ -2840,6 +2840,7 @@ de: button_login: Anmelden button_move: Verschieben button_move_and_follow: Verschieben und Arbeitspaket anzeigen + button_next: Weiter button_print: Drucken button_quote: Zitieren button_remove: Entfernen @@ -3158,8 +3159,8 @@ de: edit_attribute_groups: description: 'Anpassen der Form-Konfiguration mit diesen zusätzlichen Add-ons:' features: - groups: Add new attribute sections - rename: Rename attribute sections + groups: Neue Attributabschnitte hinzufügen + rename: Attributabschnitte umbenennen related: Tabelle mit zugehörigen Arbeitspaketen hinzufügen readonly_work_packages: description: Arbeitspakete in bestimmten Status als schreibgeschützt markieren. @@ -3469,6 +3470,12 @@ de: selected: Ausgewählt include_sub_items: Unterelemente einbeziehen no_results_text: Keine Ergebnisse + header: + project_select_component: + all_projects: Alle Projekte + favorites: Favoriten + leave_project: Projekt verlassen + title: Projekte toggle_switch: label_on: Ein label_off: Aus @@ -3510,8 +3517,8 @@ de: projects: Neueste sichtbare Projekte in dieser Instanz. no_visible_projects: Es gibt keine sichtbaren Projekte in dieser OpenProject-Umgebung. favorite_projects: - no_results: You have no favorite projects - no_results_subtext: Add one or multiple projects as favorite through their overview or in a project list. + no_results: Sie haben keine favorisierten Projekte + no_results_subtext: Fügen Sie ein oder mehrere Projekte als Favorit in ihrer Übersicht oder in einer Projektliste hinzu. users: Neueste registrierte Benutzer in dieser Instanz. blocks: community: OpenProject Community @@ -3522,18 +3529,18 @@ de: learn_about: Erfahren Sie mehr über die neuen Funktionen missing: Es gibt noch keine hervorgehobenen Funktionen. '17_5': - new_features_title: 'The release contains various new features and improvements, such as: + new_features_title: 'Dieses Release enthält verschiedene neue Funktionen und Verbesserungen, wie z. B: ' new_features_list: - line_0: Project-based work package identifiers for clearer references. - line_1: Jira Migrator support for Jira identifiers, due dates, and more. - line_2: Option to exclude work package types from Backlogs. - line_3: Redesigned sprint views. - line_4: Improved work package linking across Documents and text editors. - line_5: More flexible meeting schedules and reduced email notification noise. - line_6: Nested groups for organizational structures and inherited permissions. - line_7: Improved administration interfaces for workflows, users, and type configuration. + line_0: Projektbasierte Arbeitspaket-Kennungen für klarere Referenzen. + line_1: Jira Migrator unterstützt Jira-Kennungen, Fälligkeitsdaten und mehr. + line_2: Option Arbeitspakettypen und -status in Backlogs auszuschließen. + line_3: Neu gestaltete Sprint-Ansichten. + line_4: Verbesserte Verknüpfung von Arbeitspaketen zwischen dem Dokumenten-Modul und Texteditoren. + line_5: Flexiblere Besprechungspläne und weniger E-Mail-Benachrichtigungen. + line_6: Verschachtelte Gruppen für Organisationsstrukturen und vererbte Berechtigungen. + line_7: Verbesserte Verwaltungsoberflächen für Workflows, Benutzer und Typkonfiguration. links: upgrade_enterprise_edition: Auf Enterprise Edition upgraden postgres_migration: Migration Ihrer Installation zu PostgreSQL @@ -4047,7 +4054,7 @@ de: label_home: Hauptseite label_subject_or_id: Titel oder ID label_calendar_subscriptions: Kalenderabonnements - label_identifier: Identifiers + label_identifier: Kennungen label_project_identifier: Projektkennung label_in: an label_in_less_than: in weniger als @@ -4080,7 +4087,7 @@ de: label_journal_diff: Beschreibungsvergleich label_language: Sprache label_languages: Sprachen - label_export_plural: Exports + label_export_plural: Exporte label_external_links: Externe Links label_locale: Sprache und Region label_jump_to_a_project: Zu einem Projekt springen... @@ -4277,7 +4284,7 @@ de: label_project_new: Neues Projekt label_project_plural: Projekte label_project_list_plural: Projektlisten - label_reserved_identifiers: Reserved project identifiers + label_reserved_identifiers: Reservierte Projektkennungen label_project_life_cycle: Projekt-Lebenszyklus label_project_attributes_plural: Projektattribute label_project_custom_field_plural: Projektattribute @@ -4519,6 +4526,9 @@ de: label_x_working_days_time_off: one: 'Freie Zeit: 1 Arbeitstag' other: 'Freie Zeit: %{count} Arbeitstage' + label_x_items_selected: + one: Ein Element ausgewählt + other: "%{count} Elemente ausgewählt" label_yesterday: gestern label_zen_mode: Zen-Modus label_role_type: Typ @@ -4545,7 +4555,7 @@ de: label_total_days_off: Gesamtzahl freier Tage macro_execution_error: Fehler beim Ausführen des Makros %{macro_name} macro_unavailable: Das Makro %{macro_name} kann nicht angezeigt werden. - macro_unknown: Unknown or unsupported macro. + macro_unknown: Unbekanntes oder nicht unterstütztes Makro. macros: placeholder: "[Placeholder] Makro %{macro_name}" errors: @@ -4829,11 +4839,11 @@ de: common: work_package_card_component: drag_handle: - label: Drag to reorder + label: Ziehen zum Neuordnen menu: label_actions: Arbeitspaket-Aktionen parent: Übergeordnetes Arbeitspaket - undisclosed: Undisclosed + undisclosed: Nicht sichtbar permission_add_work_package_comments: Kommentare hinzufügen permission_add_work_packages: Arbeitspakete hinzufügen permission_add_messages: Forenbeiträge hinzufügen @@ -5235,8 +5245,8 @@ de: setting_consent_required: Einwilligung erforderlich setting_consent_decline_mail: Kontaktadresse bei Rückfragen zur Einwilligung setting_cross_project_work_package_relations: Arbeitspaket-Beziehungen zwischen Projekten erlauben - setting_csv_escape_formulas: Escape formulas in CSV exports - setting_csv_escape_formulas_text: 'Escape spreadsheet formulas in CSV exports by prefixing cells that begin with characters such as =, +, -, or @ with a single quote. This mitigates CSV formula injection when exported files are opened in spreadsheet applications such as Excel. This comes at the downside of modifying the string values inside the CSV, so you may want to disable this if downstream tools require the exact, unescaped cell values. + setting_csv_escape_formulas: Formeln in CSV-Exporten maskieren + setting_csv_escape_formulas_text: 'Tabellenkalkulationsformeln in CSV-Exporten maskieren, indem Zellen, die mit Zeichen wie =, +, - oder @ beginnen, ein einfaches Anführungszeichen vorangestellt wird. Dies verhindert CSV-Formelinjektionen, wenn exportierte Dateien in Tabellenkalkulationsanwendungen wie Excel geöffnet werden. Der Nachteil ist, dass dadurch die Zeichenkettenwerte in der CSV verändert werden. Diese Option sollte daher deaktiviert werden, wenn nachgelagerte Tools die exakten, unmaskierten Zellwerte benötigen. ' setting_first_week_of_year: Die erste Woche im Jahr enthält @@ -5279,7 +5289,7 @@ de: setting_work_package_properties: Arbeitspaket-Eigenschaften setting_work_package_startdate_is_adddate: Neue Arbeitspakete haben "Heute" als Anfangsdatum setting_work_packages_projects_export_limit: Arbeitspakete / Exportlimit für Projekte - setting_work_packages_projects_export_limit_text: 'Maximum number of work packages or projects that can be included in a single export. Larger exports are truncated to this limit. + setting_work_packages_projects_export_limit_text: 'Maximale Anzahl von Arbeitspaketen oder Projekten, die in einem einzelnen Export enthalten sein können. Größere Exporte werden auf diesen Grenzwert gekürzt. ' setting_journal_aggregation_time_minutes: Aggregationszeitraum @@ -5368,9 +5378,9 @@ de: setting_welcome_title: Titel des Willkommens-Block setting_welcome_on_homescreen: Willkommens-Block auf Startseite anzeigen setting_work_packages_identifier_classic: Instanzweite numerische Sequenz (Standard) - setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 (for example, #1234). The numbers are unique within the instance and remain the same even if work packages are moved between projects.' - setting_work_packages_identifier_semantic: Project-based semantic identifiers (Beta) - setting_work_packages_identifier_semantic_caption: Every project has a unique project identifier prefixed to a number (for example, PROJ-11). The numbering of each project starts at 1. If a work package is moved to another project, a new identifier is generated but the old one will continue to function. + setting_work_packages_identifier_classic_caption: 'Jedes Arbeitspaket erhält eine sequentielle Nummer beginnend mit 1 (z.B. #1234). Die Nummern sind innerhalb dieser Instanz eindeutig. Sie bleiben also gleich, auch wenn Arbeitspakete zwischen Projekten verschoben werden.' + setting_work_packages_identifier_semantic: Projektspezifische semantische Kennungen (Beta) + setting_work_packages_identifier_semantic_caption: Jedes Projekt hat eine eindeutige Projektkennung, die einer Zahl vorangestellt wird (z. B. PROJ-11). Die Nummerierung beginnt in jedem Projekt bei 1. Wenn ein Arbeitspaket in ein anderes Projekt verschoben wird, wird eine neue Kennung generiert, die alte bleibt jedoch weiterhin gültig. setting_work_package_list_default_highlighting_mode: Standard Hervorhebung setting_work_package_list_default_highlighted_attributes: Voreinstellung Inline Hervorherbung setting_working_days: Arbeitstage @@ -5552,7 +5562,7 @@ de: section_work_week: Arbeitswoche section_holidays_and_closures: Feiertage und Schließungen work_packages: - work_package_identifier: Work package identifiers + work_package_identifier: Arbeitspaket-Kennungen not_allowed_text: Sie haben nicht die notwendigen Rechte, um diese Seite zu sehen. activities: enable_internal_comments: Interne Kommentare aktivieren @@ -5982,16 +5992,16 @@ de: ' dialog: - title: Change working days - description: 'Changing which days of the week are considered working days or non-working days can affect the start and finish days of all work packages and life cycles in all projects in this instance. + title: Arbeitstage ändern + description: 'Die Änderung der Wochentage, die als Arbeitstage oder arbeitsfreie Tage gelten, kann sich auf die Start- und Endtage aller Arbeitspakete und Projektphasen in allen Projekten auswirken. ' - removed_title: 'You will remove the following days from the non-working days list:' - warning: 'The changes might take some time to take effect. You will be notified when all relevant work packages and project life cycles have been updated. + removed_title: 'Sie werden die folgenden Tage aus der Liste der arbeitsfreien Tage entfernen:' + warning: 'Es kann einige Zeit dauern, bis die Änderungen wirksam werden. Sie werden benachrichtigt, wenn alle relevanten Arbeitspakete und Projektphasen aktualisiert worden sind. ' - heading: Change the working days? - confirm_button: Save and reschedule + heading: Arbeitstage ändern? + confirm_button: Speichern und verschieben journal_note: changed: _**Arbeitstage** geändert (%{changes})._ days: @@ -6066,7 +6076,7 @@ de: ancestor: Unbekannt - Das übergeordnete Element ist wegen fehlender Berechtigungen nicht sichtbar. definingProject: Unbekannt - Das Projekt ist wegen fehlender Berechtigungen nicht sichtbar. definingWorkspace: Unbekannt - Der Arbeitsbereich ist wegen fehlender Berechtigungen nicht sichtbar. - workPackage: Undisclosed - The work package is invisible because of lacking permissions. + workPackage: Unbekannt - Das Arbeitspaket ist wegen fehlender Berechtigungen nicht sichtbar. doorkeeper: pre_authorization: status: Vorab-Autorisierung diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml index 2a38bd0ade8..806442f878f 100644 --- a/config/locales/crowdin/el.yml +++ b/config/locales/crowdin/el.yml @@ -2106,17 +2106,14 @@ el: before: πρέπει να είναι πριν από %{date}. before_or_equal_to: πρέπει να είναι πριν ή ίσο με %{date}. blank: δεν πρέπει να είναι κενό. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Ένα πακέτο εργασίας δεν μπορεί να συνδεθεί με μια από τις υποεργασίες του. circular_dependency: Αυτή η σχέση θα δημιουργήσει κυκλική εξάρτηση. confirmation: δεν ταιριάζει με %{attribute}. could_not_be_copied: "%{dependency} δεν μπόρεσε να αντιγραφεί (πλήρως)." + datetime_must_be_in_future: must be in the future. does_not_exist: δεν υπάρχει. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: δεν είναι δυνατή η πρόσβαση. error_readonly: επιχειρήθηκε να εγγραφεί αλλά δεν ήταν εγγράψιμο. @@ -2137,36 +2134,38 @@ el: greater_than_or_equal_to: πρέπει να είναι μεγαλύτερο ή ίσο με %{count}. greater_than_or_equal_to_start_date: πρέπει να είναι μεγαλύτερη ή ίση με τη ημερομηνία έναρξης. greater_than_start_date: πρέπει να είναι μεγαλύτερη από τη ημερομηνία έναρξης. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: δεν έχει οριστεί σε μια από τις επιτρεπόμενες τιμές. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: δεν είναι έγκυρο. invalid_uri: must be a valid URI. invalid_url: δεν είναι μια έγκυρη διεύθυνση URL. invalid_url_scheme: 'δεν είναι υποστηριζόμενο πρωτόκολλο (επιτρεπόμενα: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: πρέπει να είναι μικρότερο ή ίσο με %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: δεν μπορεί να διαγραφεί. not_editable: cannot be edited because it is already in effect. not_current_user: δεν είναι ο τρέχων χρήστης. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: δεν είναι έγκυρη ημερομηνία. not_a_datetime: δεν είναι έγκυρη ημερομηνία και ώρα. not_a_number: δεν είναι αριθμός. not_allowed: δεν είναι έγκυρο επειδή λείπουν δικαιώματα. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: δεν είναι ακέραιος αριθμός. not_an_iso_date: 'δεν είναι έγκυρη ημερομηνία. Απαιτούμενη μορφοποίηση: ΕΕΕΕ-ΜΜ-ΗΗ.' not_same_project: δεν ανήκει στο ίδιο έργο. - datetime_must_be_in_future: must be in the future. odd: πρέπει να είναι μονός. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: δεν ήταν δυνατή η επικύρωση με τη συσχετιζόμενη κανονική έκφραση. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: πρέπει να είναι μικρότερο ή ίσο με το μέγιστο μήκος. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: έχει ήδη κατοχυρωθεί. too_long: είναι πολύ μεγάλο (το μέγιστο είναι %{count} χαρακτήρες). too_short: είναι πολύ μικρό (το ελάχιστο είναι %{count} χαρακτήρες). @@ -2179,6 +2178,7 @@ el: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: έχει λάθος μέγεθος (πρέπει να είναι %{count} χαρακτήρες). models: group: @@ -2845,6 +2845,7 @@ el: button_login: Σύνδεση button_move: Μετακίνηση button_move_and_follow: Μετακίνηση και ακολούθηση + button_next: Next button_print: Εκτύπωση button_quote: Παράθεση button_remove: Αφαίρεση @@ -3474,6 +3475,12 @@ el: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4524,6 +4531,9 @@ el: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: χθες label_zen_mode: Zen mode label_role_type: Τύπος diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml index bfc989c284e..bcefdc493e1 100644 --- a/config/locales/crowdin/eo.yml +++ b/config/locales/crowdin/eo.yml @@ -2107,17 +2107,14 @@ eo: before: devas esti antaŭ la %{date}. before_or_equal_to: devas esti antaŭ aŭ egale al %{date}. blank: ne povas esti malplena. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Laborpakaĵo ne povis esti ligita al unu el siaj subtaskoj. circular_dependency: Tiu ĉi rilato povus krei cirklan dependon. confirmation: ne kongruas kun %{attribute} could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: ne ekzistas. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: ne povas esti atingita. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ eo: greater_than_or_equal_to: devas esti pli granda aŭ egala al %{count}. greater_than_or_equal_to_start_date: devas esti pli granda aŭ egala al la startdato. greater_than_start_date: devas esti pli granda ol la startdato. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: Ĝi ne estas valida. invalid_uri: must be a valid URI. invalid_url: Ĝi ne estas valida URL. invalid_url_scheme: 'ne estas subtenita protokolo (permesitaj: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: devas esti malpli aŭ egala al %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: ne estas la nuna uzanto. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: Ĝi ne estas valida dato. not_a_datetime: Ĝi ne estas valida dato/horo. not_a_number: Ĝi ne estas numero. not_allowed: nevalida pro manko de permesoj. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: ĝi ne estas entjero. not_an_iso_date: 'Ĝi ne estas valida dato. Deviga datumo estas: JJJJ-MM-TT.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: devas esti nepara. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: jam prenita. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ eo: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: la longeco estas malĝusta (devus esti %{count} signoj). models: group: @@ -2846,6 +2846,7 @@ eo: button_login: Ensaluti button_move: Movi button_move_and_follow: Movi kaj daŭrigi + button_next: Next button_print: Printi button_quote: Citi button_remove: Forigi @@ -3475,6 +3476,12 @@ eo: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ eo: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: hieraŭ label_zen_mode: Zen mode label_role_type: Tipo diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml index 1902d4efce4..7820966a13e 100644 --- a/config/locales/crowdin/es.yml +++ b/config/locales/crowdin/es.yml @@ -2102,17 +2102,14 @@ es: before: debe ser antes de %{date}. before_or_equal_to: debe ser antes o igual a %{date}. blank: no puede estar en blanco. - not_before_start_date: no debe ser anterior a la fecha de inicio. - overlapping_range: se solapa con un intervalo de días no laborables ya existente. blank_nested: necesita tener la propiedad '%{property}' definida. cannot_delete_mapping: es obligatorio. No se puede eliminar. - is_for_all_cannot_modify: es para todos los proyectos y, por tanto, no puede modificarse. cant_link_a_work_package_with_a_descendant: Un paquete de trabajo no puede ser vinculado a una de sus subtareas. circular_dependency: Esta relación podría crear una dependencia circular. confirmation: no coincide con %{attribute}. could_not_be_copied: "%{dependency} no se pudo copiar (en su totalidad)." + datetime_must_be_in_future: debe ser en el futuro. does_not_exist: no existe. - user_already_in_department: El usuario %{user_id} ya es miembro del departamento %{department_id}. error_enterprise_only: "%{action} solo está disponible en OpenProject Enterprise." error_unauthorized: no se puede acceder. error_readonly: se intentó escribir pero no se puede escribir. @@ -2133,36 +2130,38 @@ es: greater_than_or_equal_to: debe ser mayor o igual a %{count}. greater_than_or_equal_to_start_date: debe ser mayor o igual a la fecha de inicio. greater_than_start_date: debe ser mayor que la fecha de inicio. + hexcode_invalid: no es un código de color hexadecimal válido de 6 dígitos. inclusion: no está establecido a uno de los valores permitidos. inclusion_nested: no está establecido en uno de los valores permitidos en la ruta '%{path}'. invalid: no es válido. invalid_uri: debe ser un URI válido. invalid_url: no es una URL válida. invalid_url_scheme: 'no es un protocolo admitido (permitidos: %{allowed_schemes}).' + is_for_all_cannot_modify: es para todos los proyectos y, por tanto, no puede modificarse. less_than_or_equal_to: debe ser menor o igual a %{count}. not_available: no está disponible debido a una configuración del sistema. + not_before_start_date: no debe ser anterior a la fecha de inicio. not_deletable: no se puede eliminar. not_editable: no se puede editar porque ya está en vigor. not_current_user: no es el usuario actual. - system_wide_non_working_day_exists: entra en conflicto con un día no laborable ya establecido para todo el sistema en esta fecha. not_found: no encontrado. not_a_date: no es una fecha válida. not_a_datetime: no es una fecha/hora válida. not_a_number: No es un número. not_allowed: no es válido porque faltan permisos. - host_not_allowed: no es un host permitido. not_json: no se puede analizar como JSON. not_json_object: no es un objeto JSON. not_an_integer: No es un entero. not_an_iso_date: 'no es una fecha válida. Requiere formato: AAAA-MM-DD.' not_same_project: no pertenecen a un mismo proyecto. - datetime_must_be_in_future: debe ser en el futuro. odd: debe ser impar. + overlapping_range: se solapa con un intervalo de días no laborables ya existente. regex_match_failed: no coincide con la expresión regular %{expression}. regex_invalid: no se pudo validar con la expresión regular asociada. regex_list_invalid: Las líneas %{invalid_lines} no se pudieron analizar como expresión regular. - hexcode_invalid: no es un código de color hexadecimal válido de 6 dígitos. smaller_than_or_equal_to_max_length: Debe ser menor o igual que el tamaño maximo. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: entra en conflicto con un día no laborable ya establecido para todo el sistema en esta fecha. taken: Ya se ha tomado. too_long: es demasiado largo (el máximo de caracteres es %{count}). too_short: es demasiado corto (el mínimo de caracteres es %{count}). @@ -2175,6 +2174,7 @@ es: url_not_secure_context: 'no está proveyendo un "Contexto Seguro". Utiliza HTTPS o una dirección loopack, como un localhost. ' + user_already_in_department: El usuario %{user_id} ya es miembro del departamento %{department_id}. wrong_length: la longitud es incorrecta (debe ser %{count} caracteres). models: group: @@ -2839,6 +2839,7 @@ es: button_login: Iniciar sesión button_move: Mover button_move_and_follow: Mover y seguir + button_next: Siguiente button_print: Imprimir button_quote: Comentario button_remove: Eliminar @@ -3466,6 +3467,12 @@ es: selected: Seleccionado include_sub_items: Incluir subelementos no_results_text: No hay resultados + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Encendido label_off: Apagado @@ -4516,6 +4523,9 @@ es: label_x_working_days_time_off: one: 'Tiempo libre: 1 día laborable' other: 'Tiempo libre: %{count} días laborables' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ayer label_zen_mode: Modo zen label_role_type: Tipo diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml index 3f5bcc206eb..dee84228258 100644 --- a/config/locales/crowdin/et.yml +++ b/config/locales/crowdin/et.yml @@ -2107,17 +2107,14 @@ et: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: ei tohi olla tühi. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: pole olemas. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ et: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: on vigane. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: ei leitud. not_a_date: pole korrektne kuupäev. not_a_datetime: is not a valid date time. not_a_number: pole arv. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: pole täisarv. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: peab olema paaritu arv. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: on juba kasutusel. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ et: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ et: button_login: Logi sisse button_move: Tõsta button_move_and_follow: Tõsta ja järgne + button_next: Next button_print: Prindi button_quote: Tsiteeri button_remove: Eemalda @@ -3475,6 +3476,12 @@ et: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ et: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: eile label_zen_mode: Keskendumise režiim label_role_type: Tüüp diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml index 3a8b16bdb50..bdf11e4b538 100644 --- a/config/locales/crowdin/eu.yml +++ b/config/locales/crowdin/eu.yml @@ -2107,17 +2107,14 @@ eu: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ eu: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ eu: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ eu: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ eu: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ eu: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml index 87c926447a7..12a945a67f0 100644 --- a/config/locales/crowdin/fa.yml +++ b/config/locales/crowdin/fa.yml @@ -2107,17 +2107,14 @@ fa: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ fa: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: ساختار آدرس صحیح نیست. invalid_url_scheme: 'این پروتکل مجاز نیست (موارد مجاز: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ fa: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ fa: button_login: ورود button_move: انتقال button_move_and_follow: کپی و دنبال کردن + button_next: Next button_print: چاپ کردن button_quote: نقل قول button_remove: Remove @@ -3475,6 +3476,12 @@ fa: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ fa: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: نوع diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml index 977e64726f5..3fc0bd9ecd6 100644 --- a/config/locales/crowdin/fi.yml +++ b/config/locales/crowdin/fi.yml @@ -2107,17 +2107,14 @@ fi: before: on oltava ennen %{date}. before_or_equal_to: on oltava %{date} tai sitä ennen. blank: ei voi olla sisällötön. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Tehtävää ei voida yhdistää alitehtäviin. circular_dependency: Tämä riippuvuus loisi kehän. confirmation: ei vastaa %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: ei ole olemassa. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ fi: greater_than_or_equal_to: täytyy olla suurempi tai yhtä suuri kuin%{count}. greater_than_or_equal_to_start_date: on oltava suurempi tai yhtä suuri kuin alkamispäivä. greater_than_start_date: tulee olla aloituspäivän jälkeinen. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: ei löydy listauksesta. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: ei kelpaa. invalid_uri: must be a valid URI. invalid_url: ei ole kelvollinen URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: täytyy olla pienempi tai yhtä suuri kuin %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: ei ole kelvollinen päivämäärä. not_a_datetime: ei ole kelvollinen aika. not_a_number: ei ole numero. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: ei ole kokonaisluku. not_an_iso_date: 'ei ole kelvollinen päivämäärä. Vaadittava muoto: VVVV-KK-PP.' not_same_project: ei kuulu samaan projektiin. - datetime_must_be_in_future: must be in the future. odd: täytyy olla pariton. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: on oltava pienempi tai yhtä suuri kuin suurin sallittu pituus. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: on jo käytössä. too_long: on liian pitkä (maksimi on %{count} merkkiä). too_short: on liian lyhyt (minimi on %{count} merkkiä). @@ -2180,6 +2179,7 @@ fi: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: on väärän pituinen (täytyy olla täsmälleen %{count} merkkiä). models: group: @@ -2844,6 +2844,7 @@ fi: button_login: Kirjaudu button_move: Siirrä button_move_and_follow: Siirrä ja seuraa + button_next: Next button_print: Tulosta button_quote: Siteeraa button_remove: Poista @@ -3473,6 +3474,12 @@ fi: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4523,6 +4530,9 @@ fi: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: eilen label_zen_mode: Zen mode label_role_type: Tyyppi diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml index 591f42ee60f..5b9ea3711b3 100644 --- a/config/locales/crowdin/fil.yml +++ b/config/locales/crowdin/fil.yml @@ -2107,17 +2107,14 @@ fil: before: dapat ay bago ang %{date}. before_or_equal_to: dapat ay bago o katumbas sa %{date}. blank: hindi pwedeng blanko. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Ang isang package ng pagawaan ay hindi maaring mai-ugnay sa isa sa mga substak. circular_dependency: Itong pakikipag-ugnayan ay lilikha ng kabilugang dependecia. confirmation: hindi tugma %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: hindi umiiral. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ fil: greater_than_or_equal_to: dapat ay mas malaki o kapareho sa %{count}. greater_than_or_equal_to_start_date: dapat ay mas malaki kaysa o katumbas sa petsa ng pagsisimula. greater_than_start_date: dapat ay mas malaki kaysa sa petsa ng pagsisiimula. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: ay hindi nakatakda sa isa ng mga pinahintulutan halaga. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: ay hindi balido. invalid_uri: must be a valid URI. invalid_url: ay hindi balidong URL. invalid_url_scheme: 'ay hindi suportado ng protocol (pinahintulutan: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: dapat ay hindi baba o katumbas sa %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: ay hindi balido ang petsa. not_a_datetime: ay hindi balido ang petsa ng oras. not_a_number: ay hindi numero. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: ay hindi integer. not_an_iso_date: 'ay hindi balido ang petsa. Ang kinakailangan format: YYYY-MM-DD.' not_same_project: ay hindi nabibilang sa parehong proyekto. - datetime_must_be_in_future: must be in the future. odd: dapat ay kakaiba. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: hindi pwedeng mapatunayan sa nauugnay na mga regular na ekspresyon. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: dapat ay mas maliit kaysa o katumbas sa pinakamataas na haba. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: ay nakuha na. too_long: ay masyadong mahaba (pinakamataas ay ang mga %{count} karakter). too_short: ay masyadong mababa (pinakamaliit ay ang mga %{count} karakter. @@ -2180,6 +2179,7 @@ fil: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: ay ang maling haba (dapat ay %{count} ang mga karakter). models: group: @@ -2846,6 +2846,7 @@ fil: button_login: Mag-sign in button_move: Ilipat button_move_and_follow: Ilipat at sundin + button_next: Next button_print: I-print button_quote: Quote button_remove: Tanggalin @@ -3475,6 +3476,12 @@ fil: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ fil: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: kahapon label_zen_mode: Zen mode label_role_type: Uri diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml index 0c4aa066012..f10cfb47f0e 100644 --- a/config/locales/crowdin/fr.yml +++ b/config/locales/crowdin/fr.yml @@ -2100,17 +2100,14 @@ fr: before: doit être antérieur(e) à %{date}. before_or_equal_to: doit être antérieur(e) ou égal(e) à %{date}. blank: ne peut pas être vide. - not_before_start_date: ne doit pas être avant la date de début. - overlapping_range: chevauche une plage de jours non ouvrables existante. blank_nested: doit avoir la propriété « %{property} » définie. cannot_delete_mapping: est requis. Ne peut être supprimé. - is_for_all_cannot_modify: s'applique à tous les projets et ne peut donc pas être modifié. cant_link_a_work_package_with_a_descendant: Un lot de travaux ne peut pas être lié à l'une de ses sous-tâches. circular_dependency: Cette relation créerait une dépendance circulaire. confirmation: ne correspond pas à %{attribute}. could_not_be_copied: "%{dependency} n'a pas pu être copié (entièrement)." + datetime_must_be_in_future: doit se situer dans le futur. does_not_exist: n'existe pas. - user_already_in_department: L'utilisateur %{user_id} est déjà membre du service %{department_id}. error_enterprise_only: "%{action} n'est disponible que dans l'édition Enterprise d'OpenProject." error_unauthorized: est interdit d'accès. error_readonly: a tenté d'être écrit mais n'est pas accessible en écriture. @@ -2131,36 +2128,38 @@ fr: greater_than_or_equal_to: doit être supérieur ou égal à %{count}. greater_than_or_equal_to_start_date: doit être supérieur ou égal à la date de début. greater_than_start_date: doit être postérieure à la date de début. + hexcode_invalid: n'est pas un code couleur hexadécimal valide à 6 chiffres. inclusion: ne correspond à aucune des valeurs autorisées. inclusion_nested: ne correspond à aucune des valeurs autorisées dans le chemin « %{path} ». invalid: est invalide. invalid_uri: doit être une URI valide. invalid_url: n'est pas une URL valide. invalid_url_scheme: 'n''est pas un protocole pris en charge (autorisés : %{allowed_schemes}).' + is_for_all_cannot_modify: s'applique à tous les projets et ne peut donc pas être modifié. less_than_or_equal_to: doit être inférieur ou égal à %{count}. not_available: n'est pas disponible en raison d'une configuration système. + not_before_start_date: ne doit pas être avant la date de début. not_deletable: ne peut pas être supprimé not_editable: ne peut pas être modifiée car elle est déjà en vigueur. not_current_user: n'est pas l'utilisateur actuel. - system_wide_non_working_day_exists: entre en conflit avec un jour chômé existant dans le système pour cette date. not_found: introuvable. not_a_date: n'est pas une date valide. not_a_datetime: n'est pas une heure valide. not_a_number: n'est pas un nombre. not_allowed: est invalide en raison d'autorisations insuffisantes. - host_not_allowed: n'est pas un hôte autorisé. not_json: ne peut pas être analysé en tant que JSON. not_json_object: n'est pas un objet JSON. not_an_integer: n'est pas un entier. not_an_iso_date: 'n''est pas une date valide. Format requis : AAAA-MM-JJ.' not_same_project: n'appartient pas au même projet. - datetime_must_be_in_future: doit se situer dans le futur. odd: doit être impair. + overlapping_range: chevauche une plage de jours non ouvrables existante. regex_match_failed: ne correspond pas à l'expression régulière %{expression}. regex_invalid: n'a pas pu être validé avec l'expression régulière associée. regex_list_invalid: Les lignes %{invalid_lines} n'ont pas pu être analysées comme des expressions régulières. - hexcode_invalid: n'est pas un code couleur hexadécimal valide à 6 chiffres. smaller_than_or_equal_to_max_length: doit être inférieur ou égal à la longueur maximale. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: entre en conflit avec un jour chômé existant dans le système pour cette date. taken: a déjà été pris. too_long: est trop long (le maximum est de %{count} caractères). too_short: est trop court (le minimum est de %{count} caractères). @@ -2173,6 +2172,7 @@ fr: url_not_secure_context: 'ne fournit pas de « Contexte sécurisé ». Utilisez soit HTTPS, soit une adresse de bouclage, comme localhost. ' + user_already_in_department: L'utilisateur %{user_id} est déjà membre du service %{department_id}. wrong_length: est de mauvaise longueur (devrait être %{count} caractères). models: group: @@ -2839,6 +2839,7 @@ fr: button_login: Connexion button_move: Déplacer button_move_and_follow: Déplacer et suivre + button_next: Suivant button_print: Imprimer button_quote: Citer button_remove: Supprimer @@ -3468,6 +3469,12 @@ fr: selected: Sélectionné include_sub_items: Inclure les sous-projets no_results_text: Aucun résultat + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Activé label_off: Désactivé @@ -4518,6 +4525,9 @@ fr: label_x_working_days_time_off: one: 'Temps libre : 1 jour ouvrable' other: 'Temps libre : %{count} jours ouvrables' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: hier label_zen_mode: Mode zen label_role_type: Type diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml index 98dc57bd609..13e0e6668ba 100644 --- a/config/locales/crowdin/he.yml +++ b/config/locales/crowdin/he.yml @@ -2149,17 +2149,14 @@ he: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2180,36 +2177,38 @@ he: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: זה לא המשתמש הנכון. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2222,6 +2221,7 @@ he: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2928,6 +2928,7 @@ he: button_login: לוג-אין button_move: העבר button_move_and_follow: הזז ועקוב + button_next: Next button_print: Print button_quote: צטט button_remove: Remove @@ -3599,6 +3600,12 @@ he: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4659,6 +4666,11 @@ he: two: 'Time off: %{count} working days' many: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + two: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: אתמול label_zen_mode: Zen mode label_role_type: סוג diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml index 35a32f69ca6..aa4996d1bec 100644 --- a/config/locales/crowdin/hi.yml +++ b/config/locales/crowdin/hi.yml @@ -2107,17 +2107,14 @@ hi: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ hi: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: अनुपलब्ध अनुमतियों के कारण अमांय है । - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ hi: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ hi: button_login: साइन इन करें button_move: स्थानांतरित करें button_move_and_follow: स्थानांतरित करें व फौलो करें + button_next: Next button_print: Print button_quote: उद्धरण button_remove: Remove @@ -3475,6 +3476,12 @@ hi: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ hi: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: प्रकार diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml index a9065e2e865..2f15df5d5a4 100644 --- a/config/locales/crowdin/hr.yml +++ b/config/locales/crowdin/hr.yml @@ -2128,17 +2128,14 @@ hr: before: mora biti prije %{date}. before_or_equal_to: mora biti prije ili jednako %{date}. blank: ne može biti prazan unos. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Radni paket ne može biti pridružen podređenim radnim zadacima. circular_dependency: Ova relacija izraditi će skupnu odnosno cirkularnu ovisnost. confirmation: ne odgovara %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: ne postoji. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2159,36 +2156,38 @@ hr: greater_than_or_equal_to: mora biti veće od ili jednako %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nije postavljeno na jednu od dozvoljenih vrijednosti. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: je nevažeće. invalid_uri: must be a valid URI. invalid_url: nije valjani URL. invalid_url_scheme: 'nije podržani protokol (dozvoljeno: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: mora biti manji od ili jednak %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: nije tip podataka number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: nije tip podatka integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: ne pripada istom projektu. - datetime_must_be_in_future: must be in the future. odd: mora biti neparan. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: mora biti manje od ili jednako maksimalnom trajanju. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: već je zauzeto. too_long: je predugo (maksimalno %{count} znakova). too_short: je prekratko (minimalno %{count} znakova). @@ -2201,6 +2200,7 @@ hr: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: je krive duljine (mora biti %{count} znakova). models: group: @@ -2885,6 +2885,7 @@ hr: button_login: Prijavi se button_move: Premjesti button_move_and_follow: Premjesti i slijedi + button_next: Next button_print: Ispis button_quote: Citiraj button_remove: Ukloni @@ -3535,6 +3536,12 @@ hr: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4590,6 +4597,10 @@ hr: one: 'Time off: 1 working day' few: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + other: "%{count} items selected" label_yesterday: jučer label_zen_mode: Zen mode label_role_type: Tip diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml index efdbee53010..ab2fd39af19 100644 --- a/config/locales/crowdin/hu.yml +++ b/config/locales/crowdin/hu.yml @@ -2131,19 +2131,16 @@ hu: before: korábbinak kell lennie, mint %{date}. before_or_equal_to: korábbinak vagy egyenlőnek kell lennie, mint %{date}. blank: nem lehet üres. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: 'be kell állítani a ''%{property}'' tulajdonságot. ' cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A feladatcsoport nem kapcsolható saját részfeladatához. circular_dependency: Ez a kapcsolat egy körkörös függőséget eredményezne. confirmation: "%{attribute} nem egyezik." could_not_be_copied: A (z) %{dependency} nem másolható (teljesen). + datetime_must_be_in_future: must be in the future. does_not_exist: nem létezik. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: lehet, hogy nem érhető el. error_readonly: írása megkísérelve, de nem írható. @@ -2164,38 +2161,40 @@ hu: greater_than_or_equal_to: nagyobbnak vagy egyenlőnek kell lennie mint %{count}. greater_than_or_equal_to_start_date: nagyobbnak vagy egyenlőnek kell lennie, mint a kezdő dátum. greater_than_start_date: nagyobbnak kell lennie, mint a kezdő dátum. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nem a megengedett értékek egyike lett beállítva. inclusion_nested: nincs beállítva az '%{path}' elérési útvonalon a megengedett értékek egyikére. invalid: érvénytelen. invalid_uri: must be a valid URI. invalid_url: nem érvényes URL. invalid_url_scheme: 'nem támogatott protokoll (támogatott: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: kisebbnek vagy egyenlőnek kell lennie mint, %{count}. not_available: 'nem érhető el a rendszer konfigurációja miatt. ' + not_before_start_date: must not be before the start date. not_deletable: nem törölhető not_editable: cannot be edited because it is already in effect. not_current_user: nem az aktuális felhasználó - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: nem érvényes dátum. not_a_datetime: ez nem érvényes dátum. not_a_number: ez nem egy szám. not_allowed: hiányzó engedélyek miatt érvénytelen. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: ez nem egy szám. not_an_iso_date: nem érvényes dátum. A szükséges formátum ÉÉÉÉ-HH-NN. not_same_project: nem azonos projekthez tartozik. - datetime_must_be_in_future: must be in the future. odd: páratlan kell legyen. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: nem lehet a hozzárendelt reguláris kifejezéssel ellenőrizni. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: a maximális hossznak kisebbnek vagy egyenlőnek kell lennie. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: már foglalt. too_long: túl hosszú (nem lehet több %{count} karakternél). too_short: túl rövid (legalább %{count} karakter kell legyen). @@ -2210,6 +2209,7 @@ hu: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: nem megfelelő hosszúságú (%{count} karakter szükséges). models: group: @@ -2900,6 +2900,7 @@ hu: button_login: Bejelentkezés button_move: Mozgatás button_move_and_follow: Mozgatés és a következő + button_next: Next button_print: Nyomtatás button_quote: Idéz button_remove: Eltávolítás @@ -3537,6 +3538,12 @@ hu: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4589,6 +4596,9 @@ hu: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: tegnap label_zen_mode: Zen mode label_role_type: Típus diff --git a/config/locales/crowdin/hy.yml b/config/locales/crowdin/hy.yml index 6570305efa7..7de52b74825 100644 --- a/config/locales/crowdin/hy.yml +++ b/config/locales/crowdin/hy.yml @@ -2107,17 +2107,14 @@ hy: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ hy: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ hy: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ hy: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ hy: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ hy: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml index fdce041aab8..15c5aeacacf 100644 --- a/config/locales/crowdin/id.yml +++ b/config/locales/crowdin/id.yml @@ -2090,17 +2090,14 @@ id: before: harus sebelum %{date}. before_or_equal_to: harus sebelum atau maksimal %{date}. blank: harus di isi. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: harus menyetel properti '%{property}'. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Work package tidak dapat dihubungkan dengan subtask-nya. circular_dependency: Relasi ini menyebabkan dependensi circular. confirmation: tidak sesuai dengan %{attribute}. could_not_be_copied: "%{dependency} tidak dapat (sepenuhnya) disalin." + datetime_must_be_in_future: must be in the future. does_not_exist: tidak ditemukan. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: mungkin tidak dapat diakses. error_readonly: Mencoba untuk ditulis tetapi tidak dapat ditulis. @@ -2121,36 +2118,38 @@ id: greater_than_or_equal_to: harus lebih besar atau sama dengan %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: belum di set dengan nilai yang diperbolehkan. inclusion_nested: tidak disetel ke salah satu nilai yang diizinkan di jalur '%{path}'. invalid: tidak valid. invalid_uri: must be a valid URI. invalid_url: bukanlah URL yang Valid. invalid_url_scheme: 'bukanlah sebuah protokol yang didukung (diperbolehkan: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: harus kurang dari atau sama dengan %{count}. not_available: tidak tersedia karena konfigurasi sistem. + not_before_start_date: must not be before the start date. not_deletable: tidak dapat dihapus. not_editable: cannot be edited because it is already in effect. not_current_user: bukan pengguna saat ini. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: bukan tanggal yang valid. not_a_datetime: bukan tanggal waktu yang valid. not_a_number: harus diisi angka. not_allowed: tidak valid karena tidak ada izin. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: harus bilangan bulat. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: harus berasal dari proyek yang sama. - datetime_must_be_in_future: must be in the future. odd: harus ganjil. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: tidak dapat divalidasi dengan ekspresi reguler terkait. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: harus lebih kecil atau sama dengan panjang maksimum. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: sudah dipakai. too_long: panjang karakter maksimal %{count}. too_short: minimal %{count} karakter. @@ -2163,6 +2162,7 @@ id: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: panjang tidak sesuai (harus %{count} karakter). models: group: @@ -2814,6 +2814,7 @@ id: button_login: Login button_move: Pindahkan button_move_and_follow: Pindahkan dan amati + button_next: Next button_print: Cetak button_quote: Kutipan button_remove: Remove @@ -3424,6 +3425,12 @@ id: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4469,6 +4476,8 @@ id: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: kemarin label_zen_mode: Zen mode label_role_type: Mengetik diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml index bc2b09182ba..2b63a2a71c0 100644 --- a/config/locales/crowdin/it.yml +++ b/config/locales/crowdin/it.yml @@ -2105,17 +2105,14 @@ it: before: deve essere precedente al %{date}. before_or_equal_to: deve essere precedente o uguale al %{date}. blank: non può essere lasciato vuoto. - not_before_start_date: non deve essere prima della data di inizio. - overlapping_range: si sovrappone a un intervallo di giorni non lavorativi esistente. blank_nested: deve avere la proprietà '%{property}' impostata. cannot_delete_mapping: è necessario. Non può essere cancellato. - is_for_all_cannot_modify: è per tutti i progetti e non può quindi essere modificato. cant_link_a_work_package_with_a_descendant: Una macro-attività non può essere collegato a una delle sue sottoattività. circular_dependency: Questa relazione creerebbe una dipendenza circolare. confirmation: non coincide con %{attribute}. could_not_be_copied: "%{dependency} non può essere (completamente) copiato." + datetime_must_be_in_future: deve essere nel futuro. does_not_exist: non esiste. - user_already_in_department: L'utente %{user_id} è già membro del reparto %{department_id}. error_enterprise_only: "%{action} è disponibile solo in OpenProject Enterprise edition." error_unauthorized: potrebbe non essere accessibile. error_readonly: è in sola lettura, pertanto non è stato possibile modificarlo. @@ -2136,36 +2133,38 @@ it: greater_than_or_equal_to: deve essere maggiore o uguale di %{count}. greater_than_or_equal_to_start_date: deve essere successivo o uguale alla data di inizio. greater_than_start_date: deve essere successivo alla data di inizio. + hexcode_invalid: non è un codice colore esadecimale a 6 cifre valido. inclusion: non è impostata su uno dei valori consentiti. inclusion_nested: non è impostato su uno dei valori consentiti al percorso '%{path}'. invalid: non è valido. invalid_uri: deve essere un URI valido. invalid_url: non è un URL valido. invalid_url_scheme: 'non è un protocollo supportato (ammessi: %{allowed_schemes}).' + is_for_all_cannot_modify: è per tutti i progetti e non può quindi essere modificato. less_than_or_equal_to: deve essere inferiore o uguale a %{count}. not_available: non è disponibile a causa di una configurazione di sistema. + not_before_start_date: non deve essere prima della data di inizio. not_deletable: non può essere eliminato. not_editable: non può essere modificato perché è già in vigore. not_current_user: non è l'utente attuale. - system_wide_non_working_day_exists: È in conflitto con un giorno non lavorativo già definito a livello di sistema per questa data. not_found: non trovato. not_a_date: non è una data valida. not_a_datetime: non è un'orario valido. not_a_number: non è un numero. not_allowed: non è valido a causa di autorizzazioni assenti. - host_not_allowed: non è un host consentito. not_json: non è analizzabile come JSON. not_json_object: non è un oggetto JSON. not_an_integer: non è un numero intero. not_an_iso_date: 'non è una data valida. Formato richiesto: AAAA-MM-GG.' not_same_project: non appartiene allo stesso progetto. - datetime_must_be_in_future: deve essere nel futuro. odd: deve essere dispari. + overlapping_range: si sovrappone a un intervallo di giorni non lavorativi esistente. regex_match_failed: non corrisponde all'espressione regolare %{expression}. regex_invalid: non può essere convalidato con l'espressione regolare associata. regex_list_invalid: Le righe %{invalid_lines} non possono essere analizzate come espressione regolare. - hexcode_invalid: non è un codice colore esadecimale a 6 cifre valido. smaller_than_or_equal_to_max_length: deve essere minore o uguale alla lunghezza massima. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: È in conflitto con un giorno non lavorativo già definito a livello di sistema per questa data. taken: è già stato usato. too_long: è troppo lungo (il massimo è %{count} caratteri). too_short: è troppo breve (il minimo è %{count} caratteri). @@ -2178,6 +2177,7 @@ it: url_not_secure_context: 'non fornisce un "Contesto sicuro". Usa HTTPS o un indirizzo di loopback, come localhost. ' + user_already_in_department: L'utente %{user_id} è già membro del reparto %{department_id}. wrong_length: è della lunghezza sbagliata (dovrebbe essere %{count} caratteri). models: group: @@ -2846,6 +2846,7 @@ it: button_login: Accedi button_move: Sposta button_move_and_follow: Sposta e segui + button_next: Avanti button_print: Stampa button_quote: Cita button_remove: Rimuovi @@ -3475,6 +3476,12 @@ it: selected: Selezionati include_sub_items: Includi sottovoci no_results_text: Nessun risultato + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ it: label_x_working_days_time_off: one: 'Assenza: 1 giorno lavorativo' other: 'Assenza: %{count} giorni lavorativi' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ieri label_zen_mode: Modalità Zen label_role_type: Tipo diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml index c0d04c3859c..8f26d0e95ff 100644 --- a/config/locales/crowdin/ja.yml +++ b/config/locales/crowdin/ja.yml @@ -2089,17 +2089,14 @@ ja: before: は%{date}の前にしてください。 before_or_equal_to: は%{date}より以前にしてください。 blank: は空白にすることができません。 - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: プロパティ '%{property}' が設定されている必要があります。 cannot_delete_mapping: 必須です。削除できません。 - is_for_all_cannot_modify: はすべてのプロジェクトで使用されているため、変更できません。 cant_link_a_work_package_with_a_descendant: 親子関係にあるワークパッケージ間で関係の設定はできません。 circular_dependency: この関係は循環依存になります。 confirmation: は%{attribute} と一致しません。 could_not_be_copied: "%{dependency} を(完全に)コピーできませんでした。" + datetime_must_be_in_future: 未来に違いないわ。 does_not_exist: は存在しません。 - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: アクセスできません。 error_readonly: 書けませんでした。 @@ -2120,36 +2117,38 @@ ja: greater_than_or_equal_to: は%{count}以上の値にしてください。 greater_than_or_equal_to_start_date: は開始日以後にしてください。 greater_than_start_date: は開始日より後にしてください。 + hexcode_invalid: は有効な6桁の16進カラーコードではない。 inclusion: は許可されている値ではありません。 inclusion_nested: はパス '%{path}' で許可されている値のいずれかに設定されていません。 invalid: は不正な値です。 invalid_uri: must be a valid URI. invalid_url: は有効な URL ではありません。 invalid_url_scheme: 'はサポートされたプロトコルではありません (可能: %{allowed_schemes})。' + is_for_all_cannot_modify: はすべてのプロジェクトで使用されているため、変更できません。 less_than_or_equal_to: は%{count}以下の値にしてください。 not_available: はシステム構成のため使用できません。 + not_before_start_date: must not be before the start date. not_deletable: 削除できません。 not_editable: cannot be edited because it is already in effect. not_current_user: 現在のユーザーではありません。 - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: 見つかりません。 not_a_date: は有効な日付ではありません。 not_a_datetime: は有効な日時ではありません。 not_a_number: は数値にしてください。 not_allowed: 権限がないため無効です。 - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: は整数にしてください。 not_an_iso_date: 'は有効な日付ではありません。必要な形式: YYYY-MM-dd。' not_same_project: は同じプロジェクトに属していません。 - datetime_must_be_in_future: 未来に違いないわ。 odd: は奇数にしてください。 + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: 正規表現 %{expression}と一致しません。 regex_invalid: 関連付けられた正規表現を検証できませんでした。 regex_list_invalid: "%{invalid_lines}行は正規表現として解析できませんでした。" - hexcode_invalid: は有効な6桁の16進カラーコードではない。 smaller_than_or_equal_to_max_length: は最大長さより以下でなければなりません。 + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: は既に使用されています。 too_long: は%{count}文字以内を入力してください。 too_short: は%{count}文字以上を入力してください。 @@ -2162,6 +2161,7 @@ ja: url_not_secure_context: 'は「セキュアコンテキスト」を提供していません。HTTPSを使用するか、localhostのようなループバックアドレスを使用してください。 ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: は%{count}文字を入力してください。 models: group: @@ -2808,6 +2808,7 @@ ja: button_login: ログイン button_move: 移動 button_move_and_follow: 移動後表示 + button_next: Next button_print: 印刷 button_quote: 引用 button_remove: 削除 @@ -3416,6 +3417,12 @@ ja: selected: 選択済み include_sub_items: サブアイテムを含める no_results_text: 結果がありません + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4461,6 +4468,8 @@ ja: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: 昨日 label_zen_mode: 禅モード label_role_type: 種別 diff --git a/config/locales/crowdin/js-af.yml b/config/locales/crowdin/js-af.yml index c28091b37c3..d0abb9e18b9 100644 --- a/config/locales/crowdin/js-af.yml +++ b/config/locales/crowdin/js-af.yml @@ -1045,16 +1045,13 @@ af: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ar.yml b/config/locales/crowdin/js-ar.yml index c3844f3a4d6..a21b6b2260a 100644 --- a/config/locales/crowdin/js-ar.yml +++ b/config/locales/crowdin/js-ar.yml @@ -1061,16 +1061,13 @@ ar: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-az.yml b/config/locales/crowdin/js-az.yml index 6856dd03690..9ddb74d8330 100644 --- a/config/locales/crowdin/js-az.yml +++ b/config/locales/crowdin/js-az.yml @@ -1045,16 +1045,13 @@ az: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-be.yml b/config/locales/crowdin/js-be.yml index 4884b50b2f4..93a7ad7d890 100644 --- a/config/locales/crowdin/js-be.yml +++ b/config/locales/crowdin/js-be.yml @@ -1053,16 +1053,13 @@ be: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-bg.yml b/config/locales/crowdin/js-bg.yml index 00f9a2c8e21..c1e6a8165fe 100644 --- a/config/locales/crowdin/js-bg.yml +++ b/config/locales/crowdin/js-bg.yml @@ -1045,16 +1045,13 @@ bg: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ca.yml b/config/locales/crowdin/js-ca.yml index 7cf16d34bf3..da2d83984a6 100644 --- a/config/locales/crowdin/js-ca.yml +++ b/config/locales/crowdin/js-ca.yml @@ -1045,16 +1045,13 @@ ca: all: Tots els projectes selected: Només seleccionats search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Inclou tots els subprojectes tooltip: include_all_selected: Projecte ja inclòs, ja que "Inclou tots els subprojectes" està activat. current_project: Aquest és el projecte actual. does_not_match_search: El projecte no coincideix amb la cerca. no_results: Cap projecte s'ajusta a la teva cerca. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ckb-IR.yml b/config/locales/crowdin/js-ckb-IR.yml index ca666133659..03a8be8b075 100644 --- a/config/locales/crowdin/js-ckb-IR.yml +++ b/config/locales/crowdin/js-ckb-IR.yml @@ -1045,16 +1045,13 @@ ckb-IR: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml index 85b8f01ef80..b14e714cce6 100644 --- a/config/locales/crowdin/js-cs.yml +++ b/config/locales/crowdin/js-cs.yml @@ -1057,16 +1057,13 @@ cs: all: Všechny projekty selected: Pouze vybrané search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Zahrnout všechny podprojekty tooltip: include_all_selected: Projekt je již zahrnut, protože Zahrnout všechny podprojekty je povoleno. current_project: Toto je aktuální projekt, ve kterém se nacházíte. does_not_match_search: Projekt neodpovídá kritériím vyhledávání. no_results: Žádný projekt neodpovídá vašim kritériím vyhledávání. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Hledat... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-da.yml b/config/locales/crowdin/js-da.yml index 40875955062..e4b985dba20 100644 --- a/config/locales/crowdin/js-da.yml +++ b/config/locales/crowdin/js-da.yml @@ -1045,16 +1045,13 @@ da: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-de.yml b/config/locales/crowdin/js-de.yml index 57b3d76dde2..5d240541200 100644 --- a/config/locales/crowdin/js-de.yml +++ b/config/locales/crowdin/js-de.yml @@ -1047,16 +1047,13 @@ de: all: Alle Projekte selected: Nur ausgewählte search_placeholder: Projekte durchsuchen... - search_placeholder_favorites: Favoriten durchsuchen... include_subprojects: Alle Unterprojekte einbeziehen tooltip: include_all_selected: Das Projekt ist bereits enthalten, da alle Unterprojekte einbezogen sind. current_project: Dies ist das aktuelle Projekt, in dem Sie sich befinden. does_not_match_search: Projekt entspricht nicht den Suchkriterien. no_results: Kein Projekt entspricht Ihren Suchkriterien. - no_favorite_results: Kein favorisiertes Projekt entspricht Ihren Suchkriterien. include_workspaces: - search_placeholder: Suchen... types: program: Programm portfolio: Portfolio diff --git a/config/locales/crowdin/js-el.yml b/config/locales/crowdin/js-el.yml index 062a6b2f1bb..aed5bee410a 100644 --- a/config/locales/crowdin/js-el.yml +++ b/config/locales/crowdin/js-el.yml @@ -1045,16 +1045,13 @@ el: all: Όλα τα έργα selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-eo.yml b/config/locales/crowdin/js-eo.yml index 83e7d94d518..5b1b626fe46 100644 --- a/config/locales/crowdin/js-eo.yml +++ b/config/locales/crowdin/js-eo.yml @@ -1045,16 +1045,13 @@ eo: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-es.yml b/config/locales/crowdin/js-es.yml index 0308f4cf8e7..b1b9acf29f1 100644 --- a/config/locales/crowdin/js-es.yml +++ b/config/locales/crowdin/js-es.yml @@ -1043,16 +1043,13 @@ es: all: Todos los proyectos selected: Solo seleccionados search_placeholder: Buscar proyectos... - search_placeholder_favorites: Buscar favoritos... include_subprojects: Incluir todos los subproyectos tooltip: include_all_selected: Proyecto ya incluido, ya que "Incluir todos los subproyectos" está activada. current_project: Este es el proyecto actual. does_not_match_search: El proyecto no coincide con los criterios de búsqueda. no_results: Ningún producto coincide con tu criterio de búsqueda - no_favorite_results: Ningún proyecto favorito coincide con sus criterios de búsqueda. include_workspaces: - search_placeholder: Buscar… types: program: Programa portfolio: Cartera diff --git a/config/locales/crowdin/js-et.yml b/config/locales/crowdin/js-et.yml index 5e9b5c80811..016a5346156 100644 --- a/config/locales/crowdin/js-et.yml +++ b/config/locales/crowdin/js-et.yml @@ -1045,16 +1045,13 @@ et: all: Kõik projektid selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-eu.yml b/config/locales/crowdin/js-eu.yml index a73d5ea0df0..aeff6a9f655 100644 --- a/config/locales/crowdin/js-eu.yml +++ b/config/locales/crowdin/js-eu.yml @@ -1045,16 +1045,13 @@ eu: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-fa.yml b/config/locales/crowdin/js-fa.yml index ce6e219c1b4..06ef0e48f7d 100644 --- a/config/locales/crowdin/js-fa.yml +++ b/config/locales/crowdin/js-fa.yml @@ -1045,16 +1045,13 @@ fa: all: همه پروژه‌ها selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-fi.yml b/config/locales/crowdin/js-fi.yml index 0b9f4e39015..d9998e17719 100644 --- a/config/locales/crowdin/js-fi.yml +++ b/config/locales/crowdin/js-fi.yml @@ -1045,16 +1045,13 @@ fi: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-fil.yml b/config/locales/crowdin/js-fil.yml index 4763736396d..15ab2ac20e9 100644 --- a/config/locales/crowdin/js-fil.yml +++ b/config/locales/crowdin/js-fil.yml @@ -1045,16 +1045,13 @@ fil: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-fr.yml b/config/locales/crowdin/js-fr.yml index 57906649c56..e00a7c4837d 100644 --- a/config/locales/crowdin/js-fr.yml +++ b/config/locales/crowdin/js-fr.yml @@ -1045,16 +1045,13 @@ fr: all: Tous les projets selected: Uniquement la sélection search_placeholder: Recherche de projets... - search_placeholder_favorites: Recherche de favoris... include_subprojects: inclure tous les sous-projets tooltip: include_all_selected: Projet déjà inclus puisque Include tous les sous-projets sont activés. current_project: Ceci est le projet dans lequel vous vous trouvez actuellement. does_not_match_search: Le projet ne correspond pas aux critères de recherche. no_results: Aucun projet ne correspond à vos critères de recherche. - no_favorite_results: Aucun projet favori ne correspond à vos critères de recherche. include_workspaces: - search_placeholder: Rechercher... types: program: Programme portfolio: Portefeuille diff --git a/config/locales/crowdin/js-he.yml b/config/locales/crowdin/js-he.yml index fcc1fa5b5b2..daa000539dd 100644 --- a/config/locales/crowdin/js-he.yml +++ b/config/locales/crowdin/js-he.yml @@ -1053,16 +1053,13 @@ he: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-hi.yml b/config/locales/crowdin/js-hi.yml index 41abb4824f1..fa72e3876c3 100644 --- a/config/locales/crowdin/js-hi.yml +++ b/config/locales/crowdin/js-hi.yml @@ -1045,16 +1045,13 @@ hi: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-hr.yml b/config/locales/crowdin/js-hr.yml index 2bb6ea97065..c13e059f768 100644 --- a/config/locales/crowdin/js-hr.yml +++ b/config/locales/crowdin/js-hr.yml @@ -1049,16 +1049,13 @@ hr: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-hu.yml b/config/locales/crowdin/js-hu.yml index 1df25f173f9..0173a0b88bc 100644 --- a/config/locales/crowdin/js-hu.yml +++ b/config/locales/crowdin/js-hu.yml @@ -1087,16 +1087,13 @@ hu: all: Minden projekt selected: Csak a kijelölt search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Összes alprojekt bevonása tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: Ez a jelenlegi projekt, amiben vagyunk. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-hy.yml b/config/locales/crowdin/js-hy.yml index 541f2ba4634..988e4acb589 100644 --- a/config/locales/crowdin/js-hy.yml +++ b/config/locales/crowdin/js-hy.yml @@ -1045,16 +1045,13 @@ hy: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-id.yml b/config/locales/crowdin/js-id.yml index c0cb9375ff0..a23fab7b403 100644 --- a/config/locales/crowdin/js-id.yml +++ b/config/locales/crowdin/js-id.yml @@ -1041,16 +1041,13 @@ id: all: Semua proyek selected: Only selected search_placeholder: Cari proyek... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-it.yml b/config/locales/crowdin/js-it.yml index 44392815e7f..8fa03fc0c34 100644 --- a/config/locales/crowdin/js-it.yml +++ b/config/locales/crowdin/js-it.yml @@ -1045,16 +1045,13 @@ it: all: Tutti i progetti selected: Solo selezionati search_placeholder: Cerca progetti... - search_placeholder_favorites: Cerca tra i preferiti... include_subprojects: Includi tutti i sotto-progetti tooltip: include_all_selected: Il progetto già stato incluso poiché è abilitata l'opzione Includi tutti i sotto-progetti. current_project: Questo è il progetto corrente in cui ti trovi. does_not_match_search: Il progetto non corrisponde ai criteri di ricerca. no_results: Nessun progetto corrisponde ai tuoi criteri di ricerca - no_favorite_results: Nessun progetto preferito corrisponde ai tuoi criteri di ricerca. include_workspaces: - search_placeholder: Cerca... types: program: Programma portfolio: Portfolio diff --git a/config/locales/crowdin/js-ja.yml b/config/locales/crowdin/js-ja.yml index 617bb4fd770..5bcd96f7a7a 100644 --- a/config/locales/crowdin/js-ja.yml +++ b/config/locales/crowdin/js-ja.yml @@ -1041,16 +1041,13 @@ ja: all: すべてのプロジェクト selected: 選択したもののみ search_placeholder: プロジェクトを検索… - search_placeholder_favorites: Search favorites... include_subprojects: すべての子プロジェクトを含む tooltip: include_all_selected: すべての子プロジェクトを含める」が有効になっているため、プロジェクトはすでに含まれている。 current_project: これが現在あなたが参加しているプロジェクトです。 does_not_match_search: プロジェクトが検索条件に一致しません。 no_results: 検索条件に一致するプロジェクトはありません。 - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ka.yml b/config/locales/crowdin/js-ka.yml index 92414a02439..928696072fc 100644 --- a/config/locales/crowdin/js-ka.yml +++ b/config/locales/crowdin/js-ka.yml @@ -1045,16 +1045,13 @@ ka: all: ყველა პროექტი selected: მხოლოდ მონიშნული search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-kk.yml b/config/locales/crowdin/js-kk.yml index 6f4d65d8003..e71172d8d76 100644 --- a/config/locales/crowdin/js-kk.yml +++ b/config/locales/crowdin/js-kk.yml @@ -1045,16 +1045,13 @@ kk: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ko.yml b/config/locales/crowdin/js-ko.yml index b4b34070827..29b20d7bb18 100644 --- a/config/locales/crowdin/js-ko.yml +++ b/config/locales/crowdin/js-ko.yml @@ -1041,16 +1041,13 @@ ko: all: 모든 프로젝트 selected: 선택한 항목만 search_placeholder: 프로젝트 검색... - search_placeholder_favorites: 즐겨찾기 검색... include_subprojects: 모든 하위 프로젝트 포함 tooltip: include_all_selected: "'모든 하위 프로젝트 포함'이 활성화되어 있으므로 프로젝트가 이미 포함되어 있습니다." current_project: 작업 중인 현재 프로젝트입니다. does_not_match_search: 프로젝트가 검색 기준과 일치하지 않습니다. no_results: 검색 기준과 일치하는 프로젝트가 없습니다. - no_favorite_results: 검색 기준과 일치하는 프로젝트 즐겨찾기가 없습니다. include_workspaces: - search_placeholder: 검색... types: program: 프로그램 portfolio: 포트폴리오 diff --git a/config/locales/crowdin/js-lt.yml b/config/locales/crowdin/js-lt.yml index bcb1f979a73..56ff8424376 100644 --- a/config/locales/crowdin/js-lt.yml +++ b/config/locales/crowdin/js-lt.yml @@ -1053,16 +1053,13 @@ lt: all: Visi projektai selected: Tik pasirinktus search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Įtraukti visus sub-projektus tooltip: include_all_selected: Projektas jau įtrauktas, nes įjungta parinktis įtraukti visus sub-projektus. current_project: Tai dabartinis projektas, kuriame jūs esate. does_not_match_search: Projektas neatitinka paieškos kriterijaus. no_results: Nei vienas projektas neatitinka jūsų paieškos kriterijaus. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-lv.yml b/config/locales/crowdin/js-lv.yml index 7ffc20e177b..072e956c76b 100644 --- a/config/locales/crowdin/js-lv.yml +++ b/config/locales/crowdin/js-lv.yml @@ -1049,16 +1049,13 @@ lv: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-mn.yml b/config/locales/crowdin/js-mn.yml index 2f810420bcc..b65505d6d58 100644 --- a/config/locales/crowdin/js-mn.yml +++ b/config/locales/crowdin/js-mn.yml @@ -1045,16 +1045,13 @@ mn: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml index 7db1ebdef63..4c2c6502a02 100644 --- a/config/locales/crowdin/js-ms.yml +++ b/config/locales/crowdin/js-ms.yml @@ -1041,16 +1041,13 @@ ms: all: Semua projek selected: Hanya terpilih search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Termasuk semua sub-projek tooltip: include_all_selected: Projek sudah disertakan sejak Sertakan semua sub-projek didayakan. current_project: Ini adalah projek yang anda terlibat dalam sekarang. does_not_match_search: Projek tidak sepadan dengan kriteria carian. no_results: Tiada projek yang sepadan dengan kriteria carian anda. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ne.yml b/config/locales/crowdin/js-ne.yml index c92b11dfeab..cd5f8d3808e 100644 --- a/config/locales/crowdin/js-ne.yml +++ b/config/locales/crowdin/js-ne.yml @@ -1045,16 +1045,13 @@ ne: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-nl.yml b/config/locales/crowdin/js-nl.yml index 43025229479..eaba6e5f537 100644 --- a/config/locales/crowdin/js-nl.yml +++ b/config/locales/crowdin/js-nl.yml @@ -1045,16 +1045,13 @@ nl: all: Alle projecten selected: Alleen geselecteerd search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Inclusief alle sub-projecten tooltip: include_all_selected: Project al opgenomen omdat alle subprojecten zijn ingeschakeld. current_project: Dit is het huidige project waarin u zich bevindt. does_not_match_search: Het project komt niet overeen met de zoekcriteria. no_results: Geen enkel project komt overeen met uw zoekcriteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml index 063d0be6710..1341e0f51bf 100644 --- a/config/locales/crowdin/js-no.yml +++ b/config/locales/crowdin/js-no.yml @@ -1045,16 +1045,13 @@ all: Alle prosjekter selected: Kun valgte search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Inkluder alle underprosjekter tooltip: include_all_selected: Prosjektet er allerede inkludert siden det alle underprosjekter er aktivert. current_project: Dette er det nåværende prosjektet du er i. does_not_match_search: Prosjektet samsvarer ikke med søkekriteriene. no_results: Ingen treff på dine søkekriterier. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-pl.yml b/config/locales/crowdin/js-pl.yml index 5e3db337ec0..d05ff916750 100644 --- a/config/locales/crowdin/js-pl.yml +++ b/config/locales/crowdin/js-pl.yml @@ -1053,16 +1053,13 @@ pl: all: Wszystkie projekty selected: Tylko zaznaczone search_placeholder: Wyszukaj projekty... - search_placeholder_favorites: Wyszukaj ulubione... include_subprojects: Uwzględnij wszystkie podprojekty tooltip: include_all_selected: Projekt już uwzględniony, ponieważ włączenie wszystkich podprojektów jest włączone. current_project: To jest bieżący projekt, w którym jesteś. does_not_match_search: Projekt nie spełnia kryteriów wyszukiwania. no_results: Żaden projekt nie spełnia kryteriów wyszukiwania. - no_favorite_results: Żaden ulubiony projekt nie spełnia kryteriów wyszukiwania. include_workspaces: - search_placeholder: Wyszukaj... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-pt-BR.yml b/config/locales/crowdin/js-pt-BR.yml index 116fe8bae04..31d0bf2f31e 100644 --- a/config/locales/crowdin/js-pt-BR.yml +++ b/config/locales/crowdin/js-pt-BR.yml @@ -1045,16 +1045,13 @@ pt-BR: all: Todos os projetos selected: Somente selecionados search_placeholder: Buscar projetos... - search_placeholder_favorites: Pesquisar favoritos... include_subprojects: Incluir todos os subprojetos tooltip: include_all_selected: Como a opção Incluir todos os sub-projetos está habilitada, o projeto já foi incluído. current_project: Este é o projeto atual em que você está. does_not_match_search: O projeto não corresponde ao critério de pesquisa no_results: Nenhum projeto corresponde ao seu critério de busca. - no_favorite_results: Nenhum projeto favorito corresponde aos seus critérios de busca. include_workspaces: - search_placeholder: Pesquisar... types: program: Programa portfolio: Portfólio diff --git a/config/locales/crowdin/js-pt-PT.yml b/config/locales/crowdin/js-pt-PT.yml index bb7ba35f39d..e79ad0ce3ed 100644 --- a/config/locales/crowdin/js-pt-PT.yml +++ b/config/locales/crowdin/js-pt-PT.yml @@ -1045,16 +1045,13 @@ pt-PT: all: Todos os projetos selected: Apenas os selecionados search_placeholder: Procurar projetos... - search_placeholder_favorites: Procurar favoritos... include_subprojects: Incluir todos os subprojetos tooltip: include_all_selected: Projeto já incluído porque todos os subprojetos estão ativados. current_project: Este é o projeto atual em que está. does_not_match_search: O projeto não corresponde aos critérios de pesquisa. no_results: Nenhum projeto corresponde aos seus critérios de pesquisa. - no_favorite_results: Nenhum projeto favorito corresponde aos seus critérios de pesquisa. include_workspaces: - search_placeholder: Pesquisar... types: program: Programa portfolio: Carteira diff --git a/config/locales/crowdin/js-ro.yml b/config/locales/crowdin/js-ro.yml index 2d997ab634f..e6a521ca06d 100644 --- a/config/locales/crowdin/js-ro.yml +++ b/config/locales/crowdin/js-ro.yml @@ -1049,16 +1049,13 @@ ro: all: Toate Proiectele selected: Numai selecția search_placeholder: Caută proiecte... - search_placeholder_favorites: Caută favorite... include_subprojects: Include toate subproiectele tooltip: include_all_selected: Proiectul este deja inclus, din moment ce opțiunea Include toate subproiectele este activată. current_project: Acesta este proiectul curent în care vă aflați. does_not_match_search: Proiectul nu corespunde criteriilor de căutare. no_results: Niciun proiect nu corespunde criteriilor de căutare. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml index 6fbb81dc9a1..bff82cf6790 100644 --- a/config/locales/crowdin/js-ru.yml +++ b/config/locales/crowdin/js-ru.yml @@ -1055,16 +1055,13 @@ ru: all: Все проекты selected: Только выбранные search_placeholder: Поиск проектов... - search_placeholder_favorites: Поиск в избранном... include_subprojects: Включить все подпроекты tooltip: include_all_selected: Проект уже включен, поскольку разрешено включение всех подпроектов. current_project: Это текущий проект, в котором вы находитесь. does_not_match_search: Ни один проект не соответствует критериям поиска. no_results: Ни один проект не соответствует критериям поиска. - no_favorite_results: Ни один избранный проект не соответствует критериям поиска. include_workspaces: - search_placeholder: Поиск... types: program: Программа portfolio: Портфолио diff --git a/config/locales/crowdin/js-rw.yml b/config/locales/crowdin/js-rw.yml index a2594894b22..41882fae9cf 100644 --- a/config/locales/crowdin/js-rw.yml +++ b/config/locales/crowdin/js-rw.yml @@ -1045,16 +1045,13 @@ rw: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-si.yml b/config/locales/crowdin/js-si.yml index dc9e6c2fd0e..660e6115c86 100644 --- a/config/locales/crowdin/js-si.yml +++ b/config/locales/crowdin/js-si.yml @@ -1045,16 +1045,13 @@ si: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-sk.yml b/config/locales/crowdin/js-sk.yml index d365d9e7cbc..8bdb21d9e17 100644 --- a/config/locales/crowdin/js-sk.yml +++ b/config/locales/crowdin/js-sk.yml @@ -1053,16 +1053,13 @@ sk: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-sl.yml b/config/locales/crowdin/js-sl.yml index 9a0ef6f0851..b1fd06e2610 100644 --- a/config/locales/crowdin/js-sl.yml +++ b/config/locales/crowdin/js-sl.yml @@ -1071,16 +1071,13 @@ sl: all: Vsi projekti selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-sr.yml b/config/locales/crowdin/js-sr.yml index 810e923470d..a75ec3dac15 100644 --- a/config/locales/crowdin/js-sr.yml +++ b/config/locales/crowdin/js-sr.yml @@ -1049,16 +1049,13 @@ sr: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-sv.yml b/config/locales/crowdin/js-sv.yml index 1879a829834..9822b62bc97 100644 --- a/config/locales/crowdin/js-sv.yml +++ b/config/locales/crowdin/js-sv.yml @@ -1045,16 +1045,13 @@ sv: all: Alla projekt selected: Only selected search_placeholder: Sök projekt... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Projekt som redan ingår sedan Inkludera alla delprojekt är aktiverat. current_project: Detta är det aktuella projektet du befinner dig i. does_not_match_search: Projektet matchar inte sökkriterierna. no_results: Inget projekt matchar dina sökkriterier. - no_favorite_results: Inget favoritprojekt matchar dina sökkriterier. include_workspaces: - search_placeholder: Sök... types: program: Program portfolio: Portfölj diff --git a/config/locales/crowdin/js-th.yml b/config/locales/crowdin/js-th.yml index 4a8d537293e..fea2483c3b3 100644 --- a/config/locales/crowdin/js-th.yml +++ b/config/locales/crowdin/js-th.yml @@ -1041,16 +1041,13 @@ th: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-tr.yml b/config/locales/crowdin/js-tr.yml index 1dec81a6398..ea663176b15 100644 --- a/config/locales/crowdin/js-tr.yml +++ b/config/locales/crowdin/js-tr.yml @@ -1045,16 +1045,13 @@ tr: all: Tüm projeler selected: Sadece seçilen search_placeholder: Projeleri ara... - search_placeholder_favorites: Favorileri ara... include_subprojects: Tüm alt projeleri dahil et tooltip: include_all_selected: Tüm alt projeleri dahil et etkinleştirildiğinden, proje zaten dahil edilmiştir. current_project: Bu, içinde bulunduğunuz mevcut projedir. does_not_match_search: Proje arama kriterleriyle eşleşmiyor. no_results: Arama kriterleriniz ile eşleşen proje yok - no_favorite_results: Arama kriterleriniz ile eşleşen favori proje yok. include_workspaces: - search_placeholder: Arama... types: program: Program portfolio: Portföy diff --git a/config/locales/crowdin/js-uk.yml b/config/locales/crowdin/js-uk.yml index d51448dafb7..95b6846bf9e 100644 --- a/config/locales/crowdin/js-uk.yml +++ b/config/locales/crowdin/js-uk.yml @@ -1053,16 +1053,13 @@ uk: all: Усі проєкти selected: Тільки вибране search_placeholder: Пошук проєктів… - search_placeholder_favorites: Пошук серед вибраного… include_subprojects: Включити всі підпроєкти tooltip: include_all_selected: Проєкт уже включено, оскільки ввімкнено параметр «Включати всі вкладені проєкти». current_project: Це поточний проєкт, який зараз відкрито. does_not_match_search: Проєкт не відповідає критеріям пошуку. no_results: Жоден проєкт не відповідає вашим критеріям пошуку. - no_favorite_results: Немає вибраних проєктів, які відповідають критеріям пошуку. include_workspaces: - search_placeholder: Пошук… types: program: Програма portfolio: Портфель diff --git a/config/locales/crowdin/js-uz.yml b/config/locales/crowdin/js-uz.yml index cad7dde0a08..ac3714d80b5 100644 --- a/config/locales/crowdin/js-uz.yml +++ b/config/locales/crowdin/js-uz.yml @@ -1045,16 +1045,13 @@ uz: all: All projects selected: Only selected search_placeholder: Search projects... - search_placeholder_favorites: Search favorites... include_subprojects: Include all sub-projects tooltip: include_all_selected: Project already included since Include all sub-projects is enabled. current_project: This is the current project you are in. does_not_match_search: Project does not match the search criteria. no_results: No project matches your search criteria. - no_favorite_results: No favorite project matches your search criteria. include_workspaces: - search_placeholder: Search... types: program: Program portfolio: Portfolio diff --git a/config/locales/crowdin/js-vi.yml b/config/locales/crowdin/js-vi.yml index 4c2cff2803d..f6003009978 100644 --- a/config/locales/crowdin/js-vi.yml +++ b/config/locales/crowdin/js-vi.yml @@ -1041,16 +1041,13 @@ vi: all: Tất cả dự án selected: Chỉ được chọn search_placeholder: Tìm kiếm dự án... - search_placeholder_favorites: Tìm kiếm yêu thích... include_subprojects: Bao gồm tất cả các tiểu dự án tooltip: include_all_selected: Dự án đã được đưa vào kể từ khi tính năng Bao gồm tất cả các dự án con được bật. current_project: Đây là dự án hiện tại bạn đang tham gia. does_not_match_search: Dự án không phù hợp với tiêu chí tìm kiếm. no_results: Không có dự án nào phù hợp với tiêu chí tìm kiếm của bạn. - no_favorite_results: Không có dự án yêu thích nào phù hợp với tiêu chí tìm kiếm của bạn. include_workspaces: - search_placeholder: Tìm kiếm... types: program: chương trình portfolio: danh mục đầu tư diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml index 9cb486d1314..1dfc6960dee 100644 --- a/config/locales/crowdin/js-zh-CN.yml +++ b/config/locales/crowdin/js-zh-CN.yml @@ -1041,16 +1041,13 @@ zh-CN: all: 所有项目 selected: 仅限所选 search_placeholder: 搜索项目… - search_placeholder_favorites: 搜索收藏夹… include_subprojects: 包含所有子项目 tooltip: include_all_selected: 自启用“包含所有子项目”后已包含的项目。 current_project: 这是您当前所在的项目。 does_not_match_search: 项目不符合搜索条件。 no_results: 没有项目符合您的搜索条件。 - no_favorite_results: 没有收藏的项目符合您的搜索条件。 include_workspaces: - search_placeholder: 搜索… types: program: 项目群 portfolio: 项目组合 diff --git a/config/locales/crowdin/js-zh-TW.yml b/config/locales/crowdin/js-zh-TW.yml index c774aaa6bd0..43c2168e54e 100644 --- a/config/locales/crowdin/js-zh-TW.yml +++ b/config/locales/crowdin/js-zh-TW.yml @@ -1041,16 +1041,13 @@ zh-TW: all: 所有專案 selected: 僅所選專案 search_placeholder: 搜尋專案... - search_placeholder_favorites: 搜尋我的收藏... include_subprojects: 包含子專案 tooltip: include_all_selected: 自啓用“包含所有子項目”後已包含的項目。 current_project: 這是您當前所在的專案。 does_not_match_search: 沒有符合搜尋條件 no_results: 沒有符合搜尋條件 - no_favorite_results: 沒有符合您搜尋條件的收藏專案。 include_workspaces: - search_placeholder: 搜尋…… types: program: 方案 portfolio: 專案組合 diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml index f4633b16363..b6a0f07429d 100644 --- a/config/locales/crowdin/ka.yml +++ b/config/locales/crowdin/ka.yml @@ -2107,17 +2107,14 @@ ka: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ ka: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: არასწორია. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: კენტი უნდა იყოს. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ ka: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ ka: button_login: შესვლა button_move: გადატანა button_move_and_follow: Move and follow + button_next: Next button_print: ბეჭდვა button_quote: ციტატა button_remove: წაშლა @@ -3475,6 +3476,12 @@ ka: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ ka: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: გუშინ label_zen_mode: Zen mode label_role_type: ტიპი diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml index 536515a600c..321648be5af 100644 --- a/config/locales/crowdin/kk.yml +++ b/config/locales/crowdin/kk.yml @@ -2107,17 +2107,14 @@ kk: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ kk: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ kk: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ kk: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ kk: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ kk: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml index 9fbaa047b9f..da27fe2eb38 100644 --- a/config/locales/crowdin/ko.yml +++ b/config/locales/crowdin/ko.yml @@ -2084,17 +2084,14 @@ ko: before: 은(는) %{date} 보다 전이어야 합니다. before_or_equal_to: 은(는) %{date} 이전이어야 합니다. blank: 내용을 입력해주세요 - not_before_start_date: "- 시작 날짜 전이 아니어야 합니다." - overlapping_range: "- 기존 휴무일 범위와 겹칩니다." blank_nested: "- '%{property}' 속성이 설정되어 있어야 합니다." cannot_delete_mapping: "- 필수입니다. 삭제할 수 없습니다." - is_for_all_cannot_modify: "- 모든 프로젝트용므로 수정할 수 없습니다." cant_link_a_work_package_with_a_descendant: 작업 패키지는 하위 작업패키지들 중 하나에 연결 될 수 없습니다. circular_dependency: 이 연계는 순환 종속관계를 만듭니다. confirmation: "%{attribute} 속성에 부합하지 않습니다." could_not_be_copied: "%{dependency}을(를) (완전히) 복사할 수 없습니다." + datetime_must_be_in_future: "- 미래여야 합니다." does_not_exist: 존재하지 않음 - user_already_in_department: "%{user_id} 사용자는 이미 %{department_id} 부서의 멤버입니다." error_enterprise_only: "%{action}은(는) OpenProject Enterprise Edition에서만 사용할 수 있습니다." error_unauthorized: 액세스하지 못할 수 있습니다. error_readonly: "- 쓰려고 했지만 쓸 수 없습니다." @@ -2115,36 +2112,38 @@ ko: greater_than_or_equal_to: 은(는) %{count}보다 크거야 같아야 합니다 greater_than_or_equal_to_start_date: 은(는) 시작 날짜 이후이거나 같아야 합니다. greater_than_start_date: 은(는) 시작 날짜 이후이어야 합니다. + hexcode_invalid: "- 유효한 6자리 16진수 색상 코드가 아닙니다." inclusion: 은(는) 허용되는 값이 아닙니다. inclusion_nested: "- 경로 '%{path}'에서 허용되는 값 중 하나로 설정되지 않았습니다." invalid: 은(는) 올바르지 않은 값입니다 invalid_uri: "- 유효한 URI여야 합니다." invalid_url: 은(는) 올바른 URL이 아닙니다. invalid_url_scheme: '은(는) 지원되는 프로토콜(허용: %{allowed_schemes})이 아닙니다.' + is_for_all_cannot_modify: "- 모든 프로젝트용므로 수정할 수 없습니다." less_than_or_equal_to: 은(는) %{count} 보다 작거나 같아야 합니다 not_available: "- 시스템 구성으로 인해 사용 가능하지 않습니다." + not_before_start_date: "- 시작 날짜 전이 아니어야 합니다." not_deletable: "- 삭제할 수 없습니다." not_editable: "- 이미 적용 중이므로 편집할 수 없습니다." not_current_user: 은(는) 현재 유효한 사용자가 아닙니다. - system_wide_non_working_day_exists: "- 이 날짜의 기존 시스템 전체 휴무일과 충돌합니다." not_found: "- 찾을 수 없습니다." not_a_date: 은(는) 유효한 날짜가 아닙니다. not_a_datetime: 은(는) 유효한 날짜가 아닙니다. not_a_number: 은(는) 숫자가 아닙니다. not_allowed: "- 사용 권한이 없어 유효하지 않습니다." - host_not_allowed: "- 허용되는 호스트가 아닙니다." not_json: "- JSON으로 구문 분석할 수 없습니다." not_json_object: "- JSON 개체가 아닙니다." not_an_integer: 은(는) 정수가 아닙니다. not_an_iso_date: '은(는) 유효한 날짜가 아닙니다. 필요한 형식: YYYY-MM-DD.' not_same_project: 은(는) 동일한 프로젝트에 속하지 않습니다. - datetime_must_be_in_future: "- 미래여야 합니다." odd: 에 홀수를 입력해 주세요 + overlapping_range: "- 기존 휴무일 범위와 겹칩니다." regex_match_failed: "%{expression} 정규 표현식과 일치하지 않습니다." regex_invalid: 관련 정규 표현식으로 유효성을 확인할 수 없습니다. regex_list_invalid: "%{invalid_lines} 라인을 정규 표현식으로 구문 분석할 수 없습니다." - hexcode_invalid: "- 유효한 6자리 16진수 색상 코드가 아닙니다." smaller_than_or_equal_to_max_length: 은(는) 최대 길이보다 같거나 작아야 합니다. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: "- 이 날짜의 기존 시스템 전체 휴무일과 충돌합니다." taken: 은(는) 이미 존재합니다. too_long: 은(는) 너무 깁니다 (최대 %{count}자까지 가능합니다) too_short: 은(는) 너무 짧습니다. (최소 %{count} 자 이상이어야 합니다) @@ -2157,6 +2156,7 @@ ko: url_not_secure_context: '"보안 컨텍스트"를 제공하지 않습니다. HTTPS 또는 localhost 같은 루프백 주소를 사용하세요. ' + user_already_in_department: "%{user_id} 사용자는 이미 %{department_id} 부서의 멤버입니다." wrong_length: 너무 짧습니다 (최소 %{count} 자 이상이어야 합니다). models: group: @@ -2801,6 +2801,7 @@ ko: button_login: 로그인 button_move: 이동 button_move_and_follow: 이동하고 따라가기 + button_next: 다음 button_print: 인쇄 button_quote: 인용 button_remove: 제거 @@ -3429,6 +3430,12 @@ ko: selected: 선택됨 include_sub_items: 하위 항목 포함 no_results_text: 결과 없음 + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 켜기 label_off: 끄기 @@ -4474,6 +4481,8 @@ ko: other: 근무일 %{count}일 label_x_working_days_time_off: other: '휴가: 근무일 %{count}일' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: 어제 label_zen_mode: 젠 모드 label_role_type: 유형 diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml index b62e955f605..468d202a4dd 100644 --- a/config/locales/crowdin/lt.yml +++ b/config/locales/crowdin/lt.yml @@ -2148,17 +2148,14 @@ lt: before: turi eiti prieš %{date}. before_or_equal_to: turi eiti prieš arba būti lygu %{date}. blank: negali būti tuščia. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: reikalauja, kad savybė '%{property}' būtų nustatyta. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Darbų paketas negali būti susietas su viena iš savo vidinių užduočių. circular_dependency: Šis ryšys sukurtų ciklinę priklausomybę. confirmation: nesutampa su %{attribute}. could_not_be_copied: "%{dependency} negali (pilnai) būti nukopijuota(s)." + datetime_must_be_in_future: must be in the future. does_not_exist: neegzistuoja. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: negali būti pasiektas. error_readonly: bandytas įrašyti, bet įrašyti nebuvo galima. @@ -2179,36 +2176,38 @@ lt: greater_than_or_equal_to: turi būti didesnis arba lygus %{count}. greater_than_or_equal_to_start_date: turi būti didesnis arba lygus už pradžios datą. greater_than_start_date: turi būti didesnis už pradžios datą. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nenustatyta kaip viena iš leidžiamų reikšmių. inclusion_nested: nėra nustatytas į vieną iš leidžiamų reikšmių kelyje „%{path}“. invalid: " neteisingas." invalid_uri: must be a valid URI. invalid_url: nėra tinkamas URL. invalid_url_scheme: 'nėra palaikomos protokolas (leidžiamas: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: turi būti mažesnis arba lygus %{count}. not_available: yra nepasiekiamas dėl sistemos konfigūracijos + not_before_start_date: must not be before the start date. not_deletable: negali būti pašalintas. not_editable: cannot be edited because it is already in effect. not_current_user: nėra dabartinis naudotojas - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: nėra tinkama data. not_a_datetime: nėra tinkama data ir laikas. not_a_number: nėra skaičius. not_allowed: netinkamas dėl trūkstamų teisių. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: nėra sveikasis skaičius. not_an_iso_date: 'nėra tinkama data. Reikalingas formatas: YYYY-MM-DD.' not_same_project: nepriklauso tam pačiam projektui. - datetime_must_be_in_future: must be in the future. odd: turi būti nelyginis. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: neatitinka reguliariosios išraiškos %{expression}. regex_invalid: negalėjo būti patvirtintas su susieta reguliaria išraiška. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: turi būti mažesnis arba lygus didžiausiam ilgiui. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: jau užimtas. too_long: yra per ilgas (daugiausiai galima %{count} simbolių). too_short: yra per trumpas (mažiausiai %{count} simbolių). @@ -2221,6 +2220,7 @@ lt: url_not_secure_context: 'neteikia „Saugaus konteksto“. Arba naudokite HTTPS, arba atgalinį adresą, tokį kaip localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: yra neteisingo ilgio (turi būti %{count} simbolių). models: group: @@ -2927,6 +2927,7 @@ lt: button_login: Prisijungti button_move: Perkelti button_move_and_follow: Perkelti ir sekti + button_next: Next button_print: Spausdinti button_quote: Cituoti button_remove: Pašalinti @@ -3598,6 +3599,12 @@ lt: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4658,6 +4665,11 @@ lt: few: 'Time off: %{count} working days' many: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: vakar label_zen_mode: "„Zen“ režimas" label_role_type: Tipas diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml index 7459ab0d505..9e35b5395d0 100644 --- a/config/locales/crowdin/lv.yml +++ b/config/locales/crowdin/lv.yml @@ -2128,17 +2128,14 @@ lv: before: jābūt pirms %{date}. before_or_equal_to: jābūt pirms vai vienādam ar %{date}. blank: nevar būt tukšs. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Darbu kompleksu nevar saistīt vienu no tā apakšuzdevumiem. circular_dependency: Šī attiecība radītu riņķveida saistību. confirmation: neatbilst %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: nepastāv. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2159,36 +2156,38 @@ lv: greater_than_or_equal_to: jābūt lielākam vai vienādam ar %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nav iestatīts uz vienu no atļautajām vērtībām. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: nav derīgs. invalid_uri: must be a valid URI. invalid_url: nederīgs URL vietrādis. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: jābūt mazākam vai vienādam ar %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: nav skaitlis. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: nav vesels skaitlis. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: neietilpst vienā un tai pašā projektā. - datetime_must_be_in_future: must be in the future. odd: jābūt nepāra. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: jābūt mazākam vai vienādam ar maksimālo garumu. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: jau tika aizņemts. too_long: ir pārāk garš (maksimums ir %{count} rakstzīmes). too_short: ir pārāk īss (minimums ir %{count} rakstzīmes). @@ -2201,6 +2200,7 @@ lv: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: ir nepareizs garums (vajadzētu būt %{count} rakstzīmes). models: group: @@ -2887,6 +2887,7 @@ lv: button_login: Ienākt button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Drukāt button_quote: Citēt button_remove: Noņemt @@ -3537,6 +3538,12 @@ lv: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4592,6 +4599,10 @@ lv: zero: 'Time off: %{count} working days' one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + zero: "%{count} items selected" + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Veids diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml index 6f832b06c26..482ab1702b2 100644 --- a/config/locales/crowdin/mn.yml +++ b/config/locales/crowdin/mn.yml @@ -2107,17 +2107,14 @@ mn: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ mn: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ mn: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ mn: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ mn: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ mn: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml index 26a8bc6f60b..07e86a4c443 100644 --- a/config/locales/crowdin/ms.yml +++ b/config/locales/crowdin/ms.yml @@ -2086,17 +2086,14 @@ ms: before: mesti sebelum %{date}. before_or_equal_to: mesti sebelum atau sama dengan %{date}. blank: tidak boleh dibiarkan kosong. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: perlu ada ciri-ciri '%{property}' yang ditetapkan. cannot_delete_mapping: diperlukan. Tidak boleh dipadam. - is_for_all_cannot_modify: adalah untuk semua projek dan oleh itu tidak boleh diubah suai. cant_link_a_work_package_with_a_descendant: Pakej kerja tidak boleh dipautkan ke salah satu subtugasnya. circular_dependency: Hubungan ini akan mencipta kebergantungan bulat. confirmation: tidak sepadan dengan %{attribute}. could_not_be_copied: "%{dependency} tidak dapat disalin (sepenuhnya)." + datetime_must_be_in_future: mestilah pada masa hadapan. does_not_exist: tidak wujud. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: tidak boleh diakses. error_readonly: telah cuba untuk menulis tetapi tidak dapat ditulis. @@ -2117,36 +2114,38 @@ ms: greater_than_or_equal_to: perlu lebih besar atau sama dengan %{count}. greater_than_or_equal_to_start_date: perlu lebih besar atau sama dengan tarikh mula. greater_than_start_date: perlu lebih besar dari tarikh mula. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: tidak ditetapkan pada salah satu nilai yang dibenarkan. inclusion_nested: tidak ditetapkan pada salah satu nilai yang dibenarkan pada laluan '%{path}'. invalid: adalah tidak sah. invalid_uri: must be a valid URI. invalid_url: bukan URL yang sah. invalid_url_scheme: 'adalah bukan protokol yang disokong (dibenarkan: %{allowed_schemes}).' + is_for_all_cannot_modify: adalah untuk semua projek dan oleh itu tidak boleh diubah suai. less_than_or_equal_to: perlu kurang daripada atau sama dengan %{count}. not_available: adalah tidak tersedia kerana konfigurasi sistem. + not_before_start_date: must not be before the start date. not_deletable: tidak dapat dipadamkan. not_editable: cannot be edited because it is already in effect. not_current_user: adalah bukan pengguna semasa. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: tidak dijumpai. not_a_date: bukan tarikh yang sah. not_a_datetime: bukan tarikh masa yang sah. not_a_number: bukan nombor. not_allowed: adalah tidak sah kerana kekurangan kebenaran. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: bukan sebuah integer. not_an_iso_date: 'bukan tarikh yang sah. Format yang diperlukan: TTTT-BB-HH.' not_same_project: tidak tergolong dalam projek yang sama. - datetime_must_be_in_future: mestilah pada masa hadapan. odd: mesti ganjil. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: tidak padan dengan ungkapan biasa %{expression}. regex_invalid: tidak dapat disahkan dengan ungkapan biasa yang berkaitan. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: perlu kurang daripada atau sama dengan panjang maksima. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: sudah diguna pakai. too_long: adalah terlalu panjang (maksimum adalah %{count} karakter). too_short: adalah terlalu pendek (minimum adalah %{count} karakter). @@ -2159,6 +2158,7 @@ ms: url_not_secure_context: 'tidak menyediakan "Konteks Selamat". Gunakan antara HTTPS atau alamat gelung-balik, seperti localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: adalah panjang yang salah (sepatutnya %{count} karakter). models: group: @@ -2811,6 +2811,7 @@ ms: button_login: Daftar masuk button_move: Alih button_move_and_follow: Alih dan ikut + button_next: Next button_print: Cetak button_quote: Petikan button_remove: Keluarkan @@ -3421,6 +3422,12 @@ ms: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4470,6 +4477,8 @@ ms: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: semalam label_zen_mode: Mod Zen label_role_type: Jenis diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml index a3b248f8c1f..0581ba0c0c8 100644 --- a/config/locales/crowdin/ne.yml +++ b/config/locales/crowdin/ne.yml @@ -2107,17 +2107,14 @@ ne: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ ne: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ ne: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ ne: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ ne: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ ne: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml index 6911777bb38..b08b2e13e37 100644 --- a/config/locales/crowdin/nl.yml +++ b/config/locales/crowdin/nl.yml @@ -2105,17 +2105,14 @@ nl: before: moet voor %{date} zijn. before_or_equal_to: moet voor of gelijk zijn aan %{date}. blank: mag niet leeg zijn. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: moet de eigenschap '%{property}' ingesteld hebben. cannot_delete_mapping: is vereist. Kan niet worden verwijderd. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Een werkpakket kan niet worden gekoppeld aan een van de bijbehorende subtaken. circular_dependency: Deze relatie zou een circulaire afhankelijkheid creëren. confirmation: komt niet overeen met %{attribute}. could_not_be_copied: "%{dependency} kon niet (volledig) worden gekopieerd." + datetime_must_be_in_future: must be in the future. does_not_exist: bestaat niet. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: geen toegang. error_readonly: werd geprobeerd te schrijven maar is niet schrijfbaar. @@ -2136,36 +2133,38 @@ nl: greater_than_or_equal_to: moet groter dan of gelijk zijn aan %{count}. greater_than_or_equal_to_start_date: moet groter of gelijk zijn aan startdatum. greater_than_start_date: moet groter zijn dan startdatum. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is niet ingesteld op één van de toegestane waarden. inclusion_nested: is niet ingesteld op een van de toegestane waarden op pad '%{path}'. invalid: is ongeldig. invalid_uri: must be a valid URI. invalid_url: is geen geldige URL. invalid_url_scheme: 'is geen ondersteunde protocol (toegestaan: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: moet kleiner zijn dan of gelijk aan %{count}. not_available: is niet beschikbaar vanwege een systeemconfiguratie. + not_before_start_date: must not be before the start date. not_deletable: kan niet worden verwijderd. not_editable: cannot be edited because it is already in effect. not_current_user: is niet de huidige gebruiker. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: niet gevonden. not_a_date: is geen geldige datum. not_a_datetime: is geen geldige datum tijd. not_a_number: is geen getal. not_allowed: is ongeldig vanwege ontbrekende machtigingen. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is niet een geheel getal. not_an_iso_date: 'is geen geldige datum. Vereist formaat: JJJJ-MM-DD.' not_same_project: hoort niet bij hetzelfde project. - datetime_must_be_in_future: must be in the future. odd: moet oneven zijn. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: kon niet worden gevalideerd met de bijbehorende reguliere expressie. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: moet kleiner zijn dan of even groot zijn als de maximale lengte. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: is al in gebruik. too_long: is te lang (maximaal %{count} karakters). too_short: is te kort (minimum is %{count} karakters). @@ -2178,6 +2177,7 @@ nl: url_not_secure_context: 'bevat geen "Secure Context". Gebruik HTTPS of een loopbackadres, zoals localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is de verkeerde lengte (dient %{count} karakters te zijn). models: group: @@ -2842,6 +2842,7 @@ nl: button_login: Aanmelden button_move: Verplaatsen button_move_and_follow: Verplaatsen en volgen + button_next: Next button_print: Afdrukken button_quote: Citeer button_remove: Verwijder @@ -3471,6 +3472,12 @@ nl: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4521,6 +4528,9 @@ nl: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: gisteren label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml index 7dae744b6db..df6edeef588 100644 --- a/config/locales/crowdin/no.yml +++ b/config/locales/crowdin/no.yml @@ -2105,17 +2105,14 @@ before: må være før %{date}. before_or_equal_to: må være før eller lik %{date}. blank: kan ikke være blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: må ha egenskapen '%{property}' aktivert. cannot_delete_mapping: er påkrevd. Kan ikke slettes. - is_for_all_cannot_modify: er for alle prosjekter og kan derfor ikke modifiseres. cant_link_a_work_package_with_a_descendant: En arbeidspakke kan ikke knyttes til en av sine deloppgaver. circular_dependency: En slik relasjon ville lage en sirkulær avhengighet. confirmation: samsvarer ikke med %{attribute}. could_not_be_copied: "%{dependency} kunne ikke kopieres (fullstendig)." + datetime_must_be_in_future: must be in the future. does_not_exist: finnes ikke. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: kan ikke nås error_readonly: ble forsøkt skrevet til, men er skrivebeskyttet @@ -2136,36 +2133,38 @@ greater_than_or_equal_to: 'må være større enn eller lik: %{count}.' greater_than_or_equal_to_start_date: må være lenger frem eller lik startdato. greater_than_start_date: må være lenger frem enn startdato. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: ikke er satt til en av de tillatte verdiene. inclusion_nested: er ikke satt til en av de tillatte verdiene i stien%{path}'. invalid: er ugyldig. invalid_uri: must be a valid URI. invalid_url: er ikke en gyldig URL. invalid_url_scheme: 'er ikke en støttet protokoll (tillatt: %{allowed_schemes}).' + is_for_all_cannot_modify: er for alle prosjekter og kan derfor ikke modifiseres. less_than_or_equal_to: må være mindre enn eller lik %{count}. not_available: er ikke tilgjengelig på grunn av en systemkonfigurasjon. + not_before_start_date: must not be before the start date. not_deletable: kan ikke slettes. not_editable: cannot be edited because it is already in effect. not_current_user: er ikke gjeldende bruker. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: er ikke en gyldig dato. not_a_datetime: er ikke et gyldig tidspunkt for datoen. not_a_number: er ikke et tall. not_allowed: er ugyldig på grunn av manglende tillatelser. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: er ikke et heltall. not_an_iso_date: 'er ikke en gyldig dato. Påkrevd format: ÅÅÅÅ-MM-DD.' not_same_project: hører ikke til samme prosjekt. - datetime_must_be_in_future: must be in the future. odd: må være oddetall. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: samsvarer ikke med det regulære uttrykket %{expression}. regex_invalid: kunne ikke valideres med det tilhørende regulære uttrykket. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: må være mindre enn eller lik maksimumslengden. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: er allerede tatt. too_long: er for lang (maks antall tegn er %{count}). too_short: er for kort (minimum er %{count} tegn). @@ -2178,6 +2177,7 @@ url_not_secure_context: 'Ikke oppgi en "Secure Context". Enten bruk HTTPS eller en loopback address, som localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: har feil lengde (skal være %{count} tegn). models: group: @@ -2844,6 +2844,7 @@ button_login: Logg inn button_move: Flytt button_move_and_follow: Flytt og følg + button_next: Next button_print: Skriv ut button_quote: Sitèr button_remove: Fjern @@ -3473,6 +3474,12 @@ selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4523,6 +4530,9 @@ label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: i går label_zen_mode: Zen-modus label_role_type: Type diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml index 02fc318a8fb..e84d18623dd 100644 --- a/config/locales/crowdin/pl.yml +++ b/config/locales/crowdin/pl.yml @@ -2145,17 +2145,14 @@ pl: before: musi być przed %{date}. before_or_equal_to: musi być przed lub równe %{date}. blank: nie może być puste. - not_before_start_date: nie może być wcześniejsza niż data rozpoczęcia. - overlapping_range: pokrywa się z istniejącym zakresem dni wolnych od pracy. blank_nested: musi mieć ustawioną właściwość '%{property}'. cannot_delete_mapping: jest wymagane. Nie można usunąć. - is_for_all_cannot_modify: dotyczy wszystkich projektów i dlatego nie można zmodyfikować. cant_link_a_work_package_with_a_descendant: Zestaw zadań nie może być powiązany z jego podzadaniami. circular_dependency: Ta relacja może wytworzyć zależność cykliczną. confirmation: nie pasuje do %{attribute}. could_not_be_copied: Nie można było (w pełni) skopiować %{dependency}. + datetime_must_be_in_future: musi przypadać w przyszłości. does_not_exist: nie istnieje. - user_already_in_department: Użytkownik %{user_id} jest już członkiem działu %{department_id}. error_enterprise_only: "%{action} – dostępne tylko w OpenProject Enterprise edition." error_unauthorized: "— nie można uzyskac dostępu." error_readonly: "— podjęto próbę zapisu, ale nie jest zapisywalny." @@ -2176,36 +2173,38 @@ pl: greater_than_or_equal_to: musi być większe niż lub równe %{count}. greater_than_or_equal_to_start_date: musi być późniejsza niż data początku albo równa jej. greater_than_start_date: musi być późniejsza niż data początku. + hexcode_invalid: nie jest prawidłowym 6-cyfrowym szesnastkowym kodem koloru. inclusion: jest niezgodne z jednym z dozwolonych wartości. inclusion_nested: nie jest ustawione na jedną z dozwolonych wartości na ścieżce '%{path}'. invalid: jest nieprawidłowe. invalid_uri: musi być prawidłowym adres URI. invalid_url: nie jest poprawnym adresem URL. invalid_url_scheme: 'nie jest obsługiwanym protokołem (dozwolone: %{allowed_schemes}).' + is_for_all_cannot_modify: dotyczy wszystkich projektów i dlatego nie można zmodyfikować. less_than_or_equal_to: musi być mniejsze niż lub równe %{count}. not_available: jest niedostępne z powodu konfiguracji systemu. + not_before_start_date: nie może być wcześniejsza niż data rozpoczęcia. not_deletable: "— nie można usunąć." not_editable: nie można edytować, ponieważ jest już w użyciu. not_current_user: nie jest bieżącym użytkownikiem. - system_wide_non_working_day_exists: koliduje z istniejącym dniem wolnym od pracy w całym systemie dla tej daty. not_found: nie znaleziono. not_a_date: nie jest poprawną datą. not_a_datetime: nie jest poprawną datą i czasem. not_a_number: nie jest liczbą. not_allowed: jest nieprawidłowy ze względu na brak uprawnień. - host_not_allowed: nie jest dozwolonym hostem. not_json: nie może być analizowany jako kod JSON. not_json_object: nie jest obiektem JSON. not_an_integer: nie jest liczbą całkowitą. not_an_iso_date: 'wprowadzono nieprawidłową datę. Wymagany format: RRRR-MM-DD.' not_same_project: nie należy do tego samego projektu. - datetime_must_be_in_future: musi przypadać w przyszłości. odd: musi być nieparzyste. + overlapping_range: pokrywa się z istniejącym zakresem dni wolnych od pracy. regex_match_failed: nie pasuje do wyrażenia regularnego %{expression}. regex_invalid: nie może być zastosowany z zastosowanym wyrażeniem regularnym. regex_list_invalid: Nie można przeanalizować %{invalid_lines} wierszy jako wyrażenia regularnego. - hexcode_invalid: nie jest prawidłowym 6-cyfrowym szesnastkowym kodem koloru. smaller_than_or_equal_to_max_length: musi być mniejsze niż lub równe z maksymalnej długości. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: koliduje z istniejącym dniem wolnym od pracy w całym systemie dla tej daty. taken: zostały już podjęte. too_long: jest zbyt długi (maksymalnie %{count} znaków). too_short: jest zbyt krótkie (min. %{count} znaków). @@ -2218,6 +2217,7 @@ pl: url_not_secure_context: 'nie zapewnia „bezpiecznego kontekstu”. Użyj protokołu HTTPS albo adresu pętli zwrotnej, takiej jak localhost. ' + user_already_in_department: Użytkownik %{user_id} jest już członkiem działu %{department_id}. wrong_length: ma nieprawidłową długość (powinno mieć %{count} znaków). models: group: @@ -2922,6 +2922,7 @@ pl: button_login: Zaloguj button_move: Przenieś button_move_and_follow: Przenieś i kontynuuj + button_next: Dalej button_print: Drukuj button_quote: Cytat button_remove: Usuń @@ -3591,6 +3592,12 @@ pl: selected: Wybrany include_sub_items: Uwzględnij elementy podrzędne no_results_text: Brak wyników + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Wł. label_off: Wył. @@ -4651,6 +4658,11 @@ pl: few: 'Czas wolny: %{count} dni robocze' many: 'Czas wolny: %{count} dni roboczych' other: 'Czas wolny: %{count} dnia roboczego' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: wczoraj label_zen_mode: Tryb Zen label_role_type: Typ diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml index 426980d544c..9fc6269238b 100644 --- a/config/locales/crowdin/pt-BR.yml +++ b/config/locales/crowdin/pt-BR.yml @@ -2104,17 +2104,14 @@ pt-BR: before: deve ser antes de %{date}. before_or_equal_to: deve ser antes ou igual a %{date}. blank: não pode ficar em branco. - not_before_start_date: não pode ser anterior à data de início. - overlapping_range: sobrepõe-se a um período já existente de dias não úteis. blank_nested: 'precisa ter a propriedade ''%{property}'' definida. ' cannot_delete_mapping: é obrigatório. Não pode ser excluído. - is_for_all_cannot_modify: é aplicável a todos os projetos e, portanto, não pode ser modificado. cant_link_a_work_package_with_a_descendant: Um pacote de trabalho não pode ser vinculado a uma das suas subtarefas. circular_dependency: Esta relação vai criar uma dependência circular. confirmation: não coincide com %{attribute}. could_not_be_copied: "%{dependency} não pôde ser copiado (completamente)." + datetime_must_be_in_future: deve ser no futuro. does_not_exist: não existe. - user_already_in_department: Usuário %{user_id} já é membro do departamento %{department_id}. error_enterprise_only: "%{action} só está disponível na edição OpenProject Enterprise." error_unauthorized: não pode ser acessado. error_readonly: tentou escrever, mas não é gravável. @@ -2135,36 +2132,38 @@ pt-BR: greater_than_or_equal_to: deve ser maior ou igual a %{count}. greater_than_or_equal_to_start_date: deve ser maior ou igual a data de início. greater_than_start_date: deve ser maior que a data de início. + hexcode_invalid: não é um código de cor hexadecimal válido de 6 dígitos. inclusion: Não está definido como um dos valores permitidos. inclusion_nested: 'não foi definido para um dos valores permitidos no caminho ''%{path}''. ' invalid: é inválido. invalid_uri: deve ser um URI válido. invalid_url: não é um URL válido. invalid_url_scheme: 'não é um protocolo suportado (permitidos: %{allowed_schemes}).' + is_for_all_cannot_modify: é aplicável a todos os projetos e, portanto, não pode ser modificado. less_than_or_equal_to: deve ser menor ou igual a %{count}. not_available: não está disponível devido a uma configuração do sistema. + not_before_start_date: não pode ser anterior à data de início. not_deletable: não pode ser excluído. not_editable: não pode ser editado porque já está em vigor. not_current_user: não é o usuário atual. - system_wide_non_working_day_exists: conflita com um dia não útil já existente em todo o sistema para esta data. not_found: não encontrado. not_a_date: não é uma data válida. not_a_datetime: não é uma data/hora válida. not_a_number: não é um número. not_allowed: é inválido devido à falta de permissões. - host_not_allowed: não é um host permitido. not_json: não pode ser analisado como JSON. not_json_object: não é um objeto JSON. not_an_integer: não é um número inteiro. not_an_iso_date: 'não é uma data válida. Formato exigido: AAAA-MM-DD.' not_same_project: não pertence ao mesmo projeto. - datetime_must_be_in_future: deve ser no futuro. odd: deve ser ímpar. + overlapping_range: sobrepõe-se a um período já existente de dias não úteis. regex_match_failed: não corresponde à expressão regular %{expression}. regex_invalid: não pode ser validado com a expressão regular associada. regex_list_invalid: As linhas %{invalid_lines} não puderam ser interpretadas como expressão regular. - hexcode_invalid: não é um código de cor hexadecimal válido de 6 dígitos. smaller_than_or_equal_to_max_length: deve ser menor ou igual ao tamanho máximo. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflita com um dia não útil já existente em todo o sistema para esta data. taken: já está sendo utilizado. too_long: é muito longo (o máximo é %{count} caracteres). too_short: é muito curto (mínimo é %{count} caracteres). @@ -2177,6 +2176,7 @@ pt-BR: url_not_secure_context: 'não está fornecendo um "Secure Context". Você pode tanto usar HTTPS ou um endereço loopback. ' + user_already_in_department: Usuário %{user_id} já é membro do departamento %{department_id}. wrong_length: é o tamanho errado (deve ser %{count} caracteres). models: group: @@ -2843,6 +2843,7 @@ pt-BR: button_login: Iniciar sessão button_move: Mover button_move_and_follow: Mover e seguir + button_next: Próximo button_print: Imprimir button_quote: Citar button_remove: Remover @@ -3472,6 +3473,12 @@ pt-BR: selected: Selecionado include_sub_items: Incluir subitens no_results_text: Sem resultados + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Ativado label_off: Desativado @@ -4522,6 +4529,9 @@ pt-BR: label_x_working_days_time_off: one: 'Dia de folga: 1 dia útil' other: 'Dia de folga: %{count} dias úteis' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ontem label_zen_mode: Modo Zen label_role_type: Tipo diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml index 4397d5c7c23..262454aebf6 100644 --- a/config/locales/crowdin/pt-PT.yml +++ b/config/locales/crowdin/pt-PT.yml @@ -2105,17 +2105,14 @@ pt-PT: before: tem de ser anterior a %{date}. before_or_equal_to: deve ser antes ou igual a %{date}. blank: não pode ficar em branco. - not_before_start_date: não deve ser antes da data de início. - overlapping_range: sobrepõe-se a um intervalo de dias não úteis já existente. blank_nested: precisa de ter a propriedade '%{property}' configurada. cannot_delete_mapping: é necessário. Não pode ser eliminado. - is_for_all_cannot_modify: é para todos os projetos e, por conseguinte, não pode ser alterado. cant_link_a_work_package_with_a_descendant: Um pacote de trabalho não pode ser ligado a uma das suas sub-tarefas. circular_dependency: Esta relação vai criar uma dependência circular. confirmation: não coincide %{attribute}. could_not_be_copied: "%{dependency} não pode ser copiado (completamente)." + datetime_must_be_in_future: tem de estar no futuro. does_not_exist: não existe. - user_already_in_department: O utilizador %{user_id} já é membro do departamento %{department_id}. error_enterprise_only: "%{action} só está disponível na edição OpenProject Enterprise." error_unauthorized: não pode ser acedido. error_readonly: tentou escrever, mas não é gravável. @@ -2136,36 +2133,38 @@ pt-PT: greater_than_or_equal_to: deve ser maior ou igual a %{count}. greater_than_or_equal_to_start_date: deve ser maior ou igual à data de início. greater_than_start_date: deve ser superior à data de inicio. + hexcode_invalid: não é um código de cor hexadecimal de 6 dígitos válido. inclusion: não está definido como um dos valores permitidos. inclusion_nested: não está definido como um dos valores permitidos no caminho '%{path}'. invalid: é inválido. invalid_uri: deve ser uma URI válida. invalid_url: não é um URL válido. invalid_url_scheme: 'não é um protocolo suportado (permitido: %{allowed_schemes}).' + is_for_all_cannot_modify: é para todos os projetos e, por conseguinte, não pode ser alterado. less_than_or_equal_to: deve ser menor ou igual a %{count}. not_available: não está disponível devido a uma configuração do sistema. + not_before_start_date: não deve ser antes da data de início. not_deletable: não pode ser eliminado not_editable: não pode ser editado porque já está em vigor. not_current_user: não é o utilizador atual. - system_wide_non_working_day_exists: entra em conflito com um dia não útil existente em todo o sistema para esta data. not_found: não encontrado. not_a_date: não é uma data válida. not_a_datetime: não é uma data/hora válida. not_a_number: não é um número. not_allowed: é inválido devido a permissões em falta. - host_not_allowed: não é um anfitrião permitido. not_json: não é analisável como JSON. not_json_object: não é um objeto JSON. not_an_integer: não é um número inteiro. not_an_iso_date: 'não é uma data válida. Formato exigido: AAAA-MM-DD.' not_same_project: não pertence ao mesmo projeto. - datetime_must_be_in_future: tem de estar no futuro. odd: deve ser ímpar. + overlapping_range: sobrepõe-se a um intervalo de dias não úteis já existente. regex_match_failed: não corresponde à expressão regular %{expression}. regex_invalid: não pode ser validado com a expressão regular associada. regex_list_invalid: Não foi possível analisar as linhas %{invalid_lines} como expressão regular. - hexcode_invalid: não é um código de cor hexadecimal de 6 dígitos válido. smaller_than_or_equal_to_max_length: deve ser menor ou igual ao comprimento máximo. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: entra em conflito com um dia não útil existente em todo o sistema para esta data. taken: já está a ser utilizado. too_long: é muito longo (o máximo é %{count} caracteres). too_short: é muito curto (o mínimo é de %{count} carateres). @@ -2178,6 +2177,7 @@ pt-PT: url_not_secure_context: 'não está a fornecer um "Contexto Seguro". Use HTTPS ou um endereço de loopback, como localhost. ' + user_already_in_department: O utilizador %{user_id} já é membro do departamento %{department_id}. wrong_length: tamanho errado (deve ser %{count} caracteres). models: group: @@ -2844,6 +2844,7 @@ pt-PT: button_login: Iniciar sessão button_move: Mover button_move_and_follow: Mover e seguir + button_next: Seguinte button_print: Imprimir button_quote: Citar button_remove: Remover @@ -3473,6 +3474,12 @@ pt-PT: selected: Selecionado include_sub_items: Incluir sub-elementos no_results_text: Sem resultados + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Ligar label_off: Desligar @@ -4523,6 +4530,9 @@ pt-PT: label_x_working_days_time_off: one: 'Ausência: 1 dia útil' other: 'Ausência: %{count} dias úteis' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ontem label_zen_mode: Modo Zen label_role_type: Tipo diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml index b39507d7393..ef9e713c897 100644 --- a/config/locales/crowdin/ro.yml +++ b/config/locales/crowdin/ro.yml @@ -2128,17 +2128,14 @@ ro: before: trebuie să fie înainte de %{date}. before_or_equal_to: trebuie să fie înainte sau în %{date}. blank: nu poate fi gol. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: trebuie să aibă setul '%{property}' al proprietății. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Un pachet de lucru nu poate fi legat de una din sub-activitățile sale. circular_dependency: Această relație ar crea o dependință circulară. confirmation: nu se potrivește cu %{attribute}. could_not_be_copied: "%{dependency} nu a putut fi copiat (integral)." + datetime_must_be_in_future: must be in the future. does_not_exist: nu există. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: nu pot fi accesate. error_readonly: a fost încercat să fie scris, dar nu este inscriptibil. @@ -2159,36 +2156,38 @@ ro: greater_than_or_equal_to: trebuie să fie mai mare sau egal cu %{count}. greater_than_or_equal_to_start_date: trebuie să fie mai mare sau egală cu dată început. greater_than_start_date: trebuie să fie mai mare decât dată început + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nu este setată la una din valorile permise. inclusion_nested: nu este setată la una dintre valorile permise la calea '%{path}'. invalid: este invalid. invalid_uri: must be a valid URI. invalid_url: nu este o adresa URL validă. invalid_url_scheme: 'nu este un protocol permis (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: trebuie să fie mai mic sau egal cu %{count}. not_available: nu este disponibil din cauza unei configurații a sistemului. + not_before_start_date: must not be before the start date. not_deletable: "%s nu poate fi șters." not_editable: cannot be edited because it is already in effect. not_current_user: nu este utilizatorul curent. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: nu a fost găsit. not_a_date: Acest câmp trebuie să conțină o dată validă. not_a_datetime: nu este o dată-ora validă. not_a_number: nu este un număr. not_allowed: nu este valabilă din cauza lipsei de permisiuni. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: nu este un întreg. not_an_iso_date: 'nu este o dată validă. Formatul necesar: AAAA-MM-ZZ.' not_same_project: nu aparține aceluiași proiect. - datetime_must_be_in_future: must be in the future. odd: trebuie să fie impar. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: nu a putut fi validată cu expresia regulată asociată. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: trebuie să fie mai mic sau egal cu lungimea maximă. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. 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). @@ -2201,6 +2200,7 @@ ro: url_not_secure_context: 'nu oferă un "Context securizat". Folosește fie HTTPS sau o adresă de tip buclă, cum ar fi localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: nu are lungimea corectă (ar trebui să fie de %{count} characters). models: group: @@ -2887,6 +2887,7 @@ ro: button_login: Autentificare button_move: Mutare button_move_and_follow: Mutare și continuare + button_next: Next button_print: Tipărește button_quote: Citare button_remove: Eliminare @@ -3537,6 +3538,12 @@ ro: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4592,6 +4599,10 @@ ro: one: 'Time off: 1 working day' few: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + other: "%{count} items selected" label_yesterday: ieri label_zen_mode: Zen mode label_role_type: Tip diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml index df7bde12f5d..31b4ac19831 100644 --- a/config/locales/crowdin/ru.yml +++ b/config/locales/crowdin/ru.yml @@ -2152,17 +2152,14 @@ ru: before: должны быть до %{date}. before_or_equal_to: должны быть до или ровно %{date}. blank: не может быть пустым. - not_before_start_date: должно быть после даты начала. - overlapping_range: пересекается с существующим диапазоном нерабочих дней. blank_nested: должно быть установлено свойство '%{property}'. cannot_delete_mapping: требуется. Невозможно удалить. - is_for_all_cannot_modify: предназначено для всех проектов и поэтому не может быть изменено. cant_link_a_work_package_with_a_descendant: Пакет работ не может быть связан с одной из своих подзадач. circular_dependency: Это отношение создаст циклическую зависимость. confirmation: не совпадает со значением поля %{attribute}. could_not_be_copied: "%{dependency} не может быть скопировано (полностью)." + datetime_must_be_in_future: должно быть в будущем. does_not_exist: не существует. - user_already_in_department: Пользователь %{user_id} уже является членом департамента %{department_id}. error_enterprise_only: "%{action} доступно только в корпоративной версии OpenProject." error_unauthorized: не доступен. error_readonly: запись не разрешена. @@ -2183,36 +2180,38 @@ ru: greater_than_or_equal_to: должен быть больше или равно %{count}. greater_than_or_equal_to_start_date: должна быть позднее даты начала или совпадать с ней. greater_than_start_date: должна быть позднее даты начала. + hexcode_invalid: неверный 6-значный шестнадцатеричный код цвета. inclusion: не задано ни одно из допустимых значений. inclusion_nested: не задано одно из допустимых значений в пути '%{path}'. invalid: неверно. invalid_uri: должен быть допустимым URI. invalid_url: не является допустимым URL-адресом. invalid_url_scheme: 'не является поддерживаемым протоколом (разрешены следующие: %{allowed_schemes}).' + is_for_all_cannot_modify: предназначено для всех проектов и поэтому не может быть изменено. less_than_or_equal_to: должно быть меньше или равно %{count}. not_available: недоступно из-за конфигурации системы. + not_before_start_date: должно быть после даты начала. not_deletable: не может быть удален. not_editable: не может быть отредактирован, поскольку он уже действует. not_current_user: не является текущим пользователем. - system_wide_non_working_day_exists: конфликтует с существующим общесистемным нерабочим днем для этой даты. not_found: не найдено. not_a_date: не является допустимой датой. not_a_datetime: дата и время не являются допустимыми. not_a_number: не является числом. not_allowed: неверно, ввиду отсутствия прав. - host_not_allowed: не является разрешенным хостом. not_json: не может быть разобран как JSON. not_json_object: не является объектом JSON. not_an_integer: не является целым числом. not_an_iso_date: 'недопустимая дата. Требуемый формат: гггг-мм-дд.' not_same_project: не принадлежит тому же проекту. - datetime_must_be_in_future: должно быть в будущем. odd: должно быть нечетным. + overlapping_range: пересекается с существующим диапазоном нерабочих дней. regex_match_failed: не соответствует регулярному выражению %{expression}. regex_invalid: не может быть проверен связанным регулярным выражением. regex_list_invalid: Строки %{invalid_lines} не могут быть проанализированы как регулярное выражение. - hexcode_invalid: неверный 6-значный шестнадцатеричный код цвета. smaller_than_or_equal_to_max_length: должно быть меньше или равно максимальной длине. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: конфликтует с существующим общесистемным нерабочим днем для этой даты. taken: уже принято. too_long: слишком длинно (максимум — %{count} знаков). too_short: слишком коротко (минимум — %{count} знаков). @@ -2225,6 +2224,7 @@ ru: url_not_secure_context: 'не предоставляет "Secure Context". Используйте HTTPS или обратный адрес, например localhost. ' + user_already_in_department: Пользователь %{user_id} уже является членом департамента %{department_id}. wrong_length: неправильная длина (должно быть %{count} знаков). models: group: @@ -2931,6 +2931,7 @@ ru: button_login: Войти button_move: Переместить button_move_and_follow: Переместить и следовать + button_next: Next button_print: Печать button_quote: Цитата button_remove: Удалить @@ -3602,6 +3603,12 @@ ru: selected: Выбрано include_sub_items: Включить подпроекты no_results_text: Нет результатов + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Включено label_off: Выключено @@ -4662,6 +4669,11 @@ ru: few: 'Время отдыха: %{count} рабочих дней' many: 'Время отдыха: %{count} рабочих дней' other: 'Время отдыха: %{count} рабочих дней' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: вчера label_zen_mode: Режим «Дзен» (только доска и часы) label_role_type: Тип diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml index c3b570af8e5..ee01c1ff03c 100644 --- a/config/locales/crowdin/rw.yml +++ b/config/locales/crowdin/rw.yml @@ -2107,17 +2107,14 @@ rw: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ rw: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ rw: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ rw: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ rw: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ rw: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml index f2fff444061..26083e82ace 100644 --- a/config/locales/crowdin/si.yml +++ b/config/locales/crowdin/si.yml @@ -2107,17 +2107,14 @@ si: before: must be before %{date}. before_or_equal_to: "%{date}ට පෙර හෝ සමාන විය යුතුය." blank: හිස් විය නොහැක. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: වැඩ පැකේජයක් එහි එක් උප කර්තව්යයකට සම්බන්ධ කළ නොහැක. circular_dependency: මෙම සම්බන්ධතාවය චක්රලේඛය යැපීමක් නිර්මාණය කරනු ඇත. confirmation: "%{attribute}නොගැලපේ." could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: නොපවතී. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: ප්රවේශ විය නොහැක. error_readonly: ලිවීමට උත්සාහ කළ නමුත් එය ලිවිය නොහැක. @@ -2138,36 +2135,38 @@ si: greater_than_or_equal_to: "%{count}ට වඩා වැඩි හෝ සමාන විය යුතුය." greater_than_or_equal_to_start_date: ආරම්භක දිනයට වඩා වැඩි හෝ සමාන විය යුතුය. greater_than_start_date: ආරම්භක දිනයට වඩා වැඩි විය යුතුය. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: අවසර ලත් අගයන්ගෙන් එකක් ලෙස සකසා නැත. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: අවලංගුයි. invalid_uri: must be a valid URI. invalid_url: වලංගු URL එකක් නොවේ. invalid_url_scheme: 'සහාය දක්වන ප්රොටෝකෝලය නොවේ (අවසර ඇත: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: "%{count}ට වඩා අඩු හෝ සමාන විය යුතුය." not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: වලංගු දිනයක් නොවේ. not_a_datetime: වලංගු දිනය කාලය නොවේ. not_a_number: අංකයක් නොවේ. not_allowed: අතුරුදහන් අවසරයන් නිසා අවලංගු වේ. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: පූර්ණ සංඛ්යාලයක් නොවේ. not_an_iso_date: 'වලංගු දිනයක් නොවේ. අවශ්ය ආකෘතිය: YYY-MM-DD.' not_same_project: එකම ව්යාපෘතියට අයත් නොවේ. - datetime_must_be_in_future: must be in the future. odd: අමුතු විය යුතුය. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: ආශ්රිත නිත්ය ප්රකාශනය සමඟ වලංගු කළ නොහැකි විය. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: උපරිම දිගට වඩා කුඩා හෝ සමාන විය යුතුය. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: දැනටමත් ගෙන ඇත. too_long: ඉතා දිගු වේ (උපරිම %{count} අක්ෂර). too_short: ඉතා කෙටි වේ (අවම අක්ෂර %{count} වේ). @@ -2180,6 +2179,7 @@ si: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: වැරදි දිග (අක්ෂර %{count} විය යුතුය). models: group: @@ -2846,6 +2846,7 @@ si: button_login: පුරනය වන්න button_move: ගෙනයන්න button_move_and_follow: ගෙනයන්න සහ අනුගමනය කරන්න + button_next: Next button_print: මුද්රණය button_quote: උපුටා button_remove: ඉවත් කරන්න @@ -3475,6 +3476,12 @@ si: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ si: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: ඊයේ label_zen_mode: Zen mode label_role_type: වර්ගය diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml index 262ae74f09b..681e361bc94 100644 --- a/config/locales/crowdin/sk.yml +++ b/config/locales/crowdin/sk.yml @@ -2149,17 +2149,14 @@ sk: before: musí byť pred termínom %{date}. before_or_equal_to: musí byť pred alebo rovné termínu %{date}. blank: nemôže byť prázdne. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Pracovný balíček nemôže byť previazaný na žiadny zo svojich podriadenými balíčkov. circular_dependency: Tento vzťah by vytvoril cyklickú závislosť. confirmation: "%{attribute} sa nezhoduje." could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: neexistuje. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2180,36 +2177,38 @@ sk: greater_than_or_equal_to: musí byť väčšie alebo rovné ako %{count}. greater_than_or_equal_to_start_date: musí byť väčší alebo rovný ako počiatočný dátum. greater_than_start_date: musí byť väčší ako počiatočný dátum. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: nie je nastavená na niektorú z povolených hodnôt. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: je neplatný. invalid_uri: must be a valid URI. invalid_url: nie je platnou URL adresou. invalid_url_scheme: 'nie je podporovaný protokol (povolené: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: musí byť menšie alebo rovné ako %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: nie je platný dátum. not_a_datetime: nie je platný dátum a čas. not_a_number: nie je číslo. not_allowed: je neplatné kvôli chýbajúcim oprávneniam. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: nie je celé číslo. not_an_iso_date: 'nie je platný dátum. Požadovaný formát: RRRR-MM-DD.' not_same_project: nepodlieha rovnakému projektu. - datetime_must_be_in_future: must be in the future. odd: musí byť nepárne. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: nebolo možné overiť s príslušným regulárnym výrazom. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: musí byť menšie alebo rovné ako maximálne dĺžka. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: už existuje v systéme. too_long: je príliš dlhý (maximum je %{count} znakov). too_short: je príliš krátky (minimum je %{count} znakov). @@ -2222,6 +2221,7 @@ sk: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: má chybnú dĺžku (správne má byť %{count} znakov). models: group: @@ -2926,6 +2926,7 @@ sk: button_login: Prihlásiť sa button_move: Presunúť button_move_and_follow: Presunúť a nasledovať + button_next: Next button_print: Tlač button_quote: Citovať button_remove: Vymazať @@ -3597,6 +3598,12 @@ sk: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4657,6 +4664,11 @@ sk: few: 'Time off: %{count} working days' many: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: včera label_zen_mode: Zen mode label_role_type: Typ diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml index a432475b0fa..41c49e64a91 100644 --- a/config/locales/crowdin/sl.yml +++ b/config/locales/crowdin/sl.yml @@ -2150,17 +2150,14 @@ sl: before: mora biti pred %{date}. before_or_equal_to: mora biti pred ali enako %{date}. blank: ne sme biti prazno. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: mora imeti nastavljeno lastnost '%{property}'. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Zahtevek ne more biti povezan s svojo podnalogo circular_dependency: Ta povezava bi ustvarila krožno odvisnost. confirmation: se ne ujema %{attribute} could_not_be_copied: "%{dependency} ni bilo mogoče (v celoti) kopirati." + datetime_must_be_in_future: must be in the future. does_not_exist: ne obstaja - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: morda ni mogoče dostopati. error_readonly: poskušano je bilo napisati, vendar ni mogoče pisati. @@ -2181,36 +2178,38 @@ sl: greater_than_or_equal_to: mora biti večje ali enako %{count}. greater_than_or_equal_to_start_date: mora biti večji ali enak začetnemu datumu. greater_than_start_date: mora biti večje od začetnega datuma. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: ni nastavljeno na eno od dovoljenih vrednosti. inclusion_nested: ni nastavljena na eno od dovoljenih vrednosti na poti '%{path}'. invalid: ni pravo. invalid_uri: must be a valid URI. invalid_url: 'ni veljaven URL. ' invalid_url_scheme: ni podprt protokol (dovoljeno:%{allowed_schemes}). + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: 'mora biti manjše ali enako %{count}. ' not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: se ne da izbrisati. not_editable: cannot be edited because it is already in effect. not_current_user: ni trenutni uporabnik. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: ni veljaven datum not_a_datetime: ni veljaven datum. not_a_number: ni število. not_allowed: 'ni veljavno, saj manjka dovoljenje. ' - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: 'ni celo število. ' not_an_iso_date: 'neveljaven čas. Potreben format: YYYY-MM-DD.' not_same_project: ne pripada istemu projektu - datetime_must_be_in_future: must be in the future. odd: 'mora biti liho. ' + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: ni bilo mogoče potrditi s pripadajočim stalnim izrazom. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: mora biti manjše ali enako največji dolžini. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: je že zasedeno. too_long: je predolgo (največ %{count} znakov). too_short: je prekrateko (najmanj %{count} znakov). @@ -2223,6 +2222,7 @@ sl: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: 'je napačna dolžina (mora biti %{count} znakov). ' models: group: @@ -2935,6 +2935,7 @@ sl: button_login: Prijava button_move: Premakni button_move_and_follow: Premakni in sledi + button_next: Next button_print: Natisni button_quote: Citiraj button_remove: Odstrani @@ -3608,6 +3609,12 @@ sl: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4672,6 +4679,11 @@ sl: two: 'Time off: %{count} working days' few: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + two: "%{count} items selected" + few: "%{count} items selected" + other: "%{count} items selected" label_yesterday: včeraj label_zen_mode: Zen mode label_role_type: Vrsta diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml index beca8904efc..0a5245e465d 100644 --- a/config/locales/crowdin/sr.yml +++ b/config/locales/crowdin/sr.yml @@ -2128,17 +2128,14 @@ sr: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2159,36 +2156,38 @@ sr: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2201,6 +2200,7 @@ sr: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2887,6 +2887,7 @@ sr: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3537,6 +3538,12 @@ sr: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4592,6 +4599,10 @@ sr: one: 'Time off: 1 working day' few: 'Time off: %{count} working days' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml index f1c590c09a2..9c332e91fd5 100644 --- a/config/locales/crowdin/sv.yml +++ b/config/locales/crowdin/sv.yml @@ -2107,17 +2107,14 @@ sv: before: måste vara innan %{date}. before_or_equal_to: måste vara före eller lika med %{date}. blank: kan inte vara tomt. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: Ett arbetspaket kan inte kopplas till någon av dess underaktiviteter. circular_dependency: Detta förhållande skulle skapa ett cirkelberoende. confirmation: matchar inte %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: finns inte. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: åtkomst nekas. error_readonly: försökte skrivas men är inte skrivbart. @@ -2138,36 +2135,38 @@ sv: greater_than_or_equal_to: måste vara större än eller lika med %{count}. greater_than_or_equal_to_start_date: måste vara senare eller lika som startdatumet. greater_than_start_date: måste vara senare än startdatumet. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: inte är inställd på ett av de tillåtna värdena. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: är ogiltig. invalid_uri: must be a valid URI. invalid_url: är inte ett giltigt URL. invalid_url_scheme: 'är inte ett tillåtet protokoll (tillåtna: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: måste vara mindre än eller lika med %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: kan inte raderas. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: hittades inte. not_a_date: är inte är ett giltigt datum. not_a_datetime: är inte en giltig datumtid. not_a_number: är inte ett nummer. not_allowed: är inte tillåtet på grund av saknade behörigheter. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: är inte ett heltal. not_an_iso_date: är inte ett giltigt datum. Använd formatet ÅÅÅÅ-MM-DD. not_same_project: tillhör inte samma projekt. - datetime_must_be_in_future: must be in the future. odd: måste vara udda. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: kunde inte valideras med det associerade reguljära uttrycket. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: måste vara mindre än eller lika med maximal längd. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: har redan använts. too_long: är för långt (maximalt är %{count} tecken). too_short: är för kort (minimum är %{count} tecken). @@ -2180,6 +2179,7 @@ sv: url_not_secure_context: 'tillhandahåller inte en "Secure Context". Använd antingen HTTPS eller en loopback-adress, som localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: har fel längd (måste vara %{count} tecken). models: group: @@ -2846,6 +2846,7 @@ sv: button_login: Logga in button_move: Flytta button_move_and_follow: Flytta och följ + button_next: Next button_print: Skriv ut button_quote: Citat button_remove: Ta bort @@ -3475,6 +3476,12 @@ sv: selected: Selected include_sub_items: Include sub-items no_results_text: Inga resultat + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ sv: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: igår label_zen_mode: Zen-läge label_role_type: Typ diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml index 630b0f47049..86825024eaf 100644 --- a/config/locales/crowdin/th.yml +++ b/config/locales/crowdin/th.yml @@ -2086,17 +2086,14 @@ th: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2117,36 +2114,38 @@ th: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2159,6 +2158,7 @@ th: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2805,6 +2805,7 @@ th: button_login: ลงชื่อเข้าใช้ button_move: ย้าย button_move_and_follow: ย้าย และทำตาม + button_next: Next button_print: Print button_quote: อ้างถึง button_remove: Remove @@ -3413,6 +3414,12 @@ th: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4458,6 +4465,8 @@ th: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: เมื่อวานนี้ label_zen_mode: Zen mode label_role_type: ประเภท diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml index e963f3266ba..8a437539355 100644 --- a/config/locales/crowdin/tr.yml +++ b/config/locales/crowdin/tr.yml @@ -2108,17 +2108,14 @@ tr: before: "%{date}'dan daha önce olması gerekir." before_or_equal_to: "%{date}} tarihinden önce veya ona eşit olmalıdır." blank: boş bırakılamaz. - not_before_start_date: başlangıç tarihinden önce olmamalıdır. - overlapping_range: mevcut bir çalışma dışı gün aralığı ile çakışır. blank_nested: "'%{property}' özelliğinin ayarlanmış olması gerekir." 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." could_not_be_copied: "%{dependency} (tam olarak) kopyalanamadı." + datetime_must_be_in_future: gelecekte olmalı. does_not_exist: mevcut değil. - user_already_in_department: Kullanıcı %{user_id} zaten %{department_id} departmanının bir üyesidir. error_enterprise_only: "%{action} yalnızca OpenProject Enterprise sürümünde mevcuttur." error_unauthorized: erişilemez. error_readonly: yazılmaya çalışıldı fakat yazılabilir değil. @@ -2141,38 +2138,40 @@ tr: greater_than_or_equal_to: "%{count} ya da daha büyük olması gerekir." greater_than_or_equal_to_start_date: başlangıç tarihi ile aynı ya da daha büyük olması gerekir. greater_than_start_date: başlangıç tarihinden daha büyük olması gerekir. + hexcode_invalid: geçerli bir 6 basamaklı onaltılık renk kodu değildir. inclusion: izin verilen değerlerden birine ayarlanmamış. inclusion_nested: "'%{path}' yolunda izin verilen değerlerden birine ayarlanmamış." invalid: geçersizdir. invalid_uri: must be a valid URI. invalid_url: geçerli bir adres değil. invalid_url_scheme: 'bu protokol desteklenmiyor (izin: %{allowed_schemes}).' + is_for_all_cannot_modify: tüm projeler içindir ve bu nedenle değiştirilemez. less_than_or_equal_to: "%{count} 'ten küçük veya bu değere eşit olmalıdır." not_available: 'Sistem yapılandırması nedeniyle kullanılamaz. ' + not_before_start_date: başlangıç tarihinden önce olmamalıdır. not_deletable: kaldırılamadı. not_editable: cannot be edited because it is already in effect. not_current_user: mevcut kullanıcı değil. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. 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. - host_not_allowed: is not an allowed host. not_json: JSON olarak ayrıştırılamaz. not_json_object: 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. - datetime_must_be_in_future: gelecekte olmalı. odd: tek sayı olmalı. + overlapping_range: mevcut bir çalışma dışı gün aralığı ile çakışır. regex_match_failed: "%{expression} düzenli ifadesiyle eşleşmiyor." regex_invalid: atanmış düzenli ifadeler ile doğrulanamadı. regex_list_invalid: "%{invalid_lines} satırları düzenli ifade olarak ayrıştırılamadı." - hexcode_invalid: geçerli bir 6 basamaklı onaltılık renk kodu değildir. smaller_than_or_equal_to_max_length: en fazla uzunluğa eşit veya daha küçük olmalıdır. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: zaten alınmıştır. too_long: çok uzun (en fazla %{count} karakterdir). too_short: çok kısa (en az %{count} karakterdir). @@ -2185,6 +2184,7 @@ tr: url_not_secure_context: 'bir "Güvenli Bağlam" sağlamıyor. HTTPS veya localhost gibi bir geri döngü adresi kullanın. ' + user_already_in_department: Kullanıcı %{user_id} zaten %{department_id} departmanının bir üyesidir. wrong_length: uzunluğu yanlıştır (%{count} karakter olmalıdır). models: group: @@ -2851,6 +2851,7 @@ tr: button_login: Oturum aç button_move: Taşı button_move_and_follow: Taşı ve takip et + button_next: Next button_print: Yazdır button_quote: Alıntı button_remove: Kaldır @@ -3480,6 +3481,12 @@ tr: selected: Seçilen include_sub_items: Alt öğeleri dahil et no_results_text: Sonuç yok + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Açık label_off: Kapalı @@ -4530,6 +4537,9 @@ tr: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: dün label_zen_mode: Zen modu label_role_type: Tür diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml index d16049527d3..77e72dab136 100644 --- a/config/locales/crowdin/uk.yml +++ b/config/locales/crowdin/uk.yml @@ -2144,17 +2144,14 @@ uk: before: має бути раніше %{date} before_or_equal_to: має бути до або %{date} blank: не може бути порожнім. - not_before_start_date: не має передувати даті початку. - overlapping_range: збігається з наявним діапазоном неробочих днів. blank_nested: "– потрібно встановити властивість «%{property}»." cannot_delete_mapping: "– обов’язкове. Неможливо видалити." - is_for_all_cannot_modify: призначений для всіх проєктів, тому його не можна бути змінити. cant_link_a_work_package_with_a_descendant: Робочий пакет не може бути пов'язаний з одним з підзадач. circular_dependency: Це співвідношення створить кругову залежність. confirmation: не збігається %{attribute} could_not_be_copied: "%{dependency} не вдалося скопіювати (повністю)." + datetime_must_be_in_future: має бути в майбутньому. does_not_exist: не існує. - user_already_in_department: Користувач %{user_id} уже є членом відділу «%{department_id}». error_enterprise_only: "%{action} можна лише у версії OpenProject Enterprise." error_unauthorized: "– можливо, немає доступу." error_readonly: "– було здійснено спробу запису, але елемент недоступний для запису." @@ -2175,36 +2172,38 @@ uk: greater_than_or_equal_to: має бути більшим або рівним %{count} greater_than_or_equal_to_start_date: має бути більшою або дорівнювати даті початку. greater_than_start_date: має бути більше дати початку. + hexcode_invalid: не є дійсним 6-значним шістнадцятковим кодом кольору. inclusion: не встановлено в одному з допустимих значень inclusion_nested: "– не призначено одне з дозволених значень за шляхом «%{path}»." invalid: зазначено невірно invalid_uri: має бути дійсною URL-адресою. invalid_url: не є дійсною URL-адресою. invalid_url_scheme: 'не є підтримуваним протоколом (дозволено: %{allowed_schemes}).' + is_for_all_cannot_modify: призначений для всіх проєктів, тому його не можна бути змінити. less_than_or_equal_to: має бути меншим або рівним %{count} not_available: "– недоступно через налаштування системи." + not_before_start_date: не має передувати даті початку. not_deletable: не можна видалити. not_editable: уже використовується, тому вносити зміни не можна. not_current_user: не поточний користувач. - system_wide_non_working_day_exists: конфліктує з наявним загальним неробочим днем, указаним для цієї дати. not_found: не знайдено. not_a_date: не є дійсною датою. not_a_datetime: не є дійсним датою. not_a_number: не є числом not_allowed: недійсний через відсутність дозволів. - host_not_allowed: не є дозволеним хостом. not_json: не аналізується як JSON. not_json_object: не є об’єктом JSON. not_an_integer: не є цілим числом not_an_iso_date: 'не є дійсною датою. Необхідний формат: YYYY-MM-DD.' not_same_project: не належить до одного проекту. - datetime_must_be_in_future: має бути в майбутньому. odd: має бути непарним. + overlapping_range: збігається з наявним діапазоном неробочих днів. regex_match_failed: не збігається з регулярним виразом %{expression}. regex_invalid: неможливо перевірити з відповідним регулярним виразом. regex_list_invalid: Неможливо проаналізувати рядки %{invalid_lines} як регулярний вираз. - hexcode_invalid: не є дійсним 6-значним шістнадцятковим кодом кольору. smaller_than_or_equal_to_max_length: має бути меншою або дорівнює максимальній довжині. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: конфліктує з наявним загальним неробочим днем, указаним для цієї дати. taken: вже прийнято. too_long: 'занадто довгий (максимум - %{count} characters). @@ -2219,6 +2218,7 @@ uk: url_not_secure_context: 'не надає контекст безпеки. Використовуйте HTTPS або адресу loopback, наприклад localhost. ' + user_already_in_department: Користувач %{user_id} уже є членом відділу «%{department_id}». wrong_length: неправильна довжина (повинна бути %{count} символів). models: group: @@ -2927,6 +2927,7 @@ uk: button_login: Увійти button_move: Перемістити button_move_and_follow: Перемістити і перейти + button_next: Далі button_print: Друкувати button_quote: Цитата button_remove: Видалити @@ -3598,6 +3599,12 @@ uk: selected: Вибрано include_sub_items: Включити піделементи no_results_text: Немає результатів + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: Увімкнено label_off: Вимкнено @@ -4658,6 +4665,11 @@ uk: few: 'Вільний час: %{count} робочих дні' many: 'Вільний час: %{count} робочих днів' other: 'Вільний час: %{count} робочого дня' + label_x_items_selected: + one: One item selected + few: "%{count} items selected" + many: "%{count} items selected" + other: "%{count} items selected" label_yesterday: вчора label_zen_mode: Режим «Дзен» label_role_type: Тип diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml index e7da5e75482..c5a8e864dae 100644 --- a/config/locales/crowdin/uz.yml +++ b/config/locales/crowdin/uz.yml @@ -2107,17 +2107,14 @@ uz: before: must be before %{date}. before_or_equal_to: must be before or equal to %{date}. blank: can't be blank. - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: needs to have the property '%{property}' set. cannot_delete_mapping: is required. Cannot be deleted. - is_for_all_cannot_modify: is for all projects and can therefore not be modified. cant_link_a_work_package_with_a_descendant: A work package cannot be linked to one of its subtasks. circular_dependency: This relation would create a circular dependency. confirmation: doesn't match %{attribute}. could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: must be in the future. does_not_exist: does not exist. - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: may not be accessed. error_readonly: was attempted to be written but is not writable. @@ -2138,36 +2135,38 @@ uz: greater_than_or_equal_to: must be greater than or equal to %{count}. greater_than_or_equal_to_start_date: must be greater than or equal to the start date. greater_than_start_date: must be greater than the start date. + hexcode_invalid: is not a valid 6-digit hexadecimal color code. inclusion: is not set to one of the allowed values. inclusion_nested: is not set to one of the allowed values at path '%{path}'. invalid: is invalid. invalid_uri: must be a valid URI. invalid_url: is not a valid URL. invalid_url_scheme: 'is not a supported protocol (allowed: %{allowed_schemes}).' + is_for_all_cannot_modify: is for all projects and can therefore not be modified. less_than_or_equal_to: must be less than or equal to %{count}. not_available: is not available due to a system configuration. + not_before_start_date: must not be before the start date. not_deletable: cannot be deleted. not_editable: cannot be edited because it is already in effect. not_current_user: is not the current user. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: not found. not_a_date: is not a valid date. not_a_datetime: is not a valid date time. not_a_number: is not a number. not_allowed: is invalid because of missing permissions. - host_not_allowed: is not an allowed host. not_json: is not parseable as JSON. not_json_object: is not a JSON object. not_an_integer: is not an integer. not_an_iso_date: 'is not a valid date. Required format: YYYY-MM-DD.' not_same_project: doesn't belong to the same project. - datetime_must_be_in_future: must be in the future. odd: must be odd. + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: does not match the regular expression %{expression}. regex_invalid: could not be validated with the associated regular expression. regex_list_invalid: Lines %{invalid_lines} could not be parsed as regular expression. - hexcode_invalid: is not a valid 6-digit hexadecimal color code. smaller_than_or_equal_to_max_length: must be smaller than or equal to maximum length. + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: has already been taken. too_long: is too long (maximum is %{count} characters). too_short: is too short (minimum is %{count} characters). @@ -2180,6 +2179,7 @@ uz: url_not_secure_context: 'is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: is the wrong length (should be %{count} characters). models: group: @@ -2846,6 +2846,7 @@ uz: button_login: Sign in button_move: Move button_move_and_follow: Move and follow + button_next: Next button_print: Print button_quote: Quote button_remove: Remove @@ -3475,6 +3476,12 @@ uz: selected: Selected include_sub_items: Include sub-items no_results_text: No results + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 'On' label_off: 'Off' @@ -4525,6 +4532,9 @@ uz: label_x_working_days_time_off: one: 'Time off: 1 working day' other: 'Time off: %{count} working days' + label_x_items_selected: + one: One item selected + other: "%{count} items selected" label_yesterday: yesterday label_zen_mode: Zen mode label_role_type: Type diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml index c8ec9a18e1f..e996432403b 100644 --- a/config/locales/crowdin/vi.yml +++ b/config/locales/crowdin/vi.yml @@ -2088,17 +2088,14 @@ vi: before: phải trước khi %{date} before_or_equal_to: phải có trước hay tương đương với %{date} blank: không được để trống - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: cần phải đặt thuộc tính '%{property}'. cannot_delete_mapping: được yêu cầu. Không thể xóa được. - is_for_all_cannot_modify: dành cho tất cả các dự án và do đó không thể sửa đổi được. cant_link_a_work_package_with_a_descendant: Một gói công việc không thể được liên kết với một trong các nhiệm vụ con của nó. circular_dependency: Mối quan hệ này sẽ tạo ra sự phụ thuộc vòng tròn. confirmation: không khớp %{attribute}. could_not_be_copied: "%{dependency} không thể sao chép (đầy đủ)." + datetime_must_be_in_future: phải ở tương lai. does_not_exist: không tồn tại - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} chỉ có trong phiên bản OpenProject Enterprise." error_unauthorized: Có thể không được truy cập. error_readonly: đã được cố gắng viết nhưng không thể ghi được. @@ -2119,36 +2116,38 @@ vi: greater_than_or_equal_to: phải lớn hơn hoặc bằng %{count} greater_than_or_equal_to_start_date: phải lớn hơn hoặc bằng ngày bắt đầu. greater_than_start_date: phải lớn hơn ngày bắt đầu. + hexcode_invalid: không phải là mã màu thập lục phân 6 chữ số hợp lệ. inclusion: không nằm trong các giá trị cho phép inclusion_nested: không được đặt thành một trong các giá trị được phép tại đường dẫn '%{path}'. invalid: không hợp lệ invalid_uri: must be a valid URI. invalid_url: không phải là một URL hợp lệ. invalid_url_scheme: 'không phải là giao thức được hỗ trợ (được phép: %{allowed_schemes}).' + is_for_all_cannot_modify: dành cho tất cả các dự án và do đó không thể sửa đổi được. less_than_or_equal_to: phải nhỏ hơn hoặc bằng %{count} not_available: không khả dụng do cấu hình hệ thống. + not_before_start_date: must not be before the start date. not_deletable: không thể xóa được. not_editable: cannot be edited because it is already in effect. not_current_user: không phải là người dùng hiện tại. - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: không tìm thấy. not_a_date: không phải là ngày hợp lệ not_a_datetime: không phải là thời gian hợp lệ not_a_number: không phải là số not_allowed: không hợp lệ vì thiếu quyền. - host_not_allowed: is not an allowed host. not_json: không thể phân tích cú pháp dưới dạng JSON. not_json_object: không phải là một đối tượng JSON. not_an_integer: không phải là một số nguyên not_an_iso_date: 'không phải là một ngày hợp lệ. Yêu cầu định dạng: YYYY-MM-DD.' not_same_project: không thuộc cùng dự án. - datetime_must_be_in_future: phải ở tương lai. odd: phải là số lẻ + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: không khớp với biểu thức chính quy %{expression}. regex_invalid: có thể không được xác nhận với các biểu hiện thường xuyên liên kết. regex_list_invalid: Không thể phân tích cú pháp các dòng %{invalid_lines} dưới dạng biểu thức chính quy. - hexcode_invalid: không phải là mã màu thập lục phân 6 chữ số hợp lệ. smaller_than_or_equal_to_max_length: phải nhỏ hơn hoặc bằng với chiều dài tối đa + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: đã bị dùng rồi. too_long: quá dài (tối đa %{count} ký tự). too_short: quá ngắn (tối thiểu %{count} ký tự). @@ -2161,6 +2160,7 @@ vi: url_not_secure_context: 'không cung cấp "Bối cảnh an toàn". Sử dụng HTTPS hoặc địa chỉ loopback, chẳng hạn như localhost. ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: độ dài không đúng (phải là %{count} ký tự). models: group: @@ -2807,6 +2807,7 @@ vi: button_login: Đăng nhập button_move: Di chuyển button_move_and_follow: Di chuyển và thực hiện theo + button_next: Next button_print: In button_quote: Trích dẫn button_remove: Xoá @@ -3415,6 +3416,12 @@ vi: selected: đã chọn include_sub_items: Bao gồm các mục phụ no_results_text: Không có kết quả + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: trên label_off: Tắt @@ -4460,6 +4467,8 @@ vi: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: ngày hôm qua label_zen_mode: Chế độ Zen label_role_type: loại diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml index e57fa423a3b..729f05dab14 100644 --- a/config/locales/crowdin/zh-CN.yml +++ b/config/locales/crowdin/zh-CN.yml @@ -2086,17 +2086,14 @@ zh-CN: before: 必须在 %{date} 之前。 before_or_equal_to: 必须在早于或等于 %{date} blank: 不能为空。 - not_before_start_date: 不得在开始日期之前。 - overlapping_range: 与现有的非工作日范围重叠。 blank_nested: 需要设置属性“%{property}”。 cannot_delete_mapping: 必需项,不能删除 - is_for_all_cannot_modify: 适用于所有项目,因此不能修改。 cant_link_a_work_package_with_a_descendant: 工作包无法链接到它的子任务之一。 circular_dependency: 这种关系将创建循环依赖项。 confirmation: 不匹配 %{attribute}。 could_not_be_copied: 无法(完全)复制 %{dependency}。 + datetime_must_be_in_future: 必须是将来的时间 does_not_exist: 不存在。 - user_already_in_department: 用户 %{user_id} 已经是部门 %{department_id} 的成员。 error_enterprise_only: "%{action}仅在 OpenProject 企业版中可用。" error_unauthorized: 无法访问。 error_readonly: 曾尝试被写入,但不可写。 @@ -2117,36 +2114,38 @@ zh-CN: greater_than_or_equal_to: 必须大于或等于 %{count}。 greater_than_or_equal_to_start_date: 必须晚于或等于开始日期。 greater_than_start_date: 必须晚于开始日期。 + hexcode_invalid: 不是有效的 6 位十六进制颜色代码。 inclusion: 未设置为允许的值之一。 inclusion_nested: 未设置为路径“%{path}”中允许的值之一。 invalid: 是无效的。 invalid_uri: 必须是有效的 URI。 invalid_url: 不是有效的 URL。 invalid_url_scheme: 不是受支持的协议(允许:%{allowed_schemes})。 + is_for_all_cannot_modify: 适用于所有项目,因此不能修改。 less_than_or_equal_to: 必须小于或等于 %{count}。 not_available: 因系统配置而不可用。 + not_before_start_date: 不得在开始日期之前。 not_deletable: 无法删除。 not_editable: 无法编辑,因为其已经生效。 not_current_user: 不是当前用户。 - system_wide_non_working_day_exists: 与此日期现有的系统范围非工作日冲突。 not_found: 未找到 not_a_date: 不是有效的日期。 not_a_datetime: 不是有效的日期时间。 not_a_number: 不是一个数字。 not_allowed: 没有权限使用。 - host_not_allowed: 不是允许的主机。 not_json: 无法解析为 JSON。 not_json_object: 不是 JSON 对象。 not_an_integer: 不是一个整数。 not_an_iso_date: 不是有效日期。所需格式:YYYY-MM-DD。 not_same_project: 不属于同一个项目。 - datetime_must_be_in_future: 必须是将来的时间 odd: 必须是奇数。 + overlapping_range: 与现有的非工作日范围重叠。 regex_match_failed: 与正则表达式 %{expression}不匹配。 regex_invalid: 无法与关联的正则表达式进行验证。 regex_list_invalid: 行 %{invalid_lines} 无法解析为正则表达式。 - hexcode_invalid: 不是有效的 6 位十六进制颜色代码。 smaller_than_or_equal_to_max_length: 必须小于或等于最大长度。 + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: 与此日期现有的系统范围非工作日冲突。 taken: 已经采取。 too_long: 太长 (最多 %{count} 个字符)。 too_short: 太短 (最低是 %{count} 个字符)。 @@ -2159,6 +2158,7 @@ zh-CN: url_not_secure_context: '未提供“安全上下文”。使用 HTTPS 或环回地址,例如 localhost。 ' + user_already_in_department: 用户 %{user_id} 已经是部门 %{department_id} 的成员。 wrong_length: 长度不正确 (应该是 %{count} 个字符)。 models: group: @@ -2805,6 +2805,7 @@ zh-CN: button_login: 登录 button_move: 移动 button_move_and_follow: 移动和跟踪 + button_next: 下一步 button_print: 打印 button_quote: 引用 button_remove: 移除 @@ -3413,6 +3414,12 @@ zh-CN: selected: 已选择 include_sub_items: 包含子条目 no_results_text: 无结果 + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 开启 label_off: 关闭 @@ -4458,6 +4465,8 @@ zh-CN: other: "%{count} 个工作日" label_x_working_days_time_off: other: 休息时间:%{count} 个工作日 + label_x_items_selected: + other: "%{count} items selected" label_yesterday: 昨天 label_zen_mode: 极简模式 label_role_type: 类型 diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml index b2dbfa502fa..0907e908cd0 100644 --- a/config/locales/crowdin/zh-TW.yml +++ b/config/locales/crowdin/zh-TW.yml @@ -2082,17 +2082,14 @@ zh-TW: before: 必須在 %{date} 之前 before_or_equal_to: 必須在 %{date} 以前 blank: 不可空白 - not_before_start_date: must not be before the start date. - overlapping_range: overlaps with an existing non-working day range. blank_nested: '需要設置屬性 ''%{property}'' ' cannot_delete_mapping: 必需項,不能刪除 - is_for_all_cannot_modify: 適用於所有專案,因此無法修改。 cant_link_a_work_package_with_a_descendant: 工作套件不能聯結到自己的子套件。 circular_dependency: 這個關係會建立一個循環依賴 confirmation: 不吻合 %{attribute}。 could_not_be_copied: "%{dependency} 無法完整複製." + datetime_must_be_in_future: 必須是未來時間。 does_not_exist: 不存在 - user_already_in_department: User %{user_id} is already a member of department %{department_id}. error_enterprise_only: "%{action} 只適用於 OpenProject 企業版。" error_unauthorized: 無法被存取。 error_readonly: 被嘗試寫入但是無法寫入。 @@ -2113,36 +2110,38 @@ zh-TW: greater_than_or_equal_to: 必須大於或等於 %{count}。 greater_than_or_equal_to_start_date: 必須晚於或等於開始日期。 greater_than_start_date: 必須晚於開始日期。 + hexcode_invalid: 不是有效的六位數十六進位顏色代碼。 inclusion: 沒有被設置為一個允許的值。 inclusion_nested: 未設置為路徑“%{path}”中允許的值之一 invalid: 不正確。 invalid_uri: must be a valid URI. invalid_url: 不是有效的 URL。 invalid_url_scheme: '不是受支援的協定 (允許的協定: %{allowed_schemes})。' + is_for_all_cannot_modify: 適用於所有專案,因此無法修改。 less_than_or_equal_to: 必須少於或者等於 %{count}。 not_available: 由於系統配置所以不可用 + not_before_start_date: must not be before the start date. not_deletable: 無法刪除 not_editable: cannot be edited because it is already in effect. not_current_user: 不是目前使用者。 - system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. not_found: 未找到 not_a_date: 不是有效的日期。 not_a_datetime: 不是有效的日期時間。 not_a_number: 不是數字 not_allowed: 是無效的因為缺少權限 - host_not_allowed: is not an allowed host. not_json: 無法解析為 JSON。 not_json_object: 不是 JSON 物件。 not_an_integer: 不是整數 not_an_iso_date: 不是有效日期。所需格式:YYYY-MM-DD。 not_same_project: 不屬於相同的專案 - datetime_must_be_in_future: 必須是未來時間。 odd: 必須是奇數 + overlapping_range: overlaps with an existing non-working day range. regex_match_failed: 與正則表達式 %{expression} 不匹配。 regex_invalid: 不能被相關聯的正則運算式驗證。 regex_list_invalid: "%{invalid_lines} 行無法解析為正規表示式。" - hexcode_invalid: 不是有效的六位數十六進位顏色代碼。 smaller_than_or_equal_to_max_length: 必須小於或等於最大長度。 + ssrf_filtered: violates the SSRF policy of this OpenProject instance. + system_wide_non_working_day_exists: conflicts with an existing system-wide non-working day for this date. taken: 已經被使用 too_long: 太長 (最長是 %{count} 個字元) too_short: 太短 (最少 %{count} 個字元) @@ -2155,6 +2154,7 @@ zh-TW: url_not_secure_context: '未提供「安全上下文」。使用 HTTPS 或環回地址,例如 localhost。 ' + user_already_in_department: User %{user_id} is already a member of department %{department_id}. wrong_length: 長度錯誤 (應該要有 %{count} 個字元) models: group: @@ -2801,6 +2801,7 @@ zh-TW: button_login: 登入 button_move: 移動 button_move_and_follow: 移動並跟隨 + button_next: Next button_print: 列印 button_quote: 引言 button_remove: 刪除 @@ -3407,6 +3408,12 @@ zh-TW: selected: 已選取 include_sub_items: 包含子項目 no_results_text: 查無結果 + header: + project_select_component: + all_projects: All projects + favorites: Favorites + leave_project: Leave project + title: Projects toggle_switch: label_on: 開啟 label_off: 關閉 @@ -4452,6 +4459,8 @@ zh-TW: other: "%{count} working days" label_x_working_days_time_off: other: 'Time off: %{count} working days' + label_x_items_selected: + other: "%{count} items selected" label_yesterday: 昨天 label_zen_mode: 禪意模式 label_role_type: 類型 diff --git a/config/locales/en.yml b/config/locales/en.yml index 63344b1fc29..9f8e0446a38 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2197,17 +2197,14 @@ en: before: "must be before %{date}." before_or_equal_to: "must be before or equal to %{date}." blank: "can't be blank." - not_before_start_date: "must not be before the start date." - overlapping_range: "overlaps with an existing non-working day range." blank_nested: "needs to have the property '%{property}' set." cannot_delete_mapping: "is required. Cannot be deleted." - is_for_all_cannot_modify: "is for all projects and can therefore not be modified." cant_link_a_work_package_with_a_descendant: "A work package cannot be linked to one of its subtasks." circular_dependency: "This relation would create a circular dependency." confirmation: "doesn't match %{attribute}." could_not_be_copied: "%{dependency} could not be (fully) copied." + datetime_must_be_in_future: "must be in the future." does_not_exist: "does not exist." - user_already_in_department: "User %{user_id} is already a member of department %{department_id}." error_enterprise_only: "%{action} is only available in the OpenProject Enterprise edition." error_unauthorized: "may not be accessed." error_readonly: "was attempted to be written but is not writable." @@ -2228,36 +2225,38 @@ en: greater_than_or_equal_to: "must be greater than or equal to %{count}." greater_than_or_equal_to_start_date: "must be greater than or equal to the start date." greater_than_start_date: "must be greater than the start date." + hexcode_invalid: "is not a valid 6-digit hexadecimal color code." inclusion: "is not set to one of the allowed values." inclusion_nested: "is not set to one of the allowed values at path '%{path}'." invalid: "is invalid." invalid_uri: "must be a valid URI." invalid_url: "is not a valid URL." invalid_url_scheme: "is not a supported protocol (allowed: %{allowed_schemes})." + is_for_all_cannot_modify: "is for all projects and can therefore not be modified." less_than_or_equal_to: "must be less than or equal to %{count}." not_available: "is not available due to a system configuration." + not_before_start_date: "must not be before the start date." not_deletable: "cannot be deleted." not_editable: "cannot be edited because it is already in effect." not_current_user: "is not the current user." - system_wide_non_working_day_exists: "conflicts with an existing system-wide non-working day for this date." not_found: "not found." not_a_date: "is not a valid date." not_a_datetime: "is not a valid date time." not_a_number: "is not a number." not_allowed: "is invalid because of missing permissions." - host_not_allowed: "is not an allowed host." not_json: "is not parseable as JSON." not_json_object: "is not a JSON object." not_an_integer: "is not an integer." not_an_iso_date: "is not a valid date. Required format: YYYY-MM-DD." not_same_project: "doesn't belong to the same project." - datetime_must_be_in_future: "must be in the future." odd: "must be odd." + overlapping_range: "overlaps with an existing non-working day range." regex_match_failed: "does not match the regular expression %{expression}." regex_invalid: "could not be validated with the associated regular expression." regex_list_invalid: "Lines %{invalid_lines} could not be parsed as regular expression." - hexcode_invalid: "is not a valid 6-digit hexadecimal color code." smaller_than_or_equal_to_max_length: "must be smaller than or equal to maximum length." + ssrf_filtered: "violates the SSRF policy of this OpenProject instance." + system_wide_non_working_day_exists: "conflicts with an existing system-wide non-working day for this date." taken: "has already been taken." too_long: "is too long (maximum is %{count} characters)." too_short: "is too short (minimum is %{count} characters)." @@ -2269,6 +2268,7 @@ en: unremovable: "cannot be removed." url_not_secure_context: > is not providing a "Secure Context". Either use HTTPS or a loopback address, such as localhost. + user_already_in_department: "User %{user_id} is already a member of department %{department_id}." wrong_length: "is the wrong length (should be %{count} characters)." models: group: @@ -2945,6 +2945,7 @@ en: button_login: "Sign in" button_move: "Move" button_move_and_follow: "Move and follow" + button_next: "Next" button_print: "Print" button_quote: "Quote" button_remove: Remove @@ -4677,6 +4678,9 @@ en: label_x_working_days_time_off: one: "Time off: 1 working day" other: "Time off: %{count} working days" + label_x_items_selected: + one: "One item selected" + other: "%{count} items selected" label_yesterday: "yesterday" label_zen_mode: "Zen mode" label_role_type: "Type" diff --git a/docker/ci/entrypoint.sh b/docker/ci/entrypoint.sh index 4f9b3b5d681..2230cdf887d 100755 --- a/docker/ci/entrypoint.sh +++ b/docker/ci/entrypoint.sh @@ -1,5 +1,6 @@ #!/bin/bash -set -e + +set -eo pipefail export PATH="/usr/lib/postgresql/$PGVERSION/bin:$PATH" export JOBS="${CI_JOBS:=$(nproc)}" @@ -166,7 +167,21 @@ run_features() { shopt -s globstar nullglob run_background start_hocuspocus reset_dbs - execute "time bundle exec turbo_tests --verbose -n $JOBS --runtime-log spec/support/runtime-logs/turbo_runtime_features.log {,modules/*/}spec/features/**/*_spec.rb" + + if ! execute "time bundle exec turbo_tests --verbose -n $JOBS --runtime-log spec/support/runtime-logs/turbo_runtime_features.log {,modules/*/}spec/features/**/*_spec.rb"; then + failed_count=$(grep --count ' failed ' tmp/spec_examples.txt 2>/dev/null || echo 0) + if [ "$failed_count" -eq 0 ]; then + echo "failed to find failing examples, unexpected" + exit 1 + elif [ "$failed_count" -le 10 ]; then + echo "retrying $failed_count failed examples" + execute "bundle exec rspec --only-failures --format documentation {,modules/*/}spec/features/**/*_spec.rb" + else + echo "too many failures ($failed_count), not retrying" + exit 1 + fi + fi + cleanup } diff --git a/docker/dev/tls/docker-compose.core-override.example.yml b/docker/dev/tls/docker-compose.core-override.example.yml index 70c0d67a745..543a3e980e7 100644 --- a/docker/dev/tls/docker-compose.core-override.example.yml +++ b/docker/dev/tls/docker-compose.core-override.example.yml @@ -2,6 +2,7 @@ x-op-env-override: &environment OPENPROJECT_CLI_PROXY: "${OPENPROJECT_DEV_URL}" OPENPROJECT_DEV_EXTRA_HOSTS: "${OPENPROJECT_DEV_HOST}" + OPENPROJECT_HOST__NAME: "${OPENPROJECT_DEV_HOST}" OPENPROJECT_HTTPS: true SSL_CERT_FILE: /etc/ssl/certs/ca-certificates.crt # uncomment and set all the envs below to integrate keycloak with OpenProject diff --git a/docs/api/apiv3/openapi-spec.yml b/docs/api/apiv3/openapi-spec.yml index c47cf84d2ad..a23b2192a10 100644 --- a/docs/api/apiv3/openapi-spec.yml +++ b/docs/api/apiv3/openapi-spec.yml @@ -272,20 +272,32 @@ paths: "/api/v3/meetings/{id}": "$ref": "./paths/meeting.yml" "/api/v3/meetings/{id}/agenda_items": - "$ref": "./paths/meeting_agenda_items.yml" + "$ref": "./paths/meeting_agenda_items_by_meeting.yml" "/api/v3/meetings/{meeting_id}/agenda_items/{id}": + "$ref": "./paths/meeting_agenda_item_by_meeting.yml" + "/api/v3/meeting_agenda_items": + "$ref": "./paths/meeting_agenda_items.yml" + "/api/v3/meeting_agenda_items/{id}": "$ref": "./paths/meeting_agenda_item.yml" "/api/v3/meetings/{meeting_id}/agenda_items/{agenda_item_id}/outcomes": "$ref": "./paths/meeting_agenda_item_outcomes.yml" "/api/v3/meetings/{meeting_id}/agenda_items/{agenda_item_id}/outcomes/{id}": "$ref": "./paths/meeting_agenda_item_outcome.yml" + "/api/v3/meeting_outcomes": + "$ref": "./paths/meeting_outcomes.yml" + "/api/v3/meeting_outcomes/{id}": + "$ref": "./paths/meeting_outcome.yml" "/api/v3/meetings/{id}/attachments": "$ref": "./paths/meeting_attachments.yml" "/api/v3/meetings/{id}/form": "$ref": "./paths/meeting_form.yml" "/api/v3/meetings/{id}/sections": - "$ref": "./paths/meeting_sections.yml" + "$ref": "./paths/meeting_sections_by_meeting.yml" "/api/v3/meetings/{meeting_id}/sections/{id}": + "$ref": "./paths/meeting_section_by_meeting.yml" + "/api/v3/meeting_sections": + "$ref": "./paths/meeting_sections.yml" + "/api/v3/meeting_sections/{id}": "$ref": "./paths/meeting_section.yml" "/api/v3/meetings/form": "$ref": "./paths/meetings_form.yml" diff --git a/docs/api/apiv3/paths/meeting_agenda_item.yml b/docs/api/apiv3/paths/meeting_agenda_item.yml index 4c11743260b..8f2de6626ed 100644 --- a/docs/api/apiv3/paths/meeting_agenda_item.yml +++ b/docs/api/apiv3/paths/meeting_agenda_item.yml @@ -1,19 +1,12 @@ -# /api/v3/meetings/{meeting_id}/agenda_items/{id} +# /api/v3/meeting_agenda_items/{id} --- get: summary: Get a meeting agenda item operationId: get_meeting_agenda_item tags: - Meetings - description: Retrieve an individual agenda item of a meeting. + description: Retrieve an individual agenda item. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Agenda item identifier example: 1 in: path @@ -40,7 +33,7 @@ get: errorIdentifier: urn:openproject-org:api:v3:errors:NotFound message: The requested resource could not be found. description: |- - Returned if the agenda item or meeting does not exist or the client does not have sufficient permissions. + Returned if the agenda item does not exist or the client does not have sufficient permissions. patch: summary: Update a meeting agenda item @@ -49,13 +42,6 @@ patch: - Meetings description: Updates the given agenda item. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Agenda item identifier example: 1 in: path @@ -82,12 +68,6 @@ patch: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. description: |- Returned if the client does not have sufficient permissions. @@ -97,14 +77,8 @@ patch: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. description: |- - Returned if the agenda item or meeting does not exist. + Returned if the agenda item does not exist or the client does not have sufficient permissions. '406': $ref: "../components/responses/missing_content_type.yml" '415': @@ -122,13 +96,6 @@ delete: - Meetings description: Deletes the agenda item. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Agenda item identifier example: 1 in: path @@ -144,12 +111,6 @@ delete: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. description: |- Returned if the client does not have sufficient permissions. @@ -159,11 +120,5 @@ delete: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. description: |- - Returned if the agenda item or meeting does not exist. + Returned if the agenda item does not exist or the client does not have sufficient permissions. diff --git a/docs/api/apiv3/paths/meeting_agenda_item_by_meeting.yml b/docs/api/apiv3/paths/meeting_agenda_item_by_meeting.yml new file mode 100644 index 00000000000..0067285a39e --- /dev/null +++ b/docs/api/apiv3/paths/meeting_agenda_item_by_meeting.yml @@ -0,0 +1,43 @@ +# /api/v3/meetings/{meeting_id}/agenda_items/{id} +--- +get: + summary: Get a meeting agenda item + operationId: get_meeting_agenda_item_by_meeting + tags: + - Meetings + description: Retrieve an individual agenda item of a meeting. + parameters: + - description: Meeting identifier + example: 1 + in: path + name: meeting_id + required: true + schema: + type: integer + - description: Agenda item identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_agenda_item_model.yml" + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the agenda item or meeting does not exist or the client does not have sufficient permissions. diff --git a/docs/api/apiv3/paths/meeting_agenda_item_outcome.yml b/docs/api/apiv3/paths/meeting_agenda_item_outcome.yml index 00a6172cd06..c4622ca48b6 100644 --- a/docs/api/apiv3/paths/meeting_agenda_item_outcome.yml +++ b/docs/api/apiv3/paths/meeting_agenda_item_outcome.yml @@ -2,7 +2,7 @@ --- get: summary: Get a meeting outcome - operationId: get_meeting_outcome + operationId: get_meeting_outcome_by_agenda_item tags: - Meetings description: Retrieve an individual outcome of a meeting agenda item. @@ -48,143 +48,3 @@ get: message: The requested resource could not be found. description: |- Returned if the outcome, agenda item, or meeting does not exist or the client does not have sufficient permissions. - -patch: - summary: Update a meeting outcome - operationId: update_meeting_outcome - tags: - - Meetings - description: Updates the given meeting outcome. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - - description: Agenda item identifier - example: 1 - in: path - name: agenda_item_id - required: true - schema: - type: integer - - description: Outcome identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - $ref: "../components/schemas/meeting_outcome_write_model.yml" - responses: - '200': - description: OK - content: - application/hal+json: - schema: - $ref: "../components/schemas/meeting_outcome_model.yml" - '400': - $ref: "../components/responses/invalid_request_body.yml" - '403': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. - description: |- - Returned if the client does not have sufficient permissions. - - **Required permission:** manage outcomes - '404': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. - description: |- - Returned if the outcome, agenda item, or meeting does not exist. - '406': - $ref: "../components/responses/missing_content_type.yml" - '415': - $ref: "../components/responses/unsupported_media_type.yml" - '422': - description: |- - Returned if: - - * a constraint for a property was violated (`PropertyConstraintViolation`) - -delete: - summary: Delete a meeting outcome - operationId: delete_meeting_outcome - tags: - - Meetings - description: Deletes the outcome. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - - description: Agenda item identifier - example: 1 - in: path - name: agenda_item_id - required: true - schema: - type: integer - - description: Outcome identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer - responses: - '204': - description: Returned if the outcome was successfully deleted - '403': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. - description: |- - Returned if the client does not have sufficient permissions. - - **Required permission:** manage outcomes - '404': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. - description: |- - Returned if the outcome, agenda item, or meeting does not exist. diff --git a/docs/api/apiv3/paths/meeting_agenda_item_outcomes.yml b/docs/api/apiv3/paths/meeting_agenda_item_outcomes.yml index 13f5b8f66be..32d096816b8 100644 --- a/docs/api/apiv3/paths/meeting_agenda_item_outcomes.yml +++ b/docs/api/apiv3/paths/meeting_agenda_item_outcomes.yml @@ -43,76 +43,3 @@ get: Returned if the agenda item or meeting does not exist or the client does not have sufficient permissions to see it. **Required permission:** view meetings - -post: - summary: Create meeting outcome - operationId: create_meeting_outcome - tags: - - Meetings - description: Creates a new outcome for the given meeting agenda item. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - - description: Agenda item identifier - example: 1 - in: path - name: agenda_item_id - required: true - schema: - type: integer - requestBody: - content: - application/json: - schema: - $ref: "../components/schemas/meeting_outcome_write_model.yml" - responses: - '201': - description: Created - content: - application/hal+json: - schema: - $ref: "../components/schemas/meeting_outcome_model.yml" - '400': - $ref: "../components/responses/invalid_request_body.yml" - '403': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. - description: |- - Returned if the client does not have sufficient permissions. - - **Required permission:** manage outcomes - '404': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. - description: |- - Returned if the agenda item or meeting does not exist or the client does not have sufficient permissions to see it. - '406': - $ref: "../components/responses/missing_content_type.yml" - '415': - $ref: "../components/responses/unsupported_media_type.yml" - '422': - description: |- - Returned if: - - * a constraint for a property was violated (`PropertyConstraintViolation`) diff --git a/docs/api/apiv3/paths/meeting_agenda_items.yml b/docs/api/apiv3/paths/meeting_agenda_items.yml index 590180f157d..23bf5e6f549 100644 --- a/docs/api/apiv3/paths/meeting_agenda_items.yml +++ b/docs/api/apiv3/paths/meeting_agenda_items.yml @@ -1,56 +1,11 @@ -# /api/v3/meetings/{id}/agenda_items +# /api/v3/meeting_agenda_items --- -get: - summary: List meeting agenda items - operationId: list_meeting_agenda_items - tags: - - Meetings - description: Lists all agenda items for the given meeting. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer - responses: - '200': - description: OK - content: - application/hal+json: - schema: - $ref: "../components/schemas/meeting_agenda_item_collection_model.yml" - '404': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. - description: |- - Returned if the meeting does not exist or the client does not have sufficient permissions to see it. - - **Required permission:** view meetings - post: summary: Create meeting agenda item operationId: create_meeting_agenda_item tags: - Meetings - description: Creates a new agenda item for the given meeting. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer + description: Creates a new agenda item. The request body must link the meeting. requestBody: content: application/json: @@ -92,7 +47,7 @@ post: errorIdentifier: urn:openproject-org:api:v3:errors:NotFound message: The requested resource could not be found. description: |- - Returned if the meeting does not exist or the client does not have sufficient permissions to see it. + Returned if the linked meeting does not exist or the client does not have sufficient permissions to see it. '406': $ref: "../components/responses/missing_content_type.yml" '415': diff --git a/docs/api/apiv3/paths/meeting_agenda_items_by_meeting.yml b/docs/api/apiv3/paths/meeting_agenda_items_by_meeting.yml new file mode 100644 index 00000000000..c49c9e7eb03 --- /dev/null +++ b/docs/api/apiv3/paths/meeting_agenda_items_by_meeting.yml @@ -0,0 +1,38 @@ +# /api/v3/meetings/{id}/agenda_items +--- +get: + summary: List meeting agenda items + operationId: list_meeting_agenda_items + tags: + - Meetings + description: Lists all agenda items for the given meeting. + parameters: + - description: Meeting identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_agenda_item_collection_model.yml" + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the meeting does not exist or the client does not have sufficient permissions to see it. + + **Required permission:** view meetings diff --git a/docs/api/apiv3/paths/meeting_outcome.yml b/docs/api/apiv3/paths/meeting_outcome.yml new file mode 100644 index 00000000000..28581ff2423 --- /dev/null +++ b/docs/api/apiv3/paths/meeting_outcome.yml @@ -0,0 +1,124 @@ +# /api/v3/meeting_outcomes/{id} +--- +get: + summary: Get a meeting outcome + operationId: get_meeting_outcome + tags: + - Meetings + description: Retrieve an individual meeting outcome. + parameters: + - description: Outcome identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_outcome_model.yml" + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the outcome does not exist or the client does not have sufficient permissions. + +patch: + summary: Update a meeting outcome + operationId: update_meeting_outcome + tags: + - Meetings + description: Updates the given meeting outcome. + parameters: + - description: Outcome identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + requestBody: + content: + application/json: + schema: + $ref: "../components/schemas/meeting_outcome_write_model.yml" + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_outcome_model.yml" + '400': + $ref: "../components/responses/invalid_request_body.yml" + '403': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + description: |- + Returned if the client does not have sufficient permissions. + + **Required permission:** manage outcomes + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + description: |- + Returned if the outcome does not exist or the client does not have sufficient permissions. + '406': + $ref: "../components/responses/missing_content_type.yml" + '415': + $ref: "../components/responses/unsupported_media_type.yml" + '422': + description: |- + Returned if: + + * a constraint for a property was violated (`PropertyConstraintViolation`) + +delete: + summary: Delete a meeting outcome + operationId: delete_meeting_outcome + tags: + - Meetings + description: Deletes the outcome. + parameters: + - description: Outcome identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '204': + description: Returned if the outcome was successfully deleted + '403': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + description: |- + Returned if the client does not have sufficient permissions. + + **Required permission:** manage outcomes + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + description: |- + Returned if the outcome does not exist or the client does not have sufficient permissions. diff --git a/docs/api/apiv3/paths/meeting_outcomes.yml b/docs/api/apiv3/paths/meeting_outcomes.yml new file mode 100644 index 00000000000..4cf6088a753 --- /dev/null +++ b/docs/api/apiv3/paths/meeting_outcomes.yml @@ -0,0 +1,59 @@ +# /api/v3/meeting_outcomes +--- +post: + summary: Create meeting outcome + operationId: create_meeting_outcome + tags: + - Meetings + description: Creates a new meeting outcome. The request body must link the agenda item. + requestBody: + content: + application/json: + schema: + $ref: "../components/schemas/meeting_outcome_write_model.yml" + responses: + '201': + description: Created + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_outcome_model.yml" + '400': + $ref: "../components/responses/invalid_request_body.yml" + '403': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission + message: You are not authorized to access this resource. + description: |- + Returned if the client does not have sufficient permissions. + + **Required permission:** manage outcomes + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the linked agenda item does not exist or the client does not have sufficient permissions to see it. + '406': + $ref: "../components/responses/missing_content_type.yml" + '415': + $ref: "../components/responses/unsupported_media_type.yml" + '422': + description: |- + Returned if: + + * a constraint for a property was violated (`PropertyConstraintViolation`) diff --git a/docs/api/apiv3/paths/meeting_section.yml b/docs/api/apiv3/paths/meeting_section.yml index 79c167db431..d06fc3dcb5c 100644 --- a/docs/api/apiv3/paths/meeting_section.yml +++ b/docs/api/apiv3/paths/meeting_section.yml @@ -1,19 +1,12 @@ -# /api/v3/meetings/{meeting_id}/sections/{id} +# /api/v3/meeting_sections/{id} --- get: summary: Get a meeting section operationId: get_meeting_section tags: - Meetings - description: Retrieve an individual section of a meeting. + description: Retrieve an individual meeting section. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Section identifier example: 1 in: path @@ -33,29 +26,16 @@ get: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. description: |- - Returned if the section or meeting does not exist or the client does not have sufficient permissions. + Returned if the section does not exist or the client does not have sufficient permissions. patch: summary: Update a meeting section operationId: update_meeting_section tags: - Meetings - description: Updates the given section. + description: Updates the given meeting section. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Section identifier example: 1 in: path @@ -82,12 +62,6 @@ patch: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. description: |- Returned if the client does not have sufficient permissions. @@ -97,14 +71,8 @@ patch: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. description: |- - Returned if the section or meeting does not exist. + Returned if the section does not exist or the client does not have sufficient permissions. '406': $ref: "../components/responses/missing_content_type.yml" '415': @@ -120,15 +88,8 @@ delete: operationId: delete_meeting_section tags: - Meetings - description: Deletes the section and all its agenda items. + description: Deletes the meeting section. parameters: - - description: Meeting identifier - example: 1 - in: path - name: meeting_id - required: true - schema: - type: integer - description: Section identifier example: 1 in: path @@ -144,12 +105,6 @@ delete: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:MissingPermission - message: You are not authorized to access this resource. description: |- Returned if the client does not have sufficient permissions. @@ -159,11 +114,5 @@ delete: application/hal+json: schema: $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. description: |- - Returned if the section or meeting does not exist. + Returned if the section does not exist or the client does not have sufficient permissions. diff --git a/docs/api/apiv3/paths/meeting_section_by_meeting.yml b/docs/api/apiv3/paths/meeting_section_by_meeting.yml new file mode 100644 index 00000000000..6eaed2fc867 --- /dev/null +++ b/docs/api/apiv3/paths/meeting_section_by_meeting.yml @@ -0,0 +1,43 @@ +# /api/v3/meetings/{meeting_id}/sections/{id} +--- +get: + summary: Get a meeting section + operationId: get_meeting_section_by_meeting + tags: + - Meetings + description: Retrieve an individual section of a meeting. + parameters: + - description: Meeting identifier + example: 1 + in: path + name: meeting_id + required: true + schema: + type: integer + - description: Section identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_section_model.yml" + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the section or meeting does not exist or the client does not have sufficient permissions. diff --git a/docs/api/apiv3/paths/meeting_sections.yml b/docs/api/apiv3/paths/meeting_sections.yml index 5d5bf04218a..db095f5071f 100644 --- a/docs/api/apiv3/paths/meeting_sections.yml +++ b/docs/api/apiv3/paths/meeting_sections.yml @@ -1,56 +1,11 @@ -# /api/v3/meetings/{id}/sections +# /api/v3/meeting_sections --- -get: - summary: List meeting sections - operationId: list_meeting_sections - tags: - - Meetings - description: Lists all sections for the given meeting. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer - responses: - '200': - description: OK - content: - application/hal+json: - schema: - $ref: "../components/schemas/meeting_section_collection_model.yml" - '404': - content: - application/hal+json: - schema: - $ref: "../components/schemas/error_response.yml" - examples: - response: - value: - _type: Error - errorIdentifier: urn:openproject-org:api:v3:errors:NotFound - message: The requested resource could not be found. - description: |- - Returned if the meeting does not exist or the client does not have sufficient permissions to see it. - - **Required permission:** view meetings - post: summary: Create meeting section operationId: create_meeting_section tags: - Meetings - description: Creates a new section for the given meeting. - parameters: - - description: Meeting identifier - example: 1 - in: path - name: id - required: true - schema: - type: integer + description: Creates a new section. The request body must link the meeting. requestBody: content: application/json: @@ -92,7 +47,7 @@ post: errorIdentifier: urn:openproject-org:api:v3:errors:NotFound message: The requested resource could not be found. description: |- - Returned if the meeting does not exist or the client does not have sufficient permissions to see it. + Returned if the linked meeting does not exist or the client does not have sufficient permissions to see it. '406': $ref: "../components/responses/missing_content_type.yml" '415': diff --git a/docs/api/apiv3/paths/meeting_sections_by_meeting.yml b/docs/api/apiv3/paths/meeting_sections_by_meeting.yml new file mode 100644 index 00000000000..e54b6956670 --- /dev/null +++ b/docs/api/apiv3/paths/meeting_sections_by_meeting.yml @@ -0,0 +1,38 @@ +# /api/v3/meetings/{id}/sections +--- +get: + summary: List meeting sections + operationId: list_meeting_sections + tags: + - Meetings + description: Lists all sections for the given meeting. + parameters: + - description: Meeting identifier + example: 1 + in: path + name: id + required: true + schema: + type: integer + responses: + '200': + description: OK + content: + application/hal+json: + schema: + $ref: "../components/schemas/meeting_section_collection_model.yml" + '404': + content: + application/hal+json: + schema: + $ref: "../components/schemas/error_response.yml" + examples: + response: + value: + _type: Error + errorIdentifier: urn:openproject-org:api:v3:errors:NotFound + message: The requested resource could not be found. + description: |- + Returned if the meeting does not exist or the client does not have sufficient permissions to see it. + + **Required permission:** view meetings diff --git a/docs/glossary/README.md b/docs/glossary/README.md index 75dafaa325a..fd88e86fcd0 100644 --- a/docs/glossary/README.md +++ b/docs/glossary/README.md @@ -82,7 +82,7 @@ In OpenProject, authentication is an important element to guarantee a data prote Backlogs is a [module](#module) in OpenProject that brings features that support [Agile project management](#agile-project-management), in particular the Scrum methodology, such as a product backlog and sprint backlogs. -It includes functionality for planning and managing sprints, including a sprint board that is automatically created when a sprint is started. Within the backlog, work packages can be organized using **backlog buckets** to group items into clearly defined sections. Work packages that are not assigned to a backlog bucket or a sprint are listed in the **index backlog**. +It includes functionality for planning and managing [sprints](#sprint), including a sprint [board](#board) that is automatically created when a sprint is started. Within the backlog, work packages can be organized using **backlog buckets** to group items into clearly defined sections. Work packages that are not assigned to a backlog bucket or a sprint are listed in the **inbox** backlog bucket. To use backlogs in OpenProject, the Backlogs module has to be activated in the [project settings](#project-settings) by a project admin. @@ -98,7 +98,7 @@ BIM stands for Building Information Modeling. In OpenProject, we offer a special ### Board -A board in OpenProject is a view that allows you to see your work packages as cards divided into columns. A board is a typical element in [agile project management](#agile-project-management), supporting methodologies such as Scrum or Kanban. OpenProject, you can use a [basic board](../user-guide/agile-boards/#basic-boards) or [advanced Action boards](../user-guide/agile-boards). Use advanced Action boards to quickly change attributes of your work package. [Read more about boards for agile project management](../user-guide/agile-boards/). +A board in OpenProject is a view that allows you to see your work packages as cards divided into columns. A board is a typical element in [agile project management](#agile-project-management), supporting methodologies such as Scrum or Kanban. In OpenProject, you can use a [basic board](../user-guide/agile-boards/#basic-boards) or [advanced Action boards](../user-guide/agile-boards). Use advanced Action boards to quickly change attributes of your work package. [Read more about boards for agile project management](../user-guide/agile-boards/). **More information on boards in OpenProject** @@ -200,7 +200,7 @@ Excel synchronization is an integration in OpenProject which allows you to easil ### File storage -File storages can be configured in the System Administration and then be selected in the [project settings](#project-settings). OpenProject offers a [Nextcloud integration](#nextcloud-integration) to support file storage. [More information on file storage with the Nextcloud integration](../user-guide/file-management/nextcloud-integration/). +File storages can be configured in the system administration and then be selected in the [project settings](#project-settings). OpenProject offers a [Nextcloud integration](#nextcloud-integration) to support file storage. [More information on file storage with the Nextcloud integration](../user-guide/file-management/nextcloud-integration/). ### Filters @@ -218,11 +218,11 @@ The Gantt charts [module](#module) in OpenProject displays the work packages in ### Global modules -In OpenProject, global modules are defined as a menu to access all [modules](#module) for *all* your projects. With global modules you can easily see all your project-overarching information at one place, e.g. for work packages, boards, calendars or meetings. Click on the grid icon on the left side of the header menu to access the global modules. [Read more about global modules in OpenProject](../user-guide/home/global-modules/). +In OpenProject, global modules are defined as a menu to access all [modules](#module) for *all* your projects. With global modules you can easily see all your project-overarching information at one place, e.g. for [work packages](#work-package), [boards](#board), calendars or [meetings](#meetings). Click on the grid icon on the left side of the header menu to access the global modules. [Read more about global modules in OpenProject](../user-guide/home/global-modules/). ### Group -A group in OpenProject is defined as a list of users which can be added as a member to projects with a selected [role](#role). Groups can also be assigned to work packages. New groups can be defined in *Administration → Users and permissions → Groups*. +A group in OpenProject is defined as a list of users which can be added as a member to projects with a selected [role](#role). Groups can also be assigned to work packages. They can be nested to represent organizational structures and inherit permissions from parent groups. New groups can be defined in *Administration → Users and permissions → Groups*. ## H @@ -343,7 +343,7 @@ OpenProject on-premises is a self-hosted version of OpenProject. As opposed to t **More information on OpenProject on-premises** -- [See our pricing side about your options for OpenProject](https://www.openproject.org/pricing/). +- [See our pricing page about your options for OpenProject](https://www.openproject.org/pricing/). - [Read a blog article comparing on-premises and cloud](https://www.openproject.org/blog/why-self-hosting-software/). - [Read how to activate the Enterprise on-premises edition](../enterprise-guide/enterprise-on-premises-guide/activate-enterprise-on-premises/). - [Read how to start a trial for Enterprise on-premises](../enterprise-guide/enterprise-on-premises-guide/enterprise-on-premises-trial/). @@ -379,7 +379,7 @@ PM² is a project management framework developed by the European Commission to s ### PMflex -PMflex is is a comprehensive and flexible project management system based on the European [PM²](#pm--pm2) standard and further developed for public administration in Germany. [Read more about how to use PMflex with OpenProject](https://www.openproject.org/pmflex). If you are looking for specific PMflex terminology, please see our [use case of implementing PM² and PMflex project management in OpenProject](../use-cases/project-management-pm2-pmflex/#implementing-pm-and-pmflex-project-management-in-openproject). +PMflex is a comprehensive and flexible project management system based on the European [PM²](#pm--pm2) standard and further developed for public administration in Germany. [Read more about how to use PMflex with OpenProject](https://www.openproject.org/pmflex). If you are looking for specific PMflex terminology, please see our [use case of implementing PM² and PMflex project management in OpenProject](../use-cases/project-management-pm2-pmflex/#implementing-pm-and-pmflex-project-management-in-openproject). ### Portfolio @@ -388,7 +388,7 @@ In OpenProject, you can manage your project portfolio by creating, filtering and ### Primer design system -OpenProject started adopting [Github's Primer Design System](https://primer.style/) in 2023. New features will be developed using Primer and existing features will will be gradually revised. Relevant reusable components from Primer as well as common patterns and compositions of these components will be documented in our [Lookbook](https://qa.openproject-edge.com/lookbook/pages/how_to_use). [Read more about OpenProject's decision to use Primer](https://www.openproject.org/blog/primer-design-system/). +OpenProject started adopting [Github's Primer Design System](https://primer.style/) in 2023. New features will be developed using Primer and existing features will be gradually revised. Relevant reusable components from Primer as well as common patterns and compositions of these components will be documented in our [Lookbook](https://qa.openproject-edge.com/lookbook/pages/how_to_use). [Read more about OpenProject's decision to use Primer](https://www.openproject.org/blog/primer-design-system/). ### Project @@ -404,9 +404,7 @@ A project attribute in OpenProject is a [custom field](#custom-field) that appli ### Project folder -Project folders help collaborating in the most efficient way. They can be used with -OpenProject's [Nextcloud integration](#nextcloud-integration) or with -OpenProject's [OneDrive integration](#onedrive-integration). [Read more about project folders in OpenProject](../user-guide/projects/project-settings/files/#project-folders). +Project folders help collaborating in the most efficient way. They can be used with OpenProject's [Nextcloud integration](#nextcloud-integration) or with OpenProject's [OneDrive integration](#onedrive-integration). [Read more about project folders in OpenProject](../user-guide/projects/project-settings/files/#project-folders). ### Project home @@ -437,7 +435,7 @@ Phases and phase gates are visible on the [project home](#project-home) page, in ### Project lists -In OpenProject, project lists are very useful for project portfolio managers to get an overview of all their [projects](#project) on the instance. Access your project lists on OpenProject by either navigating to the "All projects" menu and clicking on the "Project lists" button, or via the [Global modules](#global-modules). [Read more about project lists OpenProject](../user-guide/projects/project-lists/). +In OpenProject, project lists are very useful for project portfolio managers to get an overview of all their [projects](#project) on the instance. Access your project lists on OpenProject by either navigating to the "All projects" menu and clicking on the "Project lists" button, or via the [Global modules](#global-modules). [Read more about project lists in OpenProject](../user-guide/projects/project-lists/). ### Project navigation @@ -481,7 +479,7 @@ In OpenProject, you can set work packages in relation to each other. Some relati OpenProject offers different types of reminders so that you can lean back and never forget a task. One is the [date alert](#date-alerts) (Enterprise add-on), which generates automatic and customized [notifications](#notifications) regarding a work package's due date or start date. -OpenProject also allows you to set **work package reminders**: Simply activate the clock icon on top of a work package and choose from different options, e.g. to be reminded the next day (at 9 am) or in one week. You can also set a custom date. [Read more about work package reminders in OpenProject](../user-guide/work-packages/edit-work-package/#work-package-reminders). +OpenProject also allows you to set **work package reminders**: Simply activate the clock icon on top of a work package and choose from different options, e.g. to be reminded the next day (at 9 am) or in one week. You can also set a custom date. [Read more about work package reminders in OpenProject](../user-guide/work-packages/edit-work-package/#work-package-reminders). ### Repository @@ -509,6 +507,10 @@ SAML (Security Assertion Markup Language) is an open standard for exchanging aut OpenProject offers the possibility to share work packages with external groups or users that are not [members](#member) of the project. This feature is an [Enterprise add-on](#enterprise-add-on). Every user with whom a work package is shared must either already be a user of the instance or be newly created. The latter requires special rights. [Read more about OpenProject's feature to share work packages with project non-members](../user-guide/work-packages/share-work-packages/). +### Sprint + +A sprint is a time-boxed iteration used in agile project management to plan and execute work during a defined period. In OpenProject, sprints are managed through the [Backlogs](#backlogs) module and include attributes such as start and end dates. Sprint [boards](#board) are automatically created when a sprint is started. + ### Story points Story points is a term known in Scrum. They are defined as numbers assigned to a [work package](#work-package) used to estimate (relatively) the size of the work. In OpenProject, you can add story points to work packages. [Read how to work with story points in OpenProject](../user-guide/backlogs-scrum/#story-points). @@ -545,7 +547,7 @@ The OpenProject [user guide](../user-guide/) is an in-depth guide of all feature ### Versions -Versions in OpenProject are defined as an attribute for [work packages](#work-package) or in the [Backlogs](#backlogs) module. Versions will be displayed in the [Roadmap](#roadmap). In the [Enterprise edition](#enterprise-add-on), you can also create a version [board](#board) to get an overview of the progress of your versions. [Read more about how to manage versions in OpenProject](../user-guide/projects/project-settings/versions/). +Versions in OpenProject are used to group and organize work packages, for example to plan releases, milestones, or delivery targets. Versions are displayed in the [Roadmap](#roadmap) and can be assigned to work packages as an attribute. You can also create a version [board](#board) to get an overview of the progress of your versions. [Read more about how to manage versions in OpenProject](../user-guide/projects/project-settings/versions/). ## W @@ -569,7 +571,8 @@ In OpenProject, a wiki is defined as a [module](#module) that allows to use wiki ### Work, Remaining Work and % Complete -In OpenProject, '**Work**' refers to a work package attribute indicating the estimated hours and days needed to complete a task. +In OpenProject, '**Work**' refers to a work package attribute indicating the estimated hours and days needed to complete a task. + '**Remaining work**' is a work package attribute that shows how much work is left to finish the work package. It is automatically calculated if you work with [status-based progress reporting](../user-guide/time-and-costs/progress-tracking/#status-based-progress-reporting). And '**% Complete**' is an automatically calculated work package attribute that shows in percentage how much work is already completed. All three attributes are important for [progress reporting with OpenProject](https://www.openproject.org/blog/changes-progress-work-estimates/). To make it easier for project managers to work with work package hierarchies, OpenProject also displays a value (in blue) for the total amount of work in the Work field for parent work packages – next to the value for the dedicated work package. This **total work value** is the sum of the work value of the parent work package and all the work values of its children. The same principle applies to the work package attribute Remaining Work. [Read in our user guide about how to configure a work package](../user-guide/work-packages/work-package-table-configuration/) @@ -599,7 +602,11 @@ If you need a Category that applies to all projects on your instance, we recomme ### Work package ID -Work package ID is defined as a unique ascending number assigned to a newly created work package. Work package IDs cannot be changed and are numbered across all projects of an OpenProject instance (therefore, the numbering within a project may not be sequential). +In OpenProject, every work package has a unique ID (identifier). It is automatically assigned when a work package is created. Work package IDs are configured globally and apply across the entire OpenProject instance. + +By default, work package IDs are numerical, ascending numbers, for example #429. System [administrators](#admin) can optionally switch to project-based work package IDs, which consist of a project-specific prefix and an ascending number (e.g. OP-382). Project-based identifiers that have been used are [reserved and can be released if necessary](../system-admin-guide/projects/reserved-project-identifiers/) so that they can be used again. + +Administrators can configure work package identifiers under *Administration → Work packages → Identifiers*. [Read more in the OpenProject system admin guide](../user-guide/projects/project-settings/project-information/#change-project-identifier). ### Work package subject @@ -617,7 +624,7 @@ Work package types are the different items a work package can represent. Each wo ### Work package view -A list of work packages is considered a view. The containing work packages in any view can be displayed a number of different ways. Examples for most used work package views are the [table view](#work-package-table), the full screen view or the split screen view. You can also display work packages in a card view and use them in a [board](#board) to use agile methods. [Read more about work package views in OpenProject](../user-guide/work-packages/work-package-views/#work-packages-views). +A list of work packages is considered a view. The containing work packages in any view can be displayed a number of different ways. Examples for most used work package views are the [table view](#work-package-table), the full screen view or the split screen view. You can also display work packages in a card view and use them in a [board](#board) to use agile methods. [Read more about work package views in OpenProject](../user-guide/work-packages/work-package-views/#work-packages-views). ### WYSIWYG editor diff --git a/docs/release-notes/17-3-3/README.md b/docs/release-notes/17-3-3/README.md new file mode 100644 index 00000000000..4b185833b06 --- /dev/null +++ b/docs/release-notes/17-3-3/README.md @@ -0,0 +1,80 @@ +--- +title: OpenProject 17.3.3 +sidebar_navigation: + title: 17.3.3 +release_version: 17.3.3 +release_date: 2026-06-08 +--- + +# OpenProject 17.3.3 + +Release date: 2026-06-08 + +We released [OpenProject 17.3.3](https://community.openproject.org/versions/2299). +The release contains several bug fixes and we recommend updating to the newest version. +Below you will find a complete list of all changes and bug fixes. + +## Security fixes + +### CVE-2026-47193 - Journal diff endpoint bypasses object, journal, and field visibility checks +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-f2rx-x2qj-2hgj](https://github.com/opf/openproject/security/advisories/GHSA-f2rx-x2qj-2hgj) + +### GHSA-3vpx-94qx-xpw6 - IDOR through /projects//settings/project_storages/ via PATCH parameter "storages_project_storage[project_folder_id]" leads to Access to Unauthorized Resources +A project-admin in one project can hijack the managed Nextcloud or OneDrive folder of another project on the same storage by writing the victim project's `project_folder_id` into the attacker's `Storages::ProjectStorage` row. The next managed-folder sync overwrites the ACL on the referenced folder with the attacker project's user list. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-3vpx-94qx-xpw6](https://github.com/opf/openproject/security/advisories/GHSA-3vpx-94qx-xpw6) + +### GHSA-6crw-7f5r-4qj9 - CSRF on TARGET through /users/:id via POST parameter "user[admin]" +Turbo Drive auto-injects CSRF tokens (from ``) on forms injected via the XSS's `append` Turbo Stream action. A second action, `dispatch_event` with `name="submit"`, auto-submits the form with no victim interaction beyond viewing the work package, resulting in a CSRF attack + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-6crw-7f5r-4qj9](https://github.com/opf/openproject/security/advisories/GHSA-6crw-7f5r-4qj9) + +### GHSA-98vw-2r87-fx2r - SQL injection in timestamps functionality +OpenProject baseline comparison allows callers to request historic work-package attributes using the `timestamps` parameter. + +The timestamp parser accepts a relative date keyword on the first line because its regular expression uses line anchors. The parser validates the input, but the original multi-line string is kept and later interpolated into a raw SQL `CASE ... THEN ''` expression. + +An authenticated user who can save a query can persist a timestamp array value containing literal commas and trigger a top-level data-modifying CTE. This gives the attacker a generic database write primitive as the OpenProject application database role. + +The demonstrated impact is administrator privilege escalation: the attacker uses that write primitive to update their own account record, setting the account's administrator flag to true. The same injection also allows in-band data disclosure through work-package timestamp metadata. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-98vw-2r87-fx2r](https://github.com/opf/openproject/security/advisories/GHSA-98vw-2r87-fx2r) + +### GHSA-h83w-5q5x-pq27 - Information Disclosure (cleartext storage of data) on localhost through memcached via Others "storage..httpx_access_token" leads to Sensitive Data Exposure +OpenProject's Storages module writes the OneDrive/SharePoint userless OAuth `access_token` plaintext to `Rails.cache` under the deterministic key `storage..httpx_access_token`, repopulated continuously by an hourly cron and every userless-OAuth call site (see Write cadence). None of the three allowed cache backends (`file_store`, `memcache`, `redis`) encrypts at rest. An attacker with read access to the cache backend recovers the Azure-AD application-tier bearer with an anonymous `get` over the memcached binary protocol (or the equivalent against Redis) + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-h83w-5q5x-pq27](https://github.com/opf/openproject/security/advisories/GHSA-h83w-5q5x-pq27) + +### GHSA-q33w-f822-hg8x - Stored XSS on openproject.example.com through /api/v3/projects/{project}/work_packages via POST parameter "description" +The HTML sanitizer grants `` elements unrestricted `data-*` attributes via `:data` wildcard. An attacker injects `data-controller="poll-for-changes"` into a work package description, causing Stimulus.js to mount a controller that fetches an attacker-uploaded attachment and passes it to `renderStreamMessage()`. This executes arbitrary Turbo Stream actions — including `redirect_to` — in every victim's authenticated browser session, redirecting them to an attacker-controlled server. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-q33w-f822-hg8x](https://github.com/opf/openproject/security/advisories/GHSA-q33w-f822-hg8x) + +### GHSA-qj96-f42f-6336 - Cache store poisoning leads to Remote Code Execution (RCE) +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-qj96-f42f-6336](https://github.com/opf/openproject/security/advisories/GHSA-qj96-f42f-6336) + + + + +## Bug fixes and changes + + + + + + + diff --git a/docs/release-notes/17-3-4/README.md b/docs/release-notes/17-3-4/README.md new file mode 100644 index 00000000000..0c91883b729 --- /dev/null +++ b/docs/release-notes/17-3-4/README.md @@ -0,0 +1,28 @@ +--- +title: OpenProject 17.3.4 +sidebar_navigation: + title: 17.3.4 +release_version: 17.3.4 +release_date: 2026-06-08 +--- + +# OpenProject 17.3.4 + +Release date: 2026-06-08 + +We released [OpenProject 17.3.4](https://community.openproject.org/versions/2305). +The release contains several bug fixes and we recommend updating to the newest version. +Below you will find a complete list of all changes and bug fixes. + + + + +## Bug fixes and changes + + + + +- Bugfix: Memcached serialization is broken in 17.3.3 \[[#75753](https://community.openproject.org/wp/75753)\] + + + diff --git a/docs/release-notes/17-4-1/README.md b/docs/release-notes/17-4-1/README.md new file mode 100644 index 00000000000..4122ed32c8d --- /dev/null +++ b/docs/release-notes/17-4-1/README.md @@ -0,0 +1,92 @@ +--- +title: OpenProject 17.4.1 +sidebar_navigation: + title: 17.4.1 +release_version: 17.4.1 +release_date: 2026-06-08 +--- + +# OpenProject 17.4.1 + +Release date: 2026-06-08 + +We released [OpenProject 17.4.1](https://community.openproject.org/versions/2301). +The release contains several bug fixes and we recommend updating to the newest version. +Below you will find a complete list of all changes and bug fixes. + +## Security fixes + +### CVE-2026-47193 - Journal diff endpoint bypasses object, journal, and field visibility checks +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-f2rx-x2qj-2hgj](https://github.com/opf/openproject/security/advisories/GHSA-f2rx-x2qj-2hgj) + +### CVE-2026-49355 - Private work package data disclosure through single meeting agenda item API +`GET /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id` discloses private work package data from a linked work package that belongs to a private/inaccessible project. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-g387-6rm2-xw88](https://github.com/opf/openproject/security/advisories/GHSA-g387-6rm2-xw88) + +### GHSA-3vpx-94qx-xpw6 - IDOR through /projects//settings/project_storages/ via PATCH parameter "storages_project_storage[project_folder_id]" leads to Access to Unauthorized Resources +A project-admin in one project can hijack the managed Nextcloud or OneDrive folder of another project on the same storage by writing the victim project's `project_folder_id` into the attacker's `Storages::ProjectStorage` row. The next managed-folder sync overwrites the ACL on the referenced folder with the attacker project's user list. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-3vpx-94qx-xpw6](https://github.com/opf/openproject/security/advisories/GHSA-3vpx-94qx-xpw6) + +### GHSA-6crw-7f5r-4qj9 - CSRF on TARGET through /users/:id via POST parameter "user[admin]" +Turbo Drive auto-injects CSRF tokens (from ``) on forms injected via the XSS's `append` Turbo Stream action. A second action, `dispatch_event` with `name="submit"`, auto-submits the form with no victim interaction beyond viewing the work package, resulting in a CSRF attack + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-6crw-7f5r-4qj9](https://github.com/opf/openproject/security/advisories/GHSA-6crw-7f5r-4qj9) + +### GHSA-98vw-2r87-fx2r - SQL injection in timestamps functionality +OpenProject baseline comparison allows callers to request historic work-package attributes using the `timestamps` parameter. + +The timestamp parser accepts a relative date keyword on the first line because its regular expression uses line anchors. The parser validates the input, but the original multi-line string is kept and later interpolated into a raw SQL `CASE ... THEN ''` expression. + +An authenticated user who can save a query can persist a timestamp array value containing literal commas and trigger a top-level data-modifying CTE. This gives the attacker a generic database write primitive as the OpenProject application database role. + +The demonstrated impact is administrator privilege escalation: the attacker uses that write primitive to update their own account record, setting the account's administrator flag to true. The same injection also allows in-band data disclosure through work-package timestamp metadata. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-98vw-2r87-fx2r](https://github.com/opf/openproject/security/advisories/GHSA-98vw-2r87-fx2r) + +### GHSA-h83w-5q5x-pq27 - Information Disclosure (cleartext storage of data) on localhost through memcached via Others "storage..httpx_access_token" leads to Sensitive Data Exposure +OpenProject's Storages module writes the OneDrive/SharePoint userless OAuth `access_token` plaintext to `Rails.cache` under the deterministic key `storage..httpx_access_token`, repopulated continuously by an hourly cron and every userless-OAuth call site (see Write cadence). None of the three allowed cache backends (`file_store`, `memcache`, `redis`) encrypts at rest. An attacker with read access to the cache backend recovers the Azure-AD application-tier bearer with an anonymous `get` over the memcached binary protocol (or the equivalent against Redis) + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-h83w-5q5x-pq27](https://github.com/opf/openproject/security/advisories/GHSA-h83w-5q5x-pq27) + +### GHSA-q33w-f822-hg8x - Stored XSS on openproject.example.com through /api/v3/projects/{project}/work_packages via POST parameter "description" +The HTML sanitizer grants `` elements unrestricted `data-*` attributes via `:data` wildcard. An attacker injects `data-controller="poll-for-changes"` into a work package description, causing Stimulus.js to mount a controller that fetches an attacker-uploaded attachment and passes it to `renderStreamMessage()`. This executes arbitrary Turbo Stream actions — including `redirect_to` — in every victim's authenticated browser session, redirecting them to an attacker-controlled server. + +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-q33w-f822-hg8x](https://github.com/opf/openproject/security/advisories/GHSA-q33w-f822-hg8x) + +### GHSA-qj96-f42f-6336 - Cache store poisoning leads to Remote Code Execution (RCE) +This vulnerability was reported as part of the [YesWeHack.com OpenProject Bug Bounty program](https://yeswehack.com/programs/openproject), sponsored by the European Commission. + +For more information, please see the [GitHub advisory #GHSA-qj96-f42f-6336](https://github.com/opf/openproject/security/advisories/GHSA-qj96-f42f-6336) + + + + +## Bug fixes and changes + + + + +- Bugfix: Migration 20250929070310 failing due to update code failing on not-yet fully migrated schema \[[#75286](https://community.openproject.org/wp/75286)\] + + + + +## Contributions +A big thanks to our Community members for reporting bugs and helping us identify and provide fixes. +This release, special thanks for reporting and finding bugs go to Alexander Aleschenko. diff --git a/docs/release-notes/17-6-0/README.md b/docs/release-notes/17-6-0/README.md index 7fe7625d46d..f1e43f576e6 100644 --- a/docs/release-notes/17-6-0/README.md +++ b/docs/release-notes/17-6-0/README.md @@ -3,12 +3,12 @@ title: OpenProject 17.6.0 sidebar_navigation: title: 17.6.0 release_version: 17.6.0 -release_date: 2026-06-08 +release_date: 2026-06-10 --- # OpenProject 17.6.0 -Release date: 2026-06-08 +Release date: 2026-06-10 We released [OpenProject 17.6.0](https://community.openproject.org/versions/2298). The release contains several bug fixes and we recommend updating to the newest version. @@ -19,7 +19,32 @@ In these Release Notes, we will give an overview of important feature changes. A ## Important updates and breaking changes - +### Integrations (e.g. Nextcloud and XWiki) respect global SSRF filters + +To increase the security of OpenProject installations, we've added protections against server-side request forgery in previous releases +of OpenProject. These prevent OpenProject from making network requests into private IP address space. + +Starting with OpenProject 17.6, these protections expand into the code that's responsible for web requests of storage and wiki integrations as well. +This means if you have a Nextcloud instance or an XWiki instance reachable via a private (i.e. not publicly routable) IP address, you need to +add it to the SSRF allowlist to be able to keep the integration working. This is usually achieved by defining the following environment variable: + +``` +OPENPROJECT_SSRF_PROTECTION_IP_ALLOWLIST=2001:db8:100::/48 +``` + +The list accepts one or multiple IP addresses or ranges (in CIDR notation) that shall be exempt from SSRF filtering. + +### Meeting API structure changes + +17.6. introduces new endpoints for meeting outcomes, +and changes the self link for all meeting related resources to be flat: + +That means, some of the responses have changed: + +POST/PATCH/DELETE `/api/v3/meetings/:id/agenda_items)` is no longer available, +they have been moved to the `/api/v3/meeting_agendas/` respectively. The same is true for outcomes and sections. + +This follows the APIv3 standards, and also fixes a bug related to the self link. @@ -31,70 +56,129 @@ In these Release Notes, we will give an overview of important feature changes. A -- Feature: Sprint goals \[[#71059](https://community.openproject.org/wp/71059)\] -- Feature: Add possibility to order backlog buckets and sprints manually \[[#73610](https://community.openproject.org/wp/73610)\] -- Feature: Add multi-select drop-down for sprint and backlog buckets \[[#73611](https://community.openproject.org/wp/73611)\] -- Feature: Multi-select cards within backlog and sprints \[[#73729](https://community.openproject.org/wp/73729)\] -- Feature: Display backlog bucket in work package page \[[#73887](https://community.openproject.org/wp/73887)\] -- Feature: "Move to backlog bucket" and "move to backlog inbox" menu option for work packages within the backlog module \[[#73925](https://community.openproject.org/wp/73925)\] -- Feature: Add existing work packages within sprint and backlog containers menu \[[#74386](https://community.openproject.org/wp/74386)\] -- Feature: "All sprints" view - simple list \[[#74594](https://community.openproject.org/wp/74594)\] -- Feature: Column, ordering and grouping by backlog bucket in work package list \[[#74653](https://community.openproject.org/wp/74653)\] -- Feature: Show message when work package with excluded type/status is moved to backlog and disappears \[[#74845](https://community.openproject.org/wp/74845)\] -- Feature: Check the accessibility on Flash messages \[[#63276](https://community.openproject.org/wp/63276)\] -- Feature: Remove newest projects in project widget on homepage \[[#74198](https://community.openproject.org/wp/74198)\] -- Feature: Make project hierarchy collapsable in the global project selector \[[#74625](https://community.openproject.org/wp/74625)\] -- Feature: Create work package out of Meeting Agenda Item \[[#57053](https://community.openproject.org/wp/57053)\] -- Feature: API for Meeting outcomes \[[#75393](https://community.openproject.org/wp/75393)\] -- Feature: Group synchronization through attributes of the group, not member/memberOf \[[#32812](https://community.openproject.org/wp/32812)\] -- Feature: Track working hours and availabilities for each user in the system \[[#34911](https://community.openproject.org/wp/34911)\] -- Feature: Allow cost types to be enabled/disabled per project \[[#42037](https://community.openproject.org/wp/42037)\] -- Feature: All open view with default sort order to show the latest on top (ID descending) \[[#57962](https://community.openproject.org/wp/57962)\] -- Feature: New Administration for User Custom Fields and Custom Field Sections \[[#72005](https://community.openproject.org/wp/72005)\] -- Feature: Primerize advanced filters component \[[#74380](https://community.openproject.org/wp/74380)\] -- Feature: Build Primer quickfilter \[[#74577](https://community.openproject.org/wp/74577)\] -- Feature: Enforce order of subheader slots/quickfilters \[[#75013](https://community.openproject.org/wp/75013)\] -- Feature: Escape possible control characters in CSV export \[[#75486](https://community.openproject.org/wp/75486)\] -- Feature: Filter project by portfolio and programm \[[#74718](https://community.openproject.org/wp/74718)\] -- Feature: Adapt Excel and CSV exports for semantic identifiers \[[#74361](https://community.openproject.org/wp/74361)\] -- Feature: Adapt BCF Export and Import for semantic identifiers \[[#74362](https://community.openproject.org/wp/74362)\] -- Feature: Adapt other PDF exports for semantic identifiers \[[#75229](https://community.openproject.org/wp/75229)\] -- Feature: /wp on an empty line should create a block work-package link, not an inline one \[[#75310](https://community.openproject.org/wp/75310)\] -- Feature: Expose installation UUID via API \[[#75442](https://community.openproject.org/wp/75442)\] -- Feature: Configure internal wiki provider \[[#75594](https://community.openproject.org/wp/75594)\] -- Feature: Show total sprint capacity (in days or story points) \[[#71060](https://community.openproject.org/wp/71060)\] -- Feature: "All Sprints" view \[[#71260](https://community.openproject.org/wp/71260)\] -- Feature: Allow multiple active sprints within a single project \[[#73232](https://community.openproject.org/wp/73232)\] -- Feature: XWiki integration \[[#53738](https://community.openproject.org/wp/53738)\] -- Feature: Extend CKEditor with Wiki interactions and macros \[[#70554](https://community.openproject.org/wp/70554)\] -- Feature: Wiki tab in work package detail view \[[#70555](https://community.openproject.org/wp/70555)\] -- Feature: Wiki integration setup on OpenProject \[[#70556](https://community.openproject.org/wp/70556)\] -- Bugfix: Page loads twice after sprint creation \[[#73316](https://community.openproject.org/wp/73316)\] -- Bugfix: A missing full stop at the end of confirmation message of danger dialog \[[#73899](https://community.openproject.org/wp/73899)\] -- Bugfix: Impossible to open work packages list from the sidebar after visiting team planner \[[#74331](https://community.openproject.org/wp/74331)\] -- Bugfix: Input group with trailing action clipboard copy button + validation error = style broken \[[#75395](https://community.openproject.org/wp/75395)\] -- Bugfix: FilterableTreeView does not keep default filter arguments \[[#75617](https://community.openproject.org/wp/75617)\] -- Bugfix: Tree view selection based on path identity breaks use cases where similar paths are allowed \[[#75618](https://community.openproject.org/wp/75618)\] -- Bugfix: Fix tracking expression browser warnings \[[#75676](https://community.openproject.org/wp/75676)\] -- Bugfix: GET /api/v3/meetings/{id} — \_links.participants count does not match \_embedded.participants count \[[#75696](https://community.openproject.org/wp/75696)\] -- Bugfix: PATCH /api/v3/meetings/{id} — adding an already existing participant via \_links.participants creates a duplicate entry \[[#75697](https://community.openproject.org/wp/75697)\] -- Bugfix: PATCH /api/v3/meetings/{id} - participants cannot be removed via \_links.participants \[[#75701](https://community.openproject.org/wp/75701)\] -- Bugfix: WP table configuration: overflow due to the very long CF label \[[#46005](https://community.openproject.org/wp/46005)\] -- Bugfix: Tooltip on Team planner not entirely visible \[[#48223](https://community.openproject.org/wp/48223)\] -- Bugfix: Problems with GitLab and GitHub integration snippets \[[#56847](https://community.openproject.org/wp/56847)\] -- Bugfix: Misalignment of fields in Work estimates and progress when language=DE \[[#65738](https://community.openproject.org/wp/65738)\] -- Bugfix: Custom text widget pagination bug \[[#66419](https://community.openproject.org/wp/66419)\] -- Bugfix: Arrow for switching years barely visible in dark mode on the calendar \[[#68517](https://community.openproject.org/wp/68517)\] -- Bugfix: Login right side panel dark mode: login form has ugly/unnecessary gray background \[[#69328](https://community.openproject.org/wp/69328)\] -- Bugfix: User sees a success banner if they save a letter/word as integer \[[#71650](https://community.openproject.org/wp/71650)\] -- Bugfix: Closed, duplicated meeting disappears from synced calendar \[[#72219](https://community.openproject.org/wp/72219)\] -- Bugfix: Wrong icon used when changing non working days \[[#73372](https://community.openproject.org/wp/73372)\] -- Bugfix: User facing work package link from GitLab tab is not the shortened version \[[#73718](https://community.openproject.org/wp/73718)\] -- Bugfix: Inline text attachments lose UTF-8 charset \[[#75402](https://community.openproject.org/wp/75402)\] -- Bugfix: BCF import permission scope not clear \[[#75457](https://community.openproject.org/wp/75457)\] -- Bugfix: Hide "my meetings" and "favourited projects" widgets for anonymous users \[[#75477](https://community.openproject.org/wp/75477)\] -- Bugfix: Setting mail header via OPENPROJECT\_EMAILS\_\_HEADER\_EN interprets colon as hash \[[#75570](https://community.openproject.org/wp/75570)\] -- Bugfix: Date custom field filter "is empty" does not return all work packages with empty values \[[#75185](https://community.openproject.org/wp/75185)\] +- Feature: Exclude certain work package types from automated backlog (per project) \[[#71305](https://community.openproject.org/wp/71305)\] +- Feature: Container header (Sprint/Bucket/Inbox) restyling \[[#72945](https://community.openproject.org/wp/72945)\] +- Feature: Restyled work package card in "Backlogs and sprints" view \[[#73089](https://community.openproject.org/wp/73089)\] +- Feature: Bring sprint sharing (SAFe) to corporate plan \[[#74147](https://community.openproject.org/wp/74147)\] +- Feature: Create work package links through # notation in documents / BlockNote \[[#73664](https://community.openproject.org/wp/73664)\] +- Feature: Create a WorkPackageCard component \[[#73968](https://community.openproject.org/wp/73968)\] +- Feature: Extend the SubHeader component to support quick filter components \[[#73972](https://community.openproject.org/wp/73972)\] +- Feature: Jira Migrator imports project-based semantic issue identifiers \[[#72427](https://community.openproject.org/wp/72427)\] +- Feature: Jira Migrator supports due date, estimated hours and remaining hours. \[[#74807](https://community.openproject.org/wp/74807)\] +- Feature: Meeting series: Add monthly scheduling options \[[#61522](https://community.openproject.org/wp/61522)\] +- Feature: Debounce emails for meetings \[[#66645](https://community.openproject.org/wp/66645)\] +- Feature: Primerize Types form configuration page \[[#69524](https://community.openproject.org/wp/69524)\] +- Feature: Expand work package mentions (##, ###) macros inside CKEditor \[[#74641](https://community.openproject.org/wp/74641)\] +- Feature: Allow Custom Fields on UserQuery \[[#74758](https://community.openproject.org/wp/74758)\] +- Feature: Primerize users administration to allow all filters \[[#74763](https://community.openproject.org/wp/74763)\] +- Feature: Workflows UX improvement: Allow multi-selection of roles in workflow \[[#72242](https://community.openproject.org/wp/72242)\] +- Feature: Administration setting for project-based work package identifiers \[[#71633](https://community.openproject.org/wp/71633)\] +- Feature: Background job for converting project-based semantic work package identifiers \[[#71645](https://community.openproject.org/wp/71645)\] +- Feature: Allow inline Work Package links within text paragraphs in the Documents module \[[#72817](https://community.openproject.org/wp/72817)\] +- Feature: Adapt creation of projects through the API for semantic identifiers \[[#73175](https://community.openproject.org/wp/73175)\] +- Feature: Define database model for project-based work package identifiers \[[#73315](https://community.openproject.org/wp/73315)\] +- Feature: Adapt work package show view for project-based semantic work package identifiers \[[#73716](https://community.openproject.org/wp/73716)\] +- Feature: Adapt work package lists for project-based semantic work package identifiers \[[#73717](https://community.openproject.org/wp/73717)\] +- Feature: Adapt routes for project-based semantic work package identifiers \[[#73756](https://community.openproject.org/wp/73756)\] +- Feature: Search work packages by their identifier \[[#73761](https://community.openproject.org/wp/73761)\] +- Feature: Adapt email notifications for project-based work package identifiers \[[#73827](https://community.openproject.org/wp/73827)\] +- Feature: Adapt work package link blocks in BlockNote for project-based semantic work package identifiers \[[#74115](https://community.openproject.org/wp/74115)\] +- Feature: Adapt work package links in CKEditor for project-based semantic work package identifiers \[[#74116](https://community.openproject.org/wp/74116)\] +- Feature: Adapt GitHub and GitLab modules for semantic identifiers \[[#74364](https://community.openproject.org/wp/74364)\] +- Feature: Adapt work package PDF exports for semantic identifiers \[[#74366](https://community.openproject.org/wp/74366)\] +- Feature: Add better progress indicator to identifier conversion page \[[#74903](https://community.openproject.org/wp/74903)\] +- Feature: Put "Beta" label on the setting for enabling semantic identifiers \[[#74975](https://community.openproject.org/wp/74975)\] +- Feature: Admin panel for releasing old classic project aliases \[[#74992](https://community.openproject.org/wp/74992)\] +- Bugfix: Closed work packages are still considered to be part of the bucket. \[[#74773](https://community.openproject.org/wp/74773)\] +- Bugfix: Inconsistent handling of "Definition of Done" \[[#74796](https://community.openproject.org/wp/74796)\] +- Bugfix: Backlogs: Missing space on mobile \[[#75188](https://community.openproject.org/wp/75188)\] +- Bugfix: Sprint field is sometimes not visible on the wp page \[[#75194](https://community.openproject.org/wp/75194)\] +- Bugfix: Backlog settings tab switching doesn't persist in url \[[#75239](https://community.openproject.org/wp/75239)\] +- Bugfix: No "Undisclosed" mention for the parent work package on the wp card for a user without permissions to see the parent \[[#75241](https://community.openproject.org/wp/75241)\] +- Bugfix: Incorrect resize behavior for pasted inline-links \[[#74190](https://community.openproject.org/wp/74190)\] +- Bugfix: Inserting "#" inside text removes content after cursor \[[#74325](https://community.openproject.org/wp/74325)\] +- Bugfix: Сards converting to hash links on copy-paste and DnD \[[#74327](https://community.openproject.org/wp/74327)\] +- Bugfix: Type colors are not applied correctly at the beginning \[[#74330](https://community.openproject.org/wp/74330)\] +- Bugfix: Inconsistent contrast for type colors when switching themes \[[#74332](https://community.openproject.org/wp/74332)\] +- Bugfix: Dropdown option order changes depending on selected item \[[#74333](https://community.openproject.org/wp/74333)\] +- Bugfix: Inconsistent inline-link heights in text flow \[[#74341](https://community.openproject.org/wp/74341)\] +- Bugfix: Inline work package chip has no visual highlight when selected \[[#74385](https://community.openproject.org/wp/74385)\] +- Bugfix: Arrow-down selection for link work package block prevented by tooltip \[[#74393](https://community.openproject.org/wp/74393)\] +- Bugfix: Wrong cursor placement after inserting links to Work Packages in BlockNote \[[#74397](https://community.openproject.org/wp/74397)\] +- Bugfix: Improve size menu and remove L+XL blocks \[[#74651](https://community.openproject.org/wp/74651)\] +- Bugfix: Click position is lost when activating an inline edit field \[[#72837](https://community.openproject.org/wp/72837)\] +- Bugfix: Doubled scrollbar on a Board \[[#73714](https://community.openproject.org/wp/73714)\] +- Bugfix: Quick filters don't react good to medium screen sizes \[[#74832](https://community.openproject.org/wp/74832)\] +- Bugfix: Hide pagination buttons when they are disabled \[[#75258](https://community.openproject.org/wp/75258)\] +- Bugfix: Horizontal ellipsis button misaligned when text expanded on Permissions Report/Workflows pages \[[#75275](https://community.openproject.org/wp/75275)\] +- Bugfix: Jira Migrator: misalignement between the status badge and the import name \[[#72840](https://community.openproject.org/wp/72840)\] +- Bugfix: Imprecise error for unallowed IP when testing Jira connection \[[#75031](https://community.openproject.org/wp/75031)\] +- Bugfix: Imprecise error for SSL errors when testing Jira connection \[[#75032](https://community.openproject.org/wp/75032)\] +- Bugfix: Jira Migrator cannot import a user with non-alphanumeric characters in their name \[[#75238](https://community.openproject.org/wp/75238)\] +- Bugfix: Jira Migrator stops the import for non-existing user in user mention \[[#75248](https://community.openproject.org/wp/75248)\] +- Bugfix: Remove extra space in Jira Migrator backup warning dialog \[[#75353](https://community.openproject.org/wp/75353)\] +- Bugfix: Jira Migrator does not scope issues between import runs. \[[#75355](https://community.openproject.org/wp/75355)\] +- Bugfix: Jira Migrator shows 0 issues info if server does not include the data in serverInfo endpoint \[[#75380](https://community.openproject.org/wp/75380)\] +- Bugfix: Jira Migrator gives unhelpful error message if user email is blank \[[#75381](https://community.openproject.org/wp/75381)\] +- Bugfix: No way to find jira import run history page \[[#75382](https://community.openproject.org/wp/75382)\] +- Bugfix: Enabled rate limiting on Jira instance breaks projects selector. \[[#75391](https://community.openproject.org/wp/75391)\] +- Bugfix: Wrong wording on import page in admin \[[#75422](https://community.openproject.org/wp/75422)\] +- Bugfix: Jira Migrator: Do not disable the new configuration button if the instance is not switched to semantic identifiers \[[#75674](https://community.openproject.org/wp/75674)\] +- Bugfix: Cancel occurence action item is called 'Delete' on My Meetings page and Meeting index page 'Past' tab \[[#74303](https://community.openproject.org/wp/74303)\] +- Bugfix: User cannot restore a cancelled occurrence if series has a deleted WP on the agenda \[[#74304](https://community.openproject.org/wp/74304)\] +- Bugfix: Show default section more clearly when using the section selector for a meeting with no sections \[[#74321](https://community.openproject.org/wp/74321)\] +- Bugfix: Meetings endpoint /api/v3/recurring\_meetings/:id/occurrences/:start\_time/init is not properly authorized \[[#75449](https://community.openproject.org/wp/75449)\] +- Bugfix: ActiveRecord::InvalidForeignKey on RecurringMeetingsController#end\_series \[[#75463](https://community.openproject.org/wp/75463)\] +- Bugfix: Work package configuration dialog's highlighting tab has no space between radio buttons and labels \[[#64359](https://community.openproject.org/wp/64359)\] +- Bugfix: Log time modal dropdown's bottom border is indistignuishable from the modal's bottom border \[[#65523](https://community.openproject.org/wp/65523)\] +- Bugfix: Wrong calendar week in My time tracking \[[#68272](https://community.openproject.org/wp/68272)\] +- Bugfix: Asterisks on Project attributes displaced \[[#68633](https://community.openproject.org/wp/68633)\] +- Bugfix: \[Meetings\] Exception raised while trying to update Stale Object \[[#68703](https://community.openproject.org/wp/68703)\] +- Bugfix: Clicking work package tabs triggers page reload and flickering \[[#69210](https://community.openproject.org/wp/69210)\] +- Bugfix: Mobile - Include project on WP list is missing spacing \[[#69451](https://community.openproject.org/wp/69451)\] +- Bugfix: Roles selectable as "Role given to a non-admin user who creates a project" that lack essential permissions \[[#69496](https://community.openproject.org/wp/69496)\] +- Bugfix: Text overflow in Baseline modal banner \[[#69526](https://community.openproject.org/wp/69526)\] +- Bugfix: Fix accessibility errors found by ERB Lint \[[#70166](https://community.openproject.org/wp/70166)\] +- Bugfix: Role not created properly when unselecting all permissions \[[#73494](https://community.openproject.org/wp/73494)\] +- Bugfix: POST/PATCH/DELETE requests to APIv3 return unauthorized \[[#73499](https://community.openproject.org/wp/73499)\] +- Bugfix: "Upgrade" button label should not be underlined \[[#73570](https://community.openproject.org/wp/73570)\] +- Bugfix: Not possible to filter for blocked users in time and cost report \[[#73660](https://community.openproject.org/wp/73660)\] +- Bugfix: Not possible to follow link custom field from work package list view \[[#73673](https://community.openproject.org/wp/73673)\] +- Bugfix: Black font in dark mode on wp description \[[#74697](https://community.openproject.org/wp/74697)\] +- Bugfix: Add upcoming/past filter to meetings index page filters \[[#74743](https://community.openproject.org/wp/74743)\] +- Bugfix: Redirect to /login is missing the URL query params \[[#74778](https://community.openproject.org/wp/74778)\] +- Bugfix: Missing space between user avatar and name \[[#74853](https://community.openproject.org/wp/74853)\] +- Bugfix: LDAP seeding via OPENPROJECT\_SEED\_LDAP\_\* uses a different (and self-contradictory) key convention than the rest of the env-var settings \[[#75361](https://community.openproject.org/wp/75361)\] +- Bugfix: Incorrect confirmation message when deleting a OAuth token \[[#72958](https://community.openproject.org/wp/72958)\] +- Bugfix: Roles select panel button should be "Apply" \[[#74560](https://community.openproject.org/wp/74560)\] +- Bugfix: Nextcloud integration shows "No connection to Nextcloud" for folders that have "&" in the name \[[#73855](https://community.openproject.org/wp/73855)\] +- Bugfix: Shared work package not showing images of comments \[[#69056](https://community.openproject.org/wp/69056)\] +- Bugfix: Lists of work packages should sort correctly by semantic id \[[#74156](https://community.openproject.org/wp/74156)\] +- Bugfix: Automatically converting project identifiers should not lead to usage of reserved keywords \[[#74161](https://community.openproject.org/wp/74161)\] +- Bugfix: Moving work packages after switching to semantic and back should not lead to errors \[[#74192](https://community.openproject.org/wp/74192)\] +- Bugfix: After migration job is complete save button is visible and clicking it triggers a 404 \[[#74623](https://community.openproject.org/wp/74623)\] +- Bugfix: Admin page for semantic IDs: grammatical issue \[[#74681](https://community.openproject.org/wp/74681)\] +- Bugfix: Admin page for semantic IDs: long ids cause overflow \[[#74730](https://community.openproject.org/wp/74730)\] +- Bugfix: Numeric ID still in the URL of the link opened from the email notification \[[#74760](https://community.openproject.org/wp/74760)\] +- Bugfix: Numeric ID in the email notification after adding watchers \[[#74762](https://community.openproject.org/wp/74762)\] +- Bugfix: Numeric ID copied instead of semantic ID in "Copy work package ID" on Backlogs page \[[#74826](https://community.openproject.org/wp/74826)\] +- Bugfix: Numeric ID in URL of the wp link when opened from search results \[[#74834](https://community.openproject.org/wp/74834)\] +- Bugfix: Semantic ID is not shown in search results in different places \[[#74844](https://community.openproject.org/wp/74844)\] +- Bugfix: Numeric ID instead of semantic one in the spent time calendar \[[#74900](https://community.openproject.org/wp/74900)\] +- Bugfix: Numeric ID instead of semantic one on the Activity page \[[#74912](https://community.openproject.org/wp/74912)\] +- Bugfix: Numeric ID instead of semantic one in Roadmap \[[#74913](https://community.openproject.org/wp/74913)\] +- Bugfix: Numeric ID instead of semantic one in bulk edit work packages \[[#74926](https://community.openproject.org/wp/74926)\] +- Bugfix: Unable to change a parent on bulk edit of work packages with semantic ID \[[#74927](https://community.openproject.org/wp/74927)\] +- Bugfix: Numeric ID instead of semantic one on the error message on bulk edit \[[#74928](https://community.openproject.org/wp/74928)\] +- Bugfix: Numeric ID instead of semantic one on the table of related work packages \[[#74942](https://community.openproject.org/wp/74942)\] +- Bugfix: Numeric ID instead of semantic one on the Time and costs report \[[#74943](https://community.openproject.org/wp/74943)\] +- Bugfix: Numeric ID instead of semantic one on the wp delete confirmation dialogue \[[#74944](https://community.openproject.org/wp/74944)\] +- Bugfix: All-numeric project identifiers are not properly handled in classic mode \[[#74993](https://community.openproject.org/wp/74993)\] +- Bugfix: Numeric ID visible in edit mode in links with # \[[#75180](https://community.openproject.org/wp/75180)\] +- Bugfix: Inconsistent naming on admin page \[[#75362](https://community.openproject.org/wp/75362)\] +- Bugfix: Reserved project identifiers: UI fails silently with 404 console error when acting on a deleted project \[[#75483](https://community.openproject.org/wp/75483)\] +- Bugfix: workPackageValue:ID:attribute macros failing with semantic IDs \[[#75574](https://community.openproject.org/wp/75574)\] +- Bugfix: Numeric ID showing in Github tab on work packages without links to PRs \[[#75636](https://community.openproject.org/wp/75636)\] diff --git a/docs/release-notes/README.md b/docs/release-notes/README.md index 4ea9dd89bdb..d726e5c9f75 100644 --- a/docs/release-notes/README.md +++ b/docs/release-notes/README.md @@ -13,6 +13,27 @@ Stay up to date and get an overview of the new features included in the releases +## 17.3.4 + +Release date: 2026-06-08 + +[Release Notes](17-3-4/) + + +## 17.4.1 + +Release date: 2026-06-08 + +[Release Notes](17-4-1/) + + +## 17.3.3 + +Release date: 2026-06-08 + +[Release Notes](17-3-3/) + + ## 17.4.0 Release date: 2026-05-13 diff --git a/docs/system-admin-guide/users-permissions/users/README.md b/docs/system-admin-guide/users-permissions/users/README.md index 47c0653a863..46c4315d457 100644 --- a/docs/system-admin-guide/users-permissions/users/README.md +++ b/docs/system-admin-guide/users-permissions/users/README.md @@ -20,45 +20,64 @@ To manage users click on your avatar (top right corner) and select **Administrat In the Community edition there is no limit to the number of users. In Enterprise editions (cloud and on-premises) the user limit is based on your subscription. The number of users for your subscription is thus not bound to names. For example, if you block a user you can add a new one without upgrading. -| Topic | Content | -| ----------------------------------------------- | -------------------------------------------------------- | -| [User list](#user-list) | Manage all users in OpenProject. | -| [Filter users](#filter-users) | Filter users in the list. | -| [Lock and unlock users](#lock-and-unlock-users) | Block a user permanently in the system or unlock a user. | -| [Create users](#create-users) | Invite or create new users. Resend or delete user invitations | -| [Manage user settings](#manage-user-settings) | Manage user details. | -| [Authentication](#authentication) | Set and use authentication methods. | -| [Delete users](#delete-users) | Delete a user from the system. | +| Topic | Content | +| ----------------------------------------------- | ------------------------------------------------------------ | +| [User list](#user-list) | Manage all users in OpenProject. | +| [Filter users](#filter-users) | Filter users in the list. | +| [Configure view](#configure-view) | Configure how user information is displayed. | +| [Lock and unlock users](#lock-and-unlock-users) | Block a user permanently in the system or unlock a user. | +| [Create users](#create-users) | Invite or create new users. Resend or delete user invitations | +| [Manage user settings](#manage-user-settings) | Manage user details. | +| [Authentication](#authentication) | Set and use authentication methods. | +| [Delete users](#delete-users) | Delete a user from the system. | ## User list The User list is where users are managed. They can be added, edited or deleted from this list, which can be filtered if required. -![openproject_system_admin_guide_users_list](openproject_system_admin_guide_users_list.png) +![List of users under OpenProject administration](openproject_system_admin_guide_users_list.png) Column headers can be clicked to toggle sort direction. Arrows indicate sort order, up for ascending (a-z/0-9) and down for descending (z-a/9-0). Paging controls are shown at the bottom of the list. You will also see whether a user is a system administrator in OpenProject. ## Filter users -At the top of the user list is a filter box. Filter by status. group or name, then click the green **Apply** button to filter the list. Click the **Clear** button to reset the filter fields and refresh the list. +To filter for users, begin by clicking the **Filters** button. -* **Status** - select from Active, All or Locked Temporarily. Each selection shows the number of users. -* **Group** - select from the list of existing groups. -* **Name** - enter any text; this can contain a "%" wild card for 0 or more characters. The filter applies to user name, first name, last name and email address. +!["Filters" button to filter through users list in OpenProject administration](openproject_systemguide_filters_button.png) -![Filter users in OpenProject](openproject_systemguide_filter_users.png) +Clicking on it opens up the **+Add filter** form. Here, you can filter by group, status, name or username, and your list is automatically updated. Each filter button displays additional filtering options to help you narrow down results. The results are then filtered based on the selected criteria. Click the **x** symbol in front of each selected filter to clear the filter and the **x** symbol at the **top-right corner** to close the form. + +![Add filter form](openproject_systemguide_add_filters.png) + +- **Username** - enter any text or character like @, .com which is unique to the user list. +- **Name** - enter any text; this can contain a "%" wild card for 0 or more characters. For example, if you are filtering for a user named Niklas but are unsure if it's Niklas, Niclas, Nikolas, or Nicholas, you can search for “Ni%las” and all matching users will be listed. The filter applies to first name, last name and email address. +- **Group** - select from the list of existing groups. +- **Status** - select from Active, Registered, Locked, Invited, Deleted. Each selection shows the number of users. + +![Filters for user list in OpenProject administration](openproject_systemguide_filter_users.png) + +## Configure view + +To configure how the table of users is displayed, click on the More menu **(...)**. + +![Menu for configure view for the user list in OpenProject administration](openproject_systemguide_configure_view.png) + +This opens up a form where you can add columns, or manage and reorder columns via drag and drop. Click **Apply** to save your changes. + +![Open form to configure view for the user list in OpenProject administration](openproject_systemguide_configure_view_form.png) ## Lock and unlock users -Handling locking and unlocking of users is also done from the user list. To disable a user's access click the **Lock permanently** link next to a user. Use the **Unlock** link to restore the user's access. +Handling locking and unlocking of users is also done from the user list. To disable a user's access click, the **Lock permanently** link next to a user. Use the **Unlock** link to restore the user's access. If you are using [Enterprise cloud](../../../enterprise-guide/enterprise-cloud-guide) or [Enterprise on-premises](../../../enterprise-guide/enterprise-on-premises-guide) locking a user will free up a user license and so you could add another user to the system within your booked plan. -> **Note**: The previous activities from a locked user will still be displayed in the system. +> [!NOTE] +> The previous activities from a locked user will still be displayed in the system. ![Lock users in OpenProject](open_project_system_admin_lock_user_permanently.png) -If a user has repeated failed logins the user will be locked temporarily and a **Reset failed logins** link will be shown in the user list. Click the link to unlock it right away, or wait and it will be unlocked automatically. Have a look at the section [Other authentication settings](../../authentication/login-registration-settings/) for failed attempts and time blocked. +If a user has repeated failed logins, the user will be locked temporarily and a **Reset failed logins** link will be shown in the user list. Click the link to unlock it right away, or wait and it will be unlocked automatically. Have a look at the section [Other authentication settings](../../authentication/login-registration-settings/) for failed attempts and time blocked. ## Create users @@ -75,7 +94,7 @@ Enter the email address, first name, and last name of the new user. Tick the box Note: the email field must be a valid format and be unique or it will be rejected on clicking the button. Click the **Create** button to add the user and show that user's details page. Click the **Create and continue** button to add the user and stay on the new user form to add another user. Either way, the new user will be invited via email. -When adding the last of multiple users you can click on **Create** or click the **Users** link in the menu on the left. The **Users list** will be shown. Click on the name of each user to [edit their details](#set-initial-details). +When adding the last of multiple users you can click on **Create** or click the **Users** link in the menu on the left. The **Users list** will be shown. Click on the name of each user to [edit their details](#set-initial-details). ### Create user (via self-registration) @@ -110,8 +129,10 @@ In the top right, click the **Send invitation** button in order to send the emai ### Delete user invitations -To invalidate or revoke a user's invitation click on the user name and then on **Delete** in the upper right corner. This will prevent the invited user from logging in. -Please note: this only works for users who haven't logged in yet. If the user is already active this will delete his/her whole profile and account. Deleting users can't be revoked. +To invalidate or revoke a user's invitation, click on the user name and then on **Delete** in the upper right corner. This will prevent the invited user from logging in. + +> [!NOTE] +> This only works for users who haven't logged in yet. If the user is already active, this will delete his/her whole profile and account. Deleting users can't be revoked. ## Manage user settings @@ -119,11 +140,11 @@ You can manage individual user details if you click on the user name in the list ### General settings -![administration-user-settings-manage-user](openproject_system_guide_general_tab.png) +![Settings to manage a user under OpenProject administration](openproject_system_guide_general_tab.png) On the **General** tab the following fields are shown: -1. User's master date +1. User's master data - **Status** - this is set by the system. - **Username** - this defaults to the email address for a new user (unless the user used the self registration). It can be changed on this page. Users cannot change their own user name. - **First name**, **Last name**, **Email** - these fields are filled from the **New user** page. Users can change them under their **Profile** page; they are mandatory. @@ -139,7 +160,7 @@ On the **General** tab the following fields are shown: To create a new password for a user (e.g. if he/she lost it) navigate to the **Authentication** section of the **General** tab. You can either **Assign a random password** (check the box on top) or set a new password manually and send it to them (preferably through secured communication). Consider checking the box next to **Enforce password change on next login**. -![reset-user-password](Authentication.png) +![Reset user password under OpenProject administration](Authentication.png) ### Add users to a project @@ -147,19 +168,20 @@ In order to see and work in a project, a user has to be a member of a project an On the **Projects** tab, select the new project from the drop-down list, choose the [roles](../roles-permissions) for this project and click the green **Add** button. -![Sysadmin add project](Sys-admin-add-project1.gif) +![Add users to a project under OpenProject system administration](Sys-admin-add-project1.gif) ### Add users to groups On the **Groups** tab you can see the groups the user belongs to. If a group is shown, click the group name link. -![User groups](system_guide_user_groups.png) +![User groups in OpenProject administration](system_guide_user_groups.png) If no groups are shown (i.e. the user does not belong to any group, yet), click the **Manage groups** link to [edit groups](../groups). -![Manage Groups](system_guide_manage_groups.png) +![Manage groups in OpenProject administration](system_guide_manage_groups.png) -**Please note**: The **Groups** tab is only shown if at least one user group exists in OpenProject. +> [!NOTE] +> The **Groups** tab is only shown if at least one user group exists in OpenProject. ### Global roles @@ -167,7 +189,7 @@ In order to add a global role to a user, at least one global role needs to be [c On the **Global roles** tab, select or de-select the global role(s) for this user. Click the **Add** button. -![Add global roles](openproject_system_guide_add_global_roles.png) +![Add global user roles in OpenProject administration](openproject_system_guide_add_global_roles.png) ### Notification settings @@ -181,13 +203,13 @@ Under **Email reminders** tab you can edit the [email reminders settings](../../ The rate history tab shows the hourly rates that have been defined for the user. The **Default rate** is applied to projects with no rate defined. All projects that the user is a member of are listed with the user's rates. -The **Valid from** date will effect the rate used when creating a [budget](../../../user-guide/budgets/) and when [logging time](../../../user-guide/time-and-costs/time-tracking/). +The **Valid from** date will affect the rate used when creating a [budget](../../../user-guide/budgets/) and when [logging time](../../../user-guide/time-and-costs/time-tracking/). If you want to set a different hourly rate for the user on different projects, you can overwrite the default rate with a different rate below in the respective projects. To enter a new hourly rate, click on the **Update** icon next to the rate history. You can either set a **default hourly rate** or define a rate for a certain project. -![set-hourly-rate-administration](system_guide_rate_history.png) +![Set hourly rates for users in OpenProject administrationin OpenProject administration](system_guide_rate_history.png) 1. Enter a date from which the rate is **Valid from**. 2. Enter the (hourly) **Rate**. The currency can only be changed in the [respective settings](../../time-and-costs). @@ -199,10 +221,9 @@ To enter a new hourly rate, click on the **Update** icon next to the rate histor ### Avatar -The **Avatar** tab shows the default icon to be shown for this user. A custom image can be uploaded as the avatar. In addition, users can also use their [Gravatar](https://en.wikipedia.org/wiki/Gravatar). User can manage this under their [profile settings](../../../user-guide/account-settings/#set-an-avatar). These features can be disabled in the [avatar settings](../avatars). +The **Avatar** tab shows the default icon to be shown for this user. A custom image can be uploaded as the avatar. In addition, users can also use their [Gravatar](https://en.wikipedia.org/wiki/Gravatar). Users can manage this under their [profile settings](../../../user-guide/account-settings/#set-an-avatar). These features can be disabled in the [avatar settings](../avatars). > [!TIP] -> > Hovering over a user's avatar or name, for example on the Members page or the Activity page, will display their information. ### Two-factor authentication (2FA) @@ -219,9 +240,9 @@ Use the **self-registration** field to give the following controls over a new us The user details Authentication section has fields **Assign random password**, **Password**, **Confirmation** and **Enforce password change**. -* If you are near the new user, you can enter a password and confirmation then tell the user what it is. They can then sign in. It is recommended that you also tick the enforce password change checkbox, so that the user is prompted to change their password after they sign in. -* You can phone the new user or send them an email, not using OpenProject, to give them the password. In this case it is more important to tick the enforce password change checkbox. -* Tick the Assign random password, and probably the enforce password change checkbox. When the details are saved OpenProject will send an email to the new user with their password. +- If you are near the new user, you can enter a password and confirmation then tell the user what it is. They can then sign in. It is recommended that you also tick the enforce password change checkbox, so that the user is prompted to change their password after they sign in. +- You can phone the new user or send them an email, not using OpenProject, to give them the password. In this case it is more important to tick the enforce password change checkbox. +- Tick the Assign random password, and probably the enforce password change checkbox. When the details are saved OpenProject will send an email to the new user with their password. ### Account activation by email @@ -231,8 +252,8 @@ Leave all fields blank. When the details are saved OpenProject will send an emai Two [settings](../settings/#user-deletion) allow users to be deleted from the system: -* **User accounts deletable by admins** - if ticked, a **Delete** button is shown on the user details page. -* **Users allowed to delete their accounts** - if ticked, a **Delete account** menu entry is shown in the **Account settings** page. +- **User accounts deletable by admins** - if ticked, a **Delete** button is shown on the user details page. +- **Users allowed to delete their accounts** - if ticked, a **Delete account** menu entry is shown in the **Account settings** page. To delete another user's account open the [user list](#user-list). Click on the **user name** of the user which you want to delete. Click the **Delete** button at the top right. @@ -240,7 +261,7 @@ To delete another user's account open the [user list](#user-list). Click on the You will then be asked to confirm the deletion of the user permanently from the system. Checking the consent box will activate the **Delete permanently** button. -![delete user](delete-user-confirmation.png) +![Delete user in OpenProject administration](delete-user-confirmation.png) > [!CAUTION] > Deleting a user account is a permanent action and cannot be reversed. The previous activities from this user will still be displayed in the system but reassigned to **Deleted user**. This is also true for the Time and cost and the Budget modules. Spent time will be still be visible for **Deleted user** inside a Work package. Time and cost reports will contain the entries with reference to **Deleted user**. Labor budgets that have been setup for the user are displayed under **Deleted user**, too. If you would like to keep track of the user's name in connection with the mentioned activities, the spent time and the budget, you are able to keep the user's name in the historical data by simply [locking the user](#lock-and-unlock-users). diff --git a/docs/system-admin-guide/users-permissions/users/openproject_system_admin_guide_users_list.png b/docs/system-admin-guide/users-permissions/users/openproject_system_admin_guide_users_list.png index a84d8b5d8f2..f201f2f3464 100644 Binary files a/docs/system-admin-guide/users-permissions/users/openproject_system_admin_guide_users_list.png and b/docs/system-admin-guide/users-permissions/users/openproject_system_admin_guide_users_list.png differ diff --git a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_add_filters.png b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_add_filters.png new file mode 100644 index 00000000000..4b94ced7c7e Binary files /dev/null and b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_add_filters.png differ diff --git a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view.png b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view.png new file mode 100644 index 00000000000..e70e5bbae9a Binary files /dev/null and b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view.png differ diff --git a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view_form.png b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view_form.png new file mode 100644 index 00000000000..dd6dcf480aa Binary files /dev/null and b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_configure_view_form.png differ diff --git a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filter_users.png b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filter_users.png index fb4b6334031..02ef4cf6416 100644 Binary files a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filter_users.png and b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filter_users.png differ diff --git a/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filters_button.png b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filters_button.png new file mode 100644 index 00000000000..67ea6986047 Binary files /dev/null and b/docs/system-admin-guide/users-permissions/users/openproject_systemguide_filters_button.png differ diff --git a/extensions/op-blocknote-hocuspocus/package-lock.json b/extensions/op-blocknote-hocuspocus/package-lock.json index 8bbe61475aa..fd6f56fe45e 100644 --- a/extensions/op-blocknote-hocuspocus/package-lock.json +++ b/extensions/op-blocknote-hocuspocus/package-lock.json @@ -12,7 +12,7 @@ "@blocknote/server-util": "^0.51.3", "@hocuspocus/extension-logger": "^3.4.4", "@hocuspocus/server": "^3.4.0", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", + "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", "tsx": "^4.21.0" }, "devDependencies": { @@ -4245,9 +4245,9 @@ "license": "MIT" }, "node_modules/op-blocknote-extensions": { - "version": "0.1.0", - "resolved": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", - "integrity": "sha512-JKwG2P5RXM0JDED0AzDeiVoxuamHtzqLO5fp88EoFig+YXlPsedJHc90zjTDqCFRilwTDamCq3jjzdFvl42kCA==", + "version": "0.1.1", + "resolved": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", + "integrity": "sha512-4VO5Qf51Z8WQGD24AYhNmGHGGwnfnB3q8KwL48hWTifZq/9IL5rKpwKB+QkxvVUCaT8iwFYwB6QPzGgLJKRVFA==", "dependencies": { "@primer/octicons-react": "^19.20.0", "i18next": "^25.6.3", diff --git a/extensions/op-blocknote-hocuspocus/package.json b/extensions/op-blocknote-hocuspocus/package.json index 5dcabaa314a..ee156887b0a 100644 --- a/extensions/op-blocknote-hocuspocus/package.json +++ b/extensions/op-blocknote-hocuspocus/package.json @@ -26,7 +26,7 @@ "@blocknote/server-util": "^0.51.3", "@hocuspocus/extension-logger": "^3.4.4", "@hocuspocus/server": "^3.4.0", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", + "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", "tsx": "^4.21.0" }, "devDependencies": { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index cc3a1036f0a..770485040a7 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -107,7 +107,7 @@ "ng2-dragula": "^6.0.0", "ngx-cookie-service": "^21.3.1", "observable-array": "0.0.4", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", + "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", "openapi-explorer": "^2.4.799", "pako": "^2.0.3", "qr-creator": "^1.0.0", @@ -155,8 +155,8 @@ "@types/urijs": "^1.19.26", "@types/uuid": "^11.0.0", "@types/webpack-env": "^1.16.0", - "@typescript-eslint/eslint-plugin": "8.59.4", - "@typescript-eslint/parser": "8.59.4", + "@typescript-eslint/eslint-plugin": "8.60.0", + "@typescript-eslint/parser": "8.60.0", "@vitest/browser-playwright": "^4.1.7", "@vitest/coverage-v8": "^4.1.7", "@vitest/eslint-plugin": "^1.6.18", @@ -7648,17 +7648,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.4.tgz", - "integrity": "sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.0.tgz", + "integrity": "sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.59.4", - "@typescript-eslint/type-utils": "8.59.4", - "@typescript-eslint/utils": "8.59.4", - "@typescript-eslint/visitor-keys": "8.59.4", + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/type-utils": "8.60.0", + "@typescript-eslint/utils": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -7671,22 +7671,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.59.4", + "@typescript-eslint/parser": "8.60.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.4.tgz", - "integrity": "sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.0.tgz", + "integrity": "sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.4", - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/typescript-estree": "8.59.4" + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7710,16 +7710,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.4.tgz", - "integrity": "sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.0.tgz", + "integrity": "sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.59.4", - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/typescript-estree": "8.59.4", - "@typescript-eslint/visitor-keys": "8.59.4", + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", "debug": "^4.4.3" }, "engines": { @@ -7735,14 +7735,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.4.tgz", - "integrity": "sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.0.tgz", + "integrity": "sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.4", - "@typescript-eslint/types": "^8.59.4", + "@typescript-eslint/tsconfig-utils": "^8.60.0", + "@typescript-eslint/types": "^8.60.0", "debug": "^4.4.3" }, "engines": { @@ -7757,14 +7757,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.4.tgz", - "integrity": "sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.0.tgz", + "integrity": "sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/visitor-keys": "8.59.4" + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7775,9 +7775,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.4.tgz", - "integrity": "sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.0.tgz", + "integrity": "sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==", "dev": true, "license": "MIT", "engines": { @@ -7792,15 +7792,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.4.tgz", - "integrity": "sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.0.tgz", + "integrity": "sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/typescript-estree": "8.59.4", - "@typescript-eslint/utils": "8.59.4", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0", + "@typescript-eslint/utils": "8.60.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -7817,16 +7817,16 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.4.tgz", - "integrity": "sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.0.tgz", + "integrity": "sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.4", - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/typescript-estree": "8.59.4" + "@typescript-eslint/scope-manager": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/typescript-estree": "8.60.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -7841,9 +7841,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.4.tgz", - "integrity": "sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.0.tgz", + "integrity": "sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==", "dev": true, "license": "MIT", "engines": { @@ -7855,16 +7855,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.4.tgz", - "integrity": "sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.0.tgz", + "integrity": "sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.59.4", - "@typescript-eslint/tsconfig-utils": "8.59.4", - "@typescript-eslint/types": "8.59.4", - "@typescript-eslint/visitor-keys": "8.59.4", + "@typescript-eslint/project-service": "8.60.0", + "@typescript-eslint/tsconfig-utils": "8.60.0", + "@typescript-eslint/types": "8.60.0", + "@typescript-eslint/visitor-keys": "8.60.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -8115,13 +8115,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.4.tgz", - "integrity": "sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==", + "version": "8.60.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.0.tgz", + "integrity": "sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.4", + "@typescript-eslint/types": "8.60.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -14515,9 +14515,9 @@ } }, "node_modules/op-blocknote-extensions": { - "version": "0.1.0", - "resolved": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", - "integrity": "sha512-JKwG2P5RXM0JDED0AzDeiVoxuamHtzqLO5fp88EoFig+YXlPsedJHc90zjTDqCFRilwTDamCq3jjzdFvl42kCA==", + "version": "0.1.1", + "resolved": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", + "integrity": "sha512-4VO5Qf51Z8WQGD24AYhNmGHGGwnfnB3q8KwL48hWTifZq/9IL5rKpwKB+QkxvVUCaT8iwFYwB6QPzGgLJKRVFA==", "dependencies": { "@primer/octicons-react": "^19.20.0", "i18next": "^25.6.3", diff --git a/frontend/package.json b/frontend/package.json index 05c323aa9eb..66ba1430508 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -33,8 +33,8 @@ "@types/urijs": "^1.19.26", "@types/uuid": "^11.0.0", "@types/webpack-env": "^1.16.0", - "@typescript-eslint/eslint-plugin": "8.59.4", - "@typescript-eslint/parser": "8.59.4", + "@typescript-eslint/eslint-plugin": "8.60.0", + "@typescript-eslint/parser": "8.60.0", "@vitest/browser-playwright": "^4.1.7", "@vitest/coverage-v8": "^4.1.7", "@vitest/eslint-plugin": "^1.6.18", @@ -154,7 +154,7 @@ "ng2-dragula": "^6.0.0", "ngx-cookie-service": "^21.3.1", "observable-array": "0.0.4", - "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz", + "op-blocknote-extensions": "https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.1/op-blocknote-extensions-0.1.1.tgz", "openapi-explorer": "^2.4.799", "pako": "^2.0.3", "qr-creator": "^1.0.0", diff --git a/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.html b/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.html index 7cb262762df..e3e3ce5ddc1 100644 --- a/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.html +++ b/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.html @@ -13,12 +13,12 @@ class="op-ian-item" [class.op-ian-item_expanded]="records[0].expanded" [class.op-ian-item_read]="records[0].readIAN === true" - [class.op-ian-item_selected]="(selectedWorkPackage$ | async) === idFromLink(records[0]._links.resource.href)" + [class.op-ian-item_selected]="notificationMatchesSelectedWorkPackage(records[0], selectedWorkPackage$ | async)" [notification]="records[0]" [aggregatedNotifications]="records" attr.data-test-selector="op-ian-notification-item-{{records[0].id}}" [attr.data-qa-ian-read]="records[0].readIAN === true || undefined" - [attr.data-qa-ian-selected]="(selectedWorkPackage$ | async) === idFromLink(records[0]._links.resource.href)" + [attr.data-qa-ian-selected]="notificationMatchesSelectedWorkPackage(records[0], selectedWorkPackage$ | async)" /> } @else { diff --git a/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.ts b/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.ts index 8d882fa961d..becd64a64ea 100644 --- a/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.ts +++ b/frontend/src/app/features/in-app-notifications/center/in-app-notification-center.component.ts @@ -153,7 +153,7 @@ export class InAppNotificationCenterComponent implements OnInit { protected readonly idFromLink = idFromLink; ngOnInit():void { - const facet = this.urlParams.get('facet') || 'unread'; + const facet = this.urlParams.get('facet') ?? 'unread'; this.storeService.setFacet(facet as 'unread'|'all'); this.storeService.setFilters({ filter: this.urlParams.get('filter'), @@ -172,4 +172,12 @@ export class InAppNotificationCenterComponent implements OnInit { return this.text.no_notification_for_filter; } + + notificationMatchesSelectedWorkPackage(notification:INotification, selected:string|null):boolean { + const href = notification._links.resource?.href; + const workPackageId = href ? idFromLink(href) : null; + const workPackage = workPackageId ? this.apiV3.work_packages.cache.current(workPackageId) : null; + + return selected === workPackageId || selected === workPackage?.displayId; + } } diff --git a/frontend/src/elements/block-note-element.ts b/frontend/src/elements/block-note-element.ts index 2dddfcee99c..1efd02c318e 100644 --- a/frontend/src/elements/block-note-element.ts +++ b/frontend/src/elements/block-note-element.ts @@ -82,9 +82,14 @@ class BlockNoteElement extends HTMLElement { this.reactRoot = createRoot(this.editorMount); this.renderCallback = (provider:HocuspocusProvider) => { - this.reactRoot?.render( - React.createElement(React.StrictMode, null, this.BlockNoteReactContainer(provider)) - ); + // Do NOT wrap in React.StrictMode. StrictMode's dev-mode double-mount causes + // BlockNoteView to destroy and recreate the ProseMirror view between the two mounts. + // y-prosemirror's `yUndoPlugin` destroys the Y.UndoManager on view-destroy (removing + // its `afterTransaction` handler from the Y.Doc), but the plugin's STATE retains the + // now-destroyed UndoManager reference. On the second mount the editor reuses the + // destroyed UndoManager, no `afterTransaction` handler is ever re-attached, no stack + // items are recorded, and Ctrl+Z becomes a no-op. + this.reactRoot?.render(this.BlockNoteReactContainer(provider)); }; LiveCollaborationManager.onReady(this.renderCallback); diff --git a/frontend/src/react/components/OpBlockNoteEditor.tsx b/frontend/src/react/components/OpBlockNoteEditor.tsx index 281f56a0369..b544083934d 100644 --- a/frontend/src/react/components/OpBlockNoteEditor.tsx +++ b/frontend/src/react/components/OpBlockNoteEditor.tsx @@ -42,6 +42,7 @@ import { openProjectWorkPackageInlineSpec, workPackageSlashMenu, useOpBlockNoteExtensions, + PasteDeduplicateInstanceIdsExtension, useHashWpMenu, } from 'op-blocknote-extensions'; import { useCallback, useEffect, useMemo } from 'react'; @@ -118,13 +119,18 @@ export function OpBlockNoteEditor({ dictionary: localeDictionary, ...(attachmentsEnabled && { uploadFile }), extensions: [ + PasteDeduplicateInstanceIdsExtension, ExternalLinkA11yExtension, ...(captureExternalLinks ? [ExternalLinkCaptureExtension] : []), ], }; }, [hocuspocusProvider, doc, activeUser, localeDictionary, attachmentsEnabled, uploadFile, captureExternalLinks]); - const editor = useCreateBlockNote(editorParams, [activeUser]); + // Create the editor exactly once per mount. `useCreateBlockNote(options, deps)` uses `deps` + // as the sole `useMemo` key — `options` is intentionally NOT in deps. `[activeUser]` rebuilt + // the editor (wiping `Y.UndoManager` history) whenever a fresh `activeUser` reference + // reached this component, e.g. on Stimulus reconnect / Turbo morph. + const editor = useCreateBlockNote(editorParams, []); useOpBlockNoteExtensions(editor); type EditorType = typeof editor; const theme = useOpTheme(); diff --git a/frontend/src/stimulus/controllers/dynamic/documents/init-yjs-provider.controller.ts b/frontend/src/stimulus/controllers/dynamic/documents/init-yjs-provider.controller.ts index e935131f9f8..3920327b064 100644 --- a/frontend/src/stimulus/controllers/dynamic/documents/init-yjs-provider.controller.ts +++ b/frontend/src/stimulus/controllers/dynamic/documents/init-yjs-provider.controller.ts @@ -74,6 +74,17 @@ export default class extends Controller { connect():void { this.currentToken = this.tokenPayloadValue; + // If a provider for this document is already live, don't build a duplicate + // — adopt it. Stimulus can fire connect() a second time (HMR replay, Turbo + // morph, parent re-attach) without firing disconnect(); building a fresh + // Y.Doc + provider in that case would destroy the live one and wipe the + // editor's Y.UndoManager mid-session. + const existing = LiveCollaborationManager.getCurrentSessionFor(this.documentNameValue); + if (existing) { + this.ownedProvider = existing.provider; + return; + } + const ydoc:Doc = new Y.Doc(); const provider = new HocuspocusProvider({ url: this.hocuspocusUrlValue, @@ -87,7 +98,7 @@ export default class extends Controller { }, }); - LiveCollaborationManager.initializeYjsProvider(provider, ydoc); + LiveCollaborationManager.initializeYjsProvider(provider, ydoc, this.documentNameValue); this.ownedProvider = provider; if (this.refreshUrlValue && this.tokenExpiresInSecondsValue) { diff --git a/frontend/src/stimulus/controllers/dynamic/quick-filter/select-panel.controller.ts b/frontend/src/stimulus/controllers/dynamic/quick-filter/select-panel.controller.ts new file mode 100644 index 00000000000..c7665dfd3b0 --- /dev/null +++ b/frontend/src/stimulus/controllers/dynamic/quick-filter/select-panel.controller.ts @@ -0,0 +1,71 @@ +/* + * -- 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. + * ++ + */ + +import { Controller } from '@hotwired/stimulus'; +import { visit } from '@hotwired/turbo'; +import type { SelectPanelElement } from '@primer/view-components/app/components/primer/alpha/select_panel_element'; + +export default class SelectPanelQuickFilterController extends Controller { + static values = { + baseUrl: String, + filterKey: String, + operator: { type: String, default: '=' }, + }; + + declare baseUrlValue:string; + declare filterKeyValue:string; + declare operatorValue:string; + + clear() { + visit(this.baseUrlValue); + } + + apply(event:Event) { + // Prevent updating dynamic label before the page reloads anyway to stop flickering + event.stopPropagation(); + + const panel = this.element.querySelector('select-panel'); + if (!panel) return; + + const selectedValues = panel.selectedItems + .map((item) => item.value) + .filter((v):v is string => v != null && v.length > 0); + + const url = new URL(this.baseUrlValue, window.location.origin); + + if (selectedValues.length > 0) { + const filters = JSON.parse(url.searchParams.get('filters') ?? '[]') as unknown[]; + filters.push({ [this.filterKeyValue]: { operator: this.operatorValue, values: selectedValues } }); + url.searchParams.set('filters', JSON.stringify(filters)); + } + + visit(url.toString()); + } +} diff --git a/frontend/src/stimulus/helpers/live-collaboration-helpers.ts b/frontend/src/stimulus/helpers/live-collaboration-helpers.ts index d1a5452f2ff..3a3d8e933d0 100644 --- a/frontend/src/stimulus/helpers/live-collaboration-helpers.ts +++ b/frontend/src/stimulus/helpers/live-collaboration-helpers.ts @@ -36,21 +36,47 @@ type Listener = (provider:HocuspocusProvider) => void; class LiveCollaborationManagerClass { yjsProviderInstance:HocuspocusProvider|null = null; yjsDocInstance:Doc|null = null; + private currentDocumentName:string|null = null; private listeners:Listener[] = []; /** - * Initializes the YJS Provider + * Returns the active session for the given document, or null if none. + * + * Used by the init-yjs-provider Stimulus controller to detect that a + * provider for the same document is already live — letting it adopt the + * existing session instead of building a duplicate Y.Doc + provider pair. + * Stimulus can fire `connect()` a second time (HMR replay, Turbo morph) + * without firing `disconnect()`; without this check, the spurious re-init + * would tear down the live Y.Doc and wipe the editor's Y.UndoManager + * history mid-session. + */ + getCurrentSessionFor(documentName:string):{provider:HocuspocusProvider; doc:Doc} | null { + if (this.yjsProviderInstance && this.yjsDocInstance && this.currentDocumentName === documentName) { + return { provider: this.yjsProviderInstance, doc: this.yjsDocInstance }; + } + return null; + } + + /** + * Initializes the YJS Provider for the given document. + * + * Callers SHOULD first check {@link getCurrentSessionFor} and adopt any + * existing session rather than calling this with a fresh provider, since + * this method unconditionally tears down the previous provider/doc. + * * @param provider The provider to use * @param doc The Y.Doc instance to use + * @param documentName Logical identifier of the document being edited * @returns void */ - initializeYjsProvider(provider:HocuspocusProvider, doc:Doc) { + initializeYjsProvider(provider:HocuspocusProvider, doc:Doc, documentName:string) { this.destroyYjsProvider(); this.destroyYjsDoc(); this.yjsProviderInstance = provider; this.yjsDocInstance = doc; + this.currentDocumentName = documentName; this.listeners.forEach((listener) => listener(this.yjsProviderInstance!)); } @@ -82,6 +108,7 @@ class LiveCollaborationManagerClass { private destroy():void { this.destroyYjsProvider(); this.destroyYjsDoc(); + this.currentDocumentName = null; this.listeners = []; } diff --git a/lookbook/docs/patterns/10-quick-filters.md.erb b/lookbook/docs/patterns/10-quick-filters.md.erb index 05840c2f635..e626973bde5 100644 --- a/lookbook/docs/patterns/10-quick-filters.md.erb +++ b/lookbook/docs/patterns/10-quick-filters.md.erb @@ -1,16 +1,17 @@ -Quick filters are lightweight controls that let users toggle a single filter without opening the full filter panel. Each click can navigate to a new URL with updated `filters` and `sortBy` params, +Quick filters are lightweight controls that let users toggle a single filter without opening the full filter panel. Each click or selection navigates to a new URL with updated `filters` and `sortBy` params, preserving any other active filters. -There are currently two variants: -* SegmentedComponent +There are currently three variants: +* SegmentedControlComponent * BooleanComponent +* SelectPanelComponent -## SegmentedComponent +## SegmentedControlComponent A general purpose segmented control that accepts any number of items via `with_item` slots. Each item has a label and a filter value (`nil` means "no filter" and is useful for an "All" option). -<%= embed OpPrimer::QuickFilterPreview, :segmented, panels: %i[source] %> +<%= embed OpPrimer::QuickFilterPreview, :segmented_control, panels: %i[source] %> Note: Clicking on buttons in the above preview will break it and redirect to the meetings index page. @@ -19,13 +20,13 @@ Note: Clicking on buttons in the above preview will break it and redirect to the When the query already has a matching filter value, the corresponding item is rendered as selected. You can also pass `orders` to define the sort order per value. -<%= embed OpPrimer::QuickFilterPreview, :segmented_with_active_filter, panels: %i[source] %> +<%= embed OpPrimer::QuickFilterPreview, :segmented_control_with_active_filter, panels: %i[source] %> Note: Clicking on buttons in the above preview will break it and redirect to the meetings index page. ## BooleanComponent -A specialized subclass of `SegmentedComponent` for boolean (true/false) filters. +A specialized subclass of `SegmentedControlComponent` for boolean (true/false) filters. It always renders exactly two items using `t` and `f` as filter values. Labels are provided via `true_label` and `false_label`. @@ -33,7 +34,11 @@ Labels are provided via `true_label` and `false_label`. Note: Clicking on buttons in the above preview will break it and redirect to the meetings index page. -## Parameters +## SelectPanelComponent -* `BooleanComponent` requires `true_label` and `false_label`. -* `SegmentedComponent` accepts items via a block using `with_item(label:, value:)`. +A multiselect select panel based quick filter. Select panel items are provided via `with_item` slots. +Navigation happens when items are checked and the "Apply" button is clicked. + +<%= embed OpPrimer::QuickFilterPreview, :select_panel_with_active_filter, panels: %i[source] %> + +Note: Clicking on buttons in the above preview will break it and redirect to the meetings index page. diff --git a/lookbook/previews/op_primer/quick_filter_preview.rb b/lookbook/previews/op_primer/quick_filter_preview.rb index bd680dd0858..239f66a683c 100644 --- a/lookbook/previews/op_primer/quick_filter_preview.rb +++ b/lookbook/previews/op_primer/quick_filter_preview.rb @@ -31,11 +31,11 @@ module OpPrimer # @logical_path OpenProject/Primer class QuickFilterPreview < Lookbook::Preview - def segmented + def segmented_control render_with_template(locals: { query: meeting_query }) end - def segmented_with_active_filter + def segmented_control_with_active_filter query = meeting_query query.where("time", "=", ["future"]) render_with_template(locals: { query: }) @@ -47,6 +47,12 @@ module OpPrimer render_with_template(locals: { query: }) end + def select_panel_with_active_filter + query = meeting_query + query.where("project_id", "=", [Project.visible.first&.id.to_s].compact) + render_with_template(locals: { query: }) + end + private def meeting_query diff --git a/lookbook/previews/op_primer/quick_filter_preview/segmented.html.erb b/lookbook/previews/op_primer/quick_filter_preview/segmented_control.html.erb similarity index 84% rename from lookbook/previews/op_primer/quick_filter_preview/segmented.html.erb rename to lookbook/previews/op_primer/quick_filter_preview/segmented_control.html.erb index ca795c2a13b..7bfc4ff0687 100644 --- a/lookbook/previews/op_primer/quick_filter_preview/segmented.html.erb +++ b/lookbook/previews/op_primer/quick_filter_preview/segmented_control.html.erb @@ -1,5 +1,5 @@ <%= render( - OpPrimer::QuickFilter::SegmentedComponent.new( + OpPrimer::QuickFilter::SegmentedControlComponent.new( name: "Meeting type", query: query, filter_key: :type, diff --git a/lookbook/previews/op_primer/quick_filter_preview/segmented_with_active_filter.html.erb b/lookbook/previews/op_primer/quick_filter_preview/segmented_control_with_active_filter.html.erb similarity index 85% rename from lookbook/previews/op_primer/quick_filter_preview/segmented_with_active_filter.html.erb rename to lookbook/previews/op_primer/quick_filter_preview/segmented_control_with_active_filter.html.erb index c87266f8f02..258af6fafa2 100644 --- a/lookbook/previews/op_primer/quick_filter_preview/segmented_with_active_filter.html.erb +++ b/lookbook/previews/op_primer/quick_filter_preview/segmented_control_with_active_filter.html.erb @@ -1,5 +1,5 @@ <%= render( - OpPrimer::QuickFilter::SegmentedComponent.new( + OpPrimer::QuickFilter::SegmentedControlComponent.new( name: "Time", query: query, filter_key: :time, diff --git a/lookbook/previews/op_primer/quick_filter_preview/select_panel_with_active_filter.html.erb b/lookbook/previews/op_primer/quick_filter_preview/select_panel_with_active_filter.html.erb new file mode 100644 index 00000000000..62b735a84aa --- /dev/null +++ b/lookbook/previews/op_primer/quick_filter_preview/select_panel_with_active_filter.html.erb @@ -0,0 +1,12 @@ +<%= render( + OpPrimer::QuickFilter::SelectPanelComponent.new( + name: "Project", + query: query, + filter_key: :project_id, + path_args: [:meetings] + ) + ) do |component| + Project.visible.each do |project| + component.with_item(label: project.name, value: project.id) + end + end %> 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 eaee4f8e5d5..834e1c6ee19 100644 --- a/modules/auth_saml/app/contracts/saml/providers/base_contract.rb +++ b/modules/auth_saml/app/contracts/saml/providers/base_contract.rb @@ -47,6 +47,8 @@ module Saml url: { allow_blank: true, allow_nil: true, schemes: %w[http https] }, if: -> { model.metadata_url_changed? } + attribute :idp_entity_id + attribute :idp_sso_service_url validates :idp_sso_service_url, url: { schemes: %w[http https] }, diff --git a/modules/auth_saml/app/forms/saml/providers/metadata_url_form.rb b/modules/auth_saml/app/forms/saml/providers/metadata_url_form.rb index 4be72e20603..e3e7c47325d 100644 --- a/modules/auth_saml/app/forms/saml/providers/metadata_url_form.rb +++ b/modules/auth_saml/app/forms/saml/providers/metadata_url_form.rb @@ -40,6 +40,14 @@ module Saml caption: I18n.t("saml.instructions.metadata_url"), input_width: :xlarge ) + f.text_field( + name: :idp_entity_id, + label: I18n.t("activerecord.attributes.saml/provider.idp_entity_id"), + required: false, + disabled: provider.seeded_from_env?, + caption: I18n.t("saml.instructions.idp_entity_id"), + input_width: :xlarge + ) end end end diff --git a/modules/auth_saml/app/forms/saml/providers/metadata_xml_form.rb b/modules/auth_saml/app/forms/saml/providers/metadata_xml_form.rb index 51024a6dc1c..f4ecd4425fc 100644 --- a/modules/auth_saml/app/forms/saml/providers/metadata_xml_form.rb +++ b/modules/auth_saml/app/forms/saml/providers/metadata_xml_form.rb @@ -42,6 +42,14 @@ module Saml rows: 10, input_width: :medium ) + f.text_field( + name: :idp_entity_id, + label: I18n.t("activerecord.attributes.saml/provider.idp_entity_id"), + required: false, + disabled: provider.seeded_from_env?, + caption: I18n.t("saml.instructions.idp_entity_id"), + input_width: :xlarge + ) end end end diff --git a/modules/auth_saml/app/models/saml/provider.rb b/modules/auth_saml/app/models/saml/provider.rb index e9aeae7fc51..1843c2e81e7 100644 --- a/modules/auth_saml/app/models/saml/provider.rb +++ b/modules/auth_saml/app/models/saml/provider.rb @@ -11,6 +11,7 @@ module Saml store_attribute :options, :metadata_xml, :string store_attribute :options, :last_metadata_update, :datetime + store_attribute :options, :idp_entity_id, :string store_attribute :options, :idp_sso_service_url, :string store_attribute :options, :idp_slo_service_url, :string diff --git a/modules/auth_saml/app/services/saml/metadata_document.rb b/modules/auth_saml/app/services/saml/metadata_document.rb new file mode 100644 index 00000000000..5d7855d46c9 --- /dev/null +++ b/modules/auth_saml/app/services/saml/metadata_document.rb @@ -0,0 +1,152 @@ +# 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 Saml + # Prepares SAML metadata XML for parsing by ruby-saml. + # + # Federation aggregates MAY contain thousands of individual entities. + # Using ruby-saml directly would load the full document into REXML, which is extremely slow. + # This class streams the XML and tries to extract the matching single EntityDescriptor when we can. + class MetadataDocument + class MetadataTooLargeError < StandardError; end + + class FederationMetadataError < StandardError; end + + MAX_SIZE = 150.megabytes + + def self.prepare(source, entity_id: nil) + new(source, entity_id:).prepare + end + + def initialize(source, entity_id: nil) + @source = source + @entity_id = entity_id.presence + end + + def prepare + if aggregate? + read_entity_fragment! + else + read_all + end + end + + def read_entity_fragment! + fragment = extract_entity_fragment + if fragment.nil? + message = + if @entity_id + "Entity '#{@entity_id}' not found in federation aggregate" + else + "No identity provider found in federation aggregate" + end + raise FederationMetadataError, message + end + + fragment + end + + # Decide whether the document is a federation aggregate by inspecting its root element. + # Using +Nokogiri::XML::Reader+, we only advance to the root element and stop based on it. + def aggregate? + with_reader_io do |io| + Nokogiri::XML::Reader(io).each do |node| + next unless node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT + + return node.local_name == "EntitiesDescriptor" + end + end + + false + end + + private + + def extract_entity_fragment + if @entity_id + find_entity_by_id + else + find_first_idp_entity + end + end + + # We try to prevent calling outer_xml on all entities when looking. + # Instead, we can only look at entityID attribute until the target is found, + # and then call outer_xml only on that fragment. + def find_entity_by_id + with_reader_io do |io| + Nokogiri::XML::Reader(io).each do |node| + next unless entity_descriptor_element?(node) + next unless node.attribute("entityID") == @entity_id + + return node.outer_xml + end + end + + nil + end + + def find_first_idp_entity + with_reader_io do |io| + Nokogiri::XML::Reader(io).each do |node| + next unless entity_descriptor_element?(node) + + fragment = node.outer_xml + return fragment if idp_descriptor_fragment?(fragment) + end + end + + nil + end + + def idp_descriptor_fragment?(fragment) + Nokogiri::XML.fragment(fragment).at_xpath(".//*[local-name()='IDPSSODescriptor']").present? + end + + def entity_descriptor_element?(node) + node.node_type == Nokogiri::XML::Reader::TYPE_ELEMENT && node.local_name == "EntityDescriptor" + end + + def read_all + return @source if @source.is_a?(String) + + with_reader_io(&:read) + end + + def with_reader_io(&) + if @source.is_a?(String) + StringIO.open(@source, &) + else + @source.rewind + yield @source + end + end + end +end diff --git a/modules/auth_saml/app/services/saml/metadata_fetcher.rb b/modules/auth_saml/app/services/saml/metadata_fetcher.rb new file mode 100644 index 00000000000..32711f7e4fd --- /dev/null +++ b/modules/auth_saml/app/services/saml/metadata_fetcher.rb @@ -0,0 +1,69 @@ +# 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 Saml + class MetadataFetcher + include ActionView::Helpers::NumberHelper + + def self.fetch(url, &) + new(url).fetch(&) + end + + def initialize(url) + @url = url + end + + def fetch + Tempfile.create("saml-metadata") do |file| + file.binmode + + OpenProject::SsrfProtection.get(@url) do |response| + unless response.is_a?(Net::HTTPSuccess) + raise OneLogin::RubySaml::HttpError, + "Failed to fetch idp metadata: #{response.code}: #{response.message}" + end + + bytes_written = 0 + response.read_body do |chunk| + file.write(chunk) + bytes_written += chunk.bytesize + if bytes_written > MetadataDocument::MAX_SIZE + raise MetadataDocument::MetadataTooLargeError, + "Metadata exceeds max size of #{number_to_human_size(MetadataDocument::MAX_SIZE, precision: 2)}" + end + end + end + + file.rewind + yield file + end + end + end +end diff --git a/modules/auth_saml/app/services/saml/update_metadata_service.rb b/modules/auth_saml/app/services/saml/update_metadata_service.rb index 3bb26271904..aff7267ec1f 100644 --- a/modules/auth_saml/app/services/saml/update_metadata_service.rb +++ b/modules/auth_saml/app/services/saml/update_metadata_service.rb @@ -39,8 +39,14 @@ module Saml @provider = provider end - def call + def call # rubocop:disable Metrics/AbcSize apply_metadata(merge_certificates(fetch_metadata)) + rescue MetadataDocument::FederationMetadataError => e + OpenProject.logger.error(e) + ServiceResult.failure(result: provider, message: I18n.t("saml.metadata_parser.federation_metadata")) + rescue MetadataDocument::MetadataTooLargeError => e + OpenProject.logger.error(e) + ServiceResult.failure(result: provider, message: I18n.t("saml.metadata_parser.metadata_too_large")) rescue StandardError => e OpenProject.logger.error(e) ServiceResult.failure(result: provider, @@ -69,12 +75,16 @@ module Saml end def parse_xml - parser_instance.parse_to_hash(provider.metadata_xml) + xml = MetadataDocument.prepare(provider.metadata_xml, entity_id: provider.idp_entity_id) + parser_instance.parse_to_hash(xml) end def parse_url validate_metadata_url_host! - parser_instance.parse_remote_to_hash(provider.metadata_url) + MetadataFetcher.fetch(provider.metadata_url) do |file| + xml = MetadataDocument.prepare(file, entity_id: provider.idp_entity_id) + parser_instance.parse_to_hash(xml) + end end def validate_metadata_url_host! diff --git a/modules/auth_saml/config/locales/crowdin/af.yml b/modules/auth_saml/config/locales/crowdin/af.yml index 36600b59a5a..8b15fb8273f 100644 --- a/modules/auth_saml/config/locales/crowdin/af.yml +++ b/modules/auth_saml/config/locales/crowdin/af.yml @@ -12,6 +12,7 @@ af: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ af: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ af: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/ar.yml b/modules/auth_saml/config/locales/crowdin/ar.yml index 636a624beaf..5c67dffc766 100644 --- a/modules/auth_saml/config/locales/crowdin/ar.yml +++ b/modules/auth_saml/config/locales/crowdin/ar.yml @@ -12,6 +12,7 @@ ar: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ ar: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ar: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/az.yml b/modules/auth_saml/config/locales/crowdin/az.yml index 79942bfabf2..63ab3a54283 100644 --- a/modules/auth_saml/config/locales/crowdin/az.yml +++ b/modules/auth_saml/config/locales/crowdin/az.yml @@ -12,6 +12,7 @@ az: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ az: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ az: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/be.yml b/modules/auth_saml/config/locales/crowdin/be.yml index 812ed9874e7..1752936976c 100644 --- a/modules/auth_saml/config/locales/crowdin/be.yml +++ b/modules/auth_saml/config/locales/crowdin/be.yml @@ -12,6 +12,7 @@ be: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ be: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ be: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/bg.yml b/modules/auth_saml/config/locales/crowdin/bg.yml index 39d92d8ff5d..959894957ee 100644 --- a/modules/auth_saml/config/locales/crowdin/bg.yml +++ b/modules/auth_saml/config/locales/crowdin/bg.yml @@ -12,6 +12,7 @@ bg: sp_entity_id: Идентификатор на обслужващата единица metadata_url: URL на метаданните на доставчика на идентичност name_identifier_format: Формат на идентификатора на името + idp_entity_id: Identity provider entity ID idp_sso_service_url: Крайна точка за вход на доставчик на идентичности idp_slo_service_url: Крайна точка за вход на доставчик на идентичности idp_cert: Публично удостоверение на доставчика на идентификация @@ -44,6 +45,10 @@ bg: success: Успешно е актуализирана конфигурацията, като са използвани метаданните на доставчика на идентичност. invalid_url: Предоставеният URL адрес на метаданни е невалиден. Предоставете HTTP(s) URL адрес. error: 'Не се получи извличане на метаданните на доставчика на идентичност: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Все още няма конфигурирани доставчици на SAML. label_empty_description: Добавете доставчик, за да ги видите тук. @@ -110,6 +115,9 @@ bg: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/ca.yml b/modules/auth_saml/config/locales/crowdin/ca.yml index 4b3d295423a..fe38441b7b2 100644 --- a/modules/auth_saml/config/locales/crowdin/ca.yml +++ b/modules/auth_saml/config/locales/crowdin/ca.yml @@ -12,6 +12,7 @@ ca: sp_entity_id: ID de l'entitat de servei metadata_url: URL de metadades del proveïdor d'identitat name_identifier_format: Format de l'identificador de nom + idp_entity_id: Identity provider entity ID idp_sso_service_url: Punt d'inici de sessió del proveïdor d'identitat idp_slo_service_url: Punt final de sortida del proveïdor d'identitat idp_cert: Certificat públic del proveïdor d'identitat @@ -44,6 +45,10 @@ ca: success: S'ha actualitzat correctament la configuració utilitzant les metadades del proveïdor d'identitat. invalid_url: L'URL de les metadades proporcionades no és vàlid. Proporciona un URL HTTP(s). error: 'Ha fallat en recuperar les metadades del proveïdor d''identitat: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Encara no s'ha configurat cap proveïdor SAML. label_empty_description: Afegiu un proveïdor per veure'ls aquí. @@ -110,6 +115,9 @@ ca: ' metadata_url: 'El vostre proveïdor d''identitat proporciona un URL de metadades. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'El vostre proveïdor d''identitat proporciona una baixada XML de metadades. diff --git a/modules/auth_saml/config/locales/crowdin/ckb-IR.yml b/modules/auth_saml/config/locales/crowdin/ckb-IR.yml index bf96224fc28..bacecc1a826 100644 --- a/modules/auth_saml/config/locales/crowdin/ckb-IR.yml +++ b/modules/auth_saml/config/locales/crowdin/ckb-IR.yml @@ -12,6 +12,7 @@ ckb-IR: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ ckb-IR: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ckb-IR: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/cs.yml b/modules/auth_saml/config/locales/crowdin/cs.yml index c5f59e29631..9eec598040d 100644 --- a/modules/auth_saml/config/locales/crowdin/cs.yml +++ b/modules/auth_saml/config/locales/crowdin/cs.yml @@ -12,6 +12,7 @@ cs: sp_entity_id: ID entity služby metadata_url: Identity provider metadata URL name_identifier_format: Formát identifikátoru názvu + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ cs: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Zatím nenastaveni žádní poskytovatelé SAML. label_empty_description: Přidejte poskytovatele, abyste je viděli zde. @@ -110,6 +115,9 @@ cs: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/da.yml b/modules/auth_saml/config/locales/crowdin/da.yml index 19999134138..bf8da19040f 100644 --- a/modules/auth_saml/config/locales/crowdin/da.yml +++ b/modules/auth_saml/config/locales/crowdin/da.yml @@ -12,6 +12,7 @@ da: sp_entity_id: Tjenesteentitets-ID metadata_url: Identitetsudbydermetadata-URL name_identifier_format: Navnidentifikatorformat + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identitetsudbyder login endpoint idp_slo_service_url: IdP(Identity provider) logud endpoint idp_cert: Identitetsudbyders offentlige certifikat @@ -44,6 +45,10 @@ da: success: Opsætningen er opdateret vha. identitetsudbyderens metadata. invalid_url: Den angivne metadata-URL er ugyldig. Angiv en HTTP(S)-URL. error: 'Mislykkedes at hente identitetsudbydermetadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Ingen SAML-udbydere opsat endnu. label_empty_description: Tilføj en udbyder for at se denne her. @@ -110,6 +115,9 @@ da: ' metadata_url: 'Identitetsudbyderen leverer en metadata-URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Identitetsudbyderen leverer en metadata-XML download. diff --git a/modules/auth_saml/config/locales/crowdin/de.yml b/modules/auth_saml/config/locales/crowdin/de.yml index 42d4b909fc9..da532a7c777 100644 --- a/modules/auth_saml/config/locales/crowdin/de.yml +++ b/modules/auth_saml/config/locales/crowdin/de.yml @@ -12,6 +12,7 @@ de: sp_entity_id: Entity-ID des Services metadata_url: Metadaten-URL des Identitätsanbieters name_identifier_format: Format der Namenskennung + idp_entity_id: Entity-ID des Identitätsanbieters idp_sso_service_url: Endpunkt für die Anmeldung beim Identitätsanbieter idp_slo_service_url: Endpunkt für die Abmeldung beim Identitätsanbieter idp_cert: Öffentliches Zertifikat des Identitätsanbieters @@ -44,6 +45,10 @@ de: success: Die Konfiguration wurde unter Verwendung der Metadaten des Identitätsanbieters erfolgreich aktualisiert. invalid_url: Die angegebene Metadaten-URL ist ungültig. Geben Sie eine HTTP(s)-URL an. error: 'Abrufen der Metadaten des Identitätsanbieters fehlgeschlagen: %{error}' + federation_metadata: 'Die Metadaten-URL verweist auf eine Aggregation vieler Identitätsanbieter. Verwenden Sie die direkte Metadaten-URL Ihrer Einrichtung oder geben Sie die IdP-Entity-ID Ihrer Einrichtung in das Metadatenformular ein und versuchen Sie es erneut. + + ' + metadata_too_large: Die Metadaten-Datei überschreitet die maximal zulässige Größe. providers: label_empty_title: Noch keine SAML-Anbieter konfiguriert. label_empty_description: Fügen Sie einen Anbieter hinzu, um sie hier zu sehen. @@ -110,6 +115,9 @@ de: ' metadata_url: 'Ihr Identitätsanbieter stellt eine Metadaten-URL zur Verfügung. + ' + idp_entity_id: 'Optional: Nützlich, wenn die Metadaten-URL auf eine Aggregation vieler Identitätsanbieter verweist. Geben Sie die Entity-ID des Identitätsanbieters Ihrer Institution ein. Wenn Sie diese Aggregation nicht verwenden, können Sie dieses Feld freilassen. + ' metadata_xml: 'Ihr Identitätsanbieter bietet einen XML-Download für Metadaten an. diff --git a/modules/auth_saml/config/locales/crowdin/el.yml b/modules/auth_saml/config/locales/crowdin/el.yml index 3dbd942f551..b9cefce251a 100644 --- a/modules/auth_saml/config/locales/crowdin/el.yml +++ b/modules/auth_saml/config/locales/crowdin/el.yml @@ -12,6 +12,7 @@ el: sp_entity_id: ID Οντότητας Παρόχου Υπηρεσίας (SP) metadata_url: URL Μεταδεδομένων Παρόχου Ταυτότητας (IdP) name_identifier_format: Μορφή αναγνωριστικού ονόματος + idp_entity_id: Identity provider entity ID idp_sso_service_url: Τερματικό σημείο σύνδεσης Παρόχου Ταυτότητας (IdP Login) idp_slo_service_url: Τερματικό σημείο αποσύνδεσης Παρόχου Ταυτότητας (IdP Logout) idp_cert: Δημόσιο πιστοποιητικό του Παρόχου Ταυτότητας (IdP) @@ -44,6 +45,10 @@ el: success: Η διαμόρφωση ενημερώθηκε επιτυχώς με χρήση των μεταδεδομένων του παρόχου ταυτότητας. invalid_url: Το παρεχόμενο URL μεταδεδομένων δεν είναι έγκυρο. Παρακαλούμε δώστε ένα HTTP(s) URL. error: 'Αποτυχία ανάκτησης μεταδεδομένων παρόχου ταυτότητας: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Δεν έχουν ρυθμιστεί ακόμη πάροχοι SAML. label_empty_description: Προσθέστε έναν πάροχο για να τον δείτε εδώ. @@ -110,6 +115,9 @@ el: ' metadata_url: 'Ο πάροχος ταυτότητάς σας παρέχει ένα URL μεταδεδομένων. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Ο πάροχος ταυτότητάς σας παρέχει ένα αρχείο XML μεταδεδομένων προς λήψη. diff --git a/modules/auth_saml/config/locales/crowdin/eo.yml b/modules/auth_saml/config/locales/crowdin/eo.yml index 5f6f63e4c87..84c1f502471 100644 --- a/modules/auth_saml/config/locales/crowdin/eo.yml +++ b/modules/auth_saml/config/locales/crowdin/eo.yml @@ -12,6 +12,7 @@ eo: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ eo: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ eo: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/es.yml b/modules/auth_saml/config/locales/crowdin/es.yml index 715644bfbfe..ca3631abe9f 100644 --- a/modules/auth_saml/config/locales/crowdin/es.yml +++ b/modules/auth_saml/config/locales/crowdin/es.yml @@ -12,6 +12,7 @@ es: sp_entity_id: ID de la entidad de servicio metadata_url: URL de metadatos del proveedor de identidad name_identifier_format: Formato del identificador del nombre + idp_entity_id: Identity provider entity ID idp_sso_service_url: Terminal de inicio de sesión del proveedor de identidad idp_slo_service_url: Terminal de cierre de sesión del proveedor de identidad idp_cert: Certificado público del proveedor de identidad @@ -44,6 +45,10 @@ es: success: Se ha actualizado con éxito la configuración utilizando los metadatos del proveedor de identidad. invalid_url: La URL de metadatos proporcionada no es válida. Proporcione una URL HTTP(s). error: 'Error al recuperar los metadatos del proveedor de identidad: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Aún no hay proveedores SAML configurados. label_empty_description: Añada un proveedor para verlo aquí. @@ -110,6 +115,9 @@ es: ' metadata_url: 'Su proveedor de identidad proporciona una URL de metadatos. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Su proveedor de identidad proporciona una descarga XML de metadatos. diff --git a/modules/auth_saml/config/locales/crowdin/et.yml b/modules/auth_saml/config/locales/crowdin/et.yml index 1bafcff7533..3708e5cc04d 100644 --- a/modules/auth_saml/config/locales/crowdin/et.yml +++ b/modules/auth_saml/config/locales/crowdin/et.yml @@ -12,6 +12,7 @@ et: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ et: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ et: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/eu.yml b/modules/auth_saml/config/locales/crowdin/eu.yml index 8daea4f87bb..841e857a43d 100644 --- a/modules/auth_saml/config/locales/crowdin/eu.yml +++ b/modules/auth_saml/config/locales/crowdin/eu.yml @@ -12,6 +12,7 @@ eu: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ eu: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ eu: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/fa.yml b/modules/auth_saml/config/locales/crowdin/fa.yml index 16a0ac07a16..8220336b584 100644 --- a/modules/auth_saml/config/locales/crowdin/fa.yml +++ b/modules/auth_saml/config/locales/crowdin/fa.yml @@ -12,6 +12,7 @@ fa: sp_entity_id: شناسه سرویس metadata_url: آدرس فراداده سرور احراز هویت name_identifier_format: قالب متغیر نام + idp_entity_id: Identity provider entity ID idp_sso_service_url: مسیر ورود سرور احراز هویت idp_slo_service_url: مسیر خروج سرور احراز هویت idp_cert: مدرک عمومی سرور احراز هویت @@ -44,6 +45,10 @@ fa: success: ارتقای تنظیمات بوسیله فراداده سرویس احراز هویت با موفقیت انجام شد. invalid_url: مسیر فراداده صحیح نیست. لطفا آدرس صحیح HTTP(S) ارائه دهید. error: 'فراداده ارائه دهنده هویت بازیابی نشد: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: هیچ سخت‌افزار احراز هویتی پیکربندی نشده است. label_empty_description: یک ارائه دهنده اضافه کنید تا آن را در اینجا ببینید. @@ -110,6 +115,9 @@ fa: ' metadata_url: 'ارائه دهنده هویت شما یک URL فراداده ارائه می دهد. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'ارائه دهنده هویت شما یک دانلود XML فراداده ارائه می دهد. diff --git a/modules/auth_saml/config/locales/crowdin/fi.yml b/modules/auth_saml/config/locales/crowdin/fi.yml index d57e1c0ea02..943820a676e 100644 --- a/modules/auth_saml/config/locales/crowdin/fi.yml +++ b/modules/auth_saml/config/locales/crowdin/fi.yml @@ -12,6 +12,7 @@ fi: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ fi: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ fi: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/fil.yml b/modules/auth_saml/config/locales/crowdin/fil.yml index 4441d30067c..19fb12a99fc 100644 --- a/modules/auth_saml/config/locales/crowdin/fil.yml +++ b/modules/auth_saml/config/locales/crowdin/fil.yml @@ -12,6 +12,7 @@ fil: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ fil: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ fil: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/fr.yml b/modules/auth_saml/config/locales/crowdin/fr.yml index 86f2dd446df..0c0b71601ad 100644 --- a/modules/auth_saml/config/locales/crowdin/fr.yml +++ b/modules/auth_saml/config/locales/crowdin/fr.yml @@ -12,6 +12,7 @@ fr: sp_entity_id: ID de l'entité de service metadata_url: URL des métadonnées du fournisseur d'identité name_identifier_format: Format de l'identifiant du nom + idp_entity_id: Identity provider entity ID idp_sso_service_url: Point de terminaison de connexion du fournisseur d'identité idp_slo_service_url: Point de terminaison de déconnexion du fournisseur d'identité idp_cert: Certificat public du fournisseur d'identité @@ -44,6 +45,10 @@ fr: success: Mise à jour réussie de la configuration à l'aide des métadonnées du fournisseur d'identité. invalid_url: L'URL des métadonnées fournie n'est pas valide. Fournissez une URL HTTP(s). error: 'Échec de la récupération des métadonnées du fournisseur d''identité : %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Aucun fournisseur SAML n'est encore configuré. label_empty_description: Ajoutez un fournisseur pour le voir ici. @@ -110,6 +115,9 @@ fr: ' metadata_url: 'Votre fournisseur d''identité fournit une URL de métadonnées. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Votre fournisseur d''identité fournit un téléchargement de métadonnées XML. diff --git a/modules/auth_saml/config/locales/crowdin/he.yml b/modules/auth_saml/config/locales/crowdin/he.yml index 4479a920ea8..aa5a68d6068 100644 --- a/modules/auth_saml/config/locales/crowdin/he.yml +++ b/modules/auth_saml/config/locales/crowdin/he.yml @@ -12,6 +12,7 @@ he: sp_entity_id: מזהה ישות השירות metadata_url: כתובת URL של מטא-נתוני ספק הזהות name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ he: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ he: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/hi.yml b/modules/auth_saml/config/locales/crowdin/hi.yml index 2bf80d82f76..85430aba3fd 100644 --- a/modules/auth_saml/config/locales/crowdin/hi.yml +++ b/modules/auth_saml/config/locales/crowdin/hi.yml @@ -12,6 +12,7 @@ hi: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ hi: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ hi: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/hr.yml b/modules/auth_saml/config/locales/crowdin/hr.yml index 5508eae4385..3cdefb68450 100644 --- a/modules/auth_saml/config/locales/crowdin/hr.yml +++ b/modules/auth_saml/config/locales/crowdin/hr.yml @@ -12,6 +12,7 @@ hr: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ hr: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ hr: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/hu.yml b/modules/auth_saml/config/locales/crowdin/hu.yml index 367844c57de..34e675905c4 100644 --- a/modules/auth_saml/config/locales/crowdin/hu.yml +++ b/modules/auth_saml/config/locales/crowdin/hu.yml @@ -12,6 +12,7 @@ hu: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Névazonosító formátum + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ hu: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ hu: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/hy.yml b/modules/auth_saml/config/locales/crowdin/hy.yml index bb9dfe30506..9fa120f1ce7 100644 --- a/modules/auth_saml/config/locales/crowdin/hy.yml +++ b/modules/auth_saml/config/locales/crowdin/hy.yml @@ -12,6 +12,7 @@ hy: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ hy: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ hy: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/id.yml b/modules/auth_saml/config/locales/crowdin/id.yml index f4c814e5923..bfd36ec9f25 100644 --- a/modules/auth_saml/config/locales/crowdin/id.yml +++ b/modules/auth_saml/config/locales/crowdin/id.yml @@ -12,6 +12,7 @@ id: sp_entity_id: ID entitas layanan metadata_url: URL metadata penyedia identitas name_identifier_format: Format pengenal nama + idp_entity_id: Identity provider entity ID idp_sso_service_url: Titik akhir masuk penyedia identitas idp_slo_service_url: Titik akhir masuk penyedia identitas idp_cert: Sertifikat publik penyedia identitas @@ -44,6 +45,10 @@ id: success: Berhasil memperbarui konfigurasi menggunakan metadata penyedia identitas. invalid_url: URL metadata yang diberikan tidak valid. Berikan URL HTTP. error: 'Gagal mengambil metadata penyedia identitas: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Belum ada penyedia SAML yang dikonfigurasi. label_empty_description: Tambahkan penyedia untuk melihatnya di sini. @@ -110,6 +115,9 @@ id: ' metadata_url: 'Penyedia identitas Anda menyediakan URL metadata. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Penyedia identitas Anda menyediakan unduhan metadata XML. diff --git a/modules/auth_saml/config/locales/crowdin/it.yml b/modules/auth_saml/config/locales/crowdin/it.yml index 7c1dbf55cc1..7885fd8e2d2 100644 --- a/modules/auth_saml/config/locales/crowdin/it.yml +++ b/modules/auth_saml/config/locales/crowdin/it.yml @@ -12,6 +12,7 @@ it: sp_entity_id: ID dell'entità di servizio metadata_url: URL dei metadati del fornitore di identità name_identifier_format: Formato dell'identificatore del nome + idp_entity_id: Identity provider entity ID idp_sso_service_url: Endpoint di login del fornitore di identità idp_slo_service_url: Endpoint di logout del fornitore di identità idp_cert: Certificato pubblico del fornitore di identità @@ -44,6 +45,10 @@ it: success: La configurazione è stata aggiornata utilizzando i metadati del fornitore di identità. invalid_url: L'URL dei metadati forniti non è valido. Fornire un URL HTTP(s). error: 'Impossibile recuperare i metadati del fornitore di identità: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Nessun fornitore SAML configurato. label_empty_description: Aggiungi un fornitore per vederli qui. @@ -110,6 +115,9 @@ it: ' metadata_url: 'Il tuo fornitore di identità fornisce un URL di metadati. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Il tuo fornitore di identità fornisce un download in XML dei metadati. diff --git a/modules/auth_saml/config/locales/crowdin/ja.yml b/modules/auth_saml/config/locales/crowdin/ja.yml index 247c542620b..748ab378d94 100644 --- a/modules/auth_saml/config/locales/crowdin/ja.yml +++ b/modules/auth_saml/config/locales/crowdin/ja.yml @@ -12,6 +12,7 @@ ja: sp_entity_id: サービス・エンティティID metadata_url: ID プロバイダのメタデータ URL name_identifier_format: 名前識別子の形式 + idp_entity_id: Identity provider entity ID idp_sso_service_url: アイデンティティ・プロバイダのログイン・エンドポイント idp_slo_service_url: アイデンティティプロバイダのログアウトエンドポイント idp_cert: ID プロバイダの公開証明書 @@ -44,6 +45,10 @@ ja: success: ID プロバイダのメタデータを使用した構成の更新に成功しました。 invalid_url: 提供されたメタデータの URL が無効です。HTTP(s) URLを指定してください。 error: ID プロバイダのメタデータの取得に失敗しました: %{error} + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: SAML プロバイダはまだ構成されていない。 label_empty_description: プロバイダーを追加して、ここでご覧ください。 @@ -110,6 +115,9 @@ ja: ' metadata_url: 'ID プロバイダはメタデータ URL を提供する。 + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'ID プロバイダがメタデータ XML をダウンロードする。 diff --git a/modules/auth_saml/config/locales/crowdin/ka.yml b/modules/auth_saml/config/locales/crowdin/ka.yml index 8af2aa6c716..e6d0ee9182b 100644 --- a/modules/auth_saml/config/locales/crowdin/ka.yml +++ b/modules/auth_saml/config/locales/crowdin/ka.yml @@ -12,6 +12,7 @@ ka: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ ka: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ka: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/kk.yml b/modules/auth_saml/config/locales/crowdin/kk.yml index 8b556f13080..9054cfe9ece 100644 --- a/modules/auth_saml/config/locales/crowdin/kk.yml +++ b/modules/auth_saml/config/locales/crowdin/kk.yml @@ -12,6 +12,7 @@ kk: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ kk: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ kk: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/ko.yml b/modules/auth_saml/config/locales/crowdin/ko.yml index c2b28111b68..e26820b2c11 100644 --- a/modules/auth_saml/config/locales/crowdin/ko.yml +++ b/modules/auth_saml/config/locales/crowdin/ko.yml @@ -12,6 +12,7 @@ ko: sp_entity_id: 서비스 엔티티 ID metadata_url: ID 공급자 메타데이터 URL name_identifier_format: 이름 식별자 형식 + idp_entity_id: Identity provider entity ID idp_sso_service_url: ID 공급자 로그인 엔드포인트 idp_slo_service_url: ID 공급자 로그아웃 엔드포인트 idp_cert: ID 공급자의 공개 인증서 @@ -44,6 +45,10 @@ ko: success: ID 공급자 메타데이터를 사용하여 구성을 업데이트했습니다. invalid_url: 제공한 메타데이터 URL이 유효하지 않습니다. HTTP(s) URL을 입력하세요. error: 'ID 공급자 메타데이터를 검색하지 못했습니다: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: 아직 구성된 SAML 공급자가 없습니다. label_empty_description: 여기에서 보려면 공급자를 추가합니다. @@ -110,6 +115,9 @@ ko: ' metadata_url: 'ID 공급자가 메타데이터 URL을 제공합니다. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'ID 공급자가 메타데이터 XML 다운로드를 제공합니다. diff --git a/modules/auth_saml/config/locales/crowdin/lt.yml b/modules/auth_saml/config/locales/crowdin/lt.yml index 24f060d22c3..6bd003884d3 100644 --- a/modules/auth_saml/config/locales/crowdin/lt.yml +++ b/modules/auth_saml/config/locales/crowdin/lt.yml @@ -12,6 +12,7 @@ lt: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ lt: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ lt: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/lv.yml b/modules/auth_saml/config/locales/crowdin/lv.yml index eae507b9461..ad99ab2f374 100644 --- a/modules/auth_saml/config/locales/crowdin/lv.yml +++ b/modules/auth_saml/config/locales/crowdin/lv.yml @@ -12,6 +12,7 @@ lv: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ lv: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ lv: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/mn.yml b/modules/auth_saml/config/locales/crowdin/mn.yml index 03a00b7711a..f618489ae3b 100644 --- a/modules/auth_saml/config/locales/crowdin/mn.yml +++ b/modules/auth_saml/config/locales/crowdin/mn.yml @@ -12,6 +12,7 @@ mn: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ mn: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ mn: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/ms.yml b/modules/auth_saml/config/locales/crowdin/ms.yml index c429036067d..9fb3cd30f9e 100644 --- a/modules/auth_saml/config/locales/crowdin/ms.yml +++ b/modules/auth_saml/config/locales/crowdin/ms.yml @@ -12,6 +12,7 @@ ms: sp_entity_id: ID entiti perkhidmatan metadata_url: URL metadata pembekal identiti name_identifier_format: Format pengecam nama + idp_entity_id: Identity provider entity ID idp_sso_service_url: Titik akhir log masuk pembekal identiti idp_slo_service_url: Titik akhir logout pembekal identiti idp_cert: Sijil awam pemberi identiti @@ -44,6 +45,10 @@ ms: success: Berjaya mengemas kini konfigurasi menggunakan metadata pembekal identiti. invalid_url: URL metadata yang diberikan adalah tidak sah. Sediakan URL HTTP. error: 'Gagal mendapatkan semula metadata pembekal identiti: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Tiada pembekal SAML dikonfigurasikan lagi. label_empty_description: Tambah pembekal untuk melihat mereka di sini. @@ -110,6 +115,9 @@ ms: ' metadata_url: 'Pembekal identiti anda menyediakan URL metadata. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Pembekal identiti anda menyediakan muat turun XML metadata. diff --git a/modules/auth_saml/config/locales/crowdin/ne.yml b/modules/auth_saml/config/locales/crowdin/ne.yml index edd3460a6a8..1492e7a4df2 100644 --- a/modules/auth_saml/config/locales/crowdin/ne.yml +++ b/modules/auth_saml/config/locales/crowdin/ne.yml @@ -12,6 +12,7 @@ ne: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ ne: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ne: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/nl.yml b/modules/auth_saml/config/locales/crowdin/nl.yml index 4e618c9fc98..e786601a540 100644 --- a/modules/auth_saml/config/locales/crowdin/nl.yml +++ b/modules/auth_saml/config/locales/crowdin/nl.yml @@ -12,6 +12,7 @@ nl: sp_entity_id: Service-entiteit ID metadata_url: URL metagegevens identiteitsprovider name_identifier_format: Formaat naamidentificatie + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identiteit provider login eindpunt idp_slo_service_url: Identiteit provider loguit eindpunt idp_cert: Publiek certificaat van identiteitsprovider @@ -44,6 +45,10 @@ nl: success: De configuratie is succesvol bijgewerkt met de metagegevens van de identiteits- provider. invalid_url: Verstrekte metadata URL is ongeldig. Geef een HTTP(s) URL. error: 'Fout bij het ophalen van de metagegevens van de identiteitaanbieder: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Er zijn nog geen SAML-providers geconfigureerd. label_empty_description: Voeg een provider toe om ze hier te zien. @@ -90,7 +95,7 @@ nl: configuration: De endpoint URL's voor de identity provider, certificaten en verdere SAML opties configureren. configuration_metadata: Deze informatie is vooraf gevuld met behulp van de meegeleverde metadata. In de meeste gevallen hoeven ze niet bewerkt te worden. encryption: Configureer assertie handtekeningen en encryptie voor SAML verzoeken en antwoorden. - encryption_form: You may optionally want to encrypt the assertion response, or have requests from OpenProject signed. + encryption_form: U kunt optioneel de assertion-response versleutelen of de verzoeken van OpenProject laten ondertekenen. mapping: Pas de mapping tussen de SAML respons en gebruikerskenmerken handmatig aan in OpenProject. requested_attributes: Definieer de set kenmerken die moet worden opgevraagd in het SAML-verzoek dat naar uw identity provider wordt gestuurd. seeded_from_env: Deze provider is geplaatst vanuit de omgevingsconfiguratie. Deze kan niet worden bewerkt. @@ -102,13 +107,16 @@ nl: documentation_link: 'Please refer to our [documentation on configuring SAML providers](docs_url) for more information on these configuration options. ' - display_name: 'The name of the provider. This will be displayed as the login button and in the list of providers. + display_name: 'De naam van de provider. Deze naam wordt getoond op de inlogknop en in de lijst met providers. ' - metadata_none: 'Your identity provider does not have a metadata endpoint or XML download option. You can configure it manually. + metadata_none: 'Uw identiteitsprovider heeft geen metadata-endpoint of XML-downloadoptie. U kunt deze handmatig configureren. ' - metadata_url: 'Your identity provider provides a metadata URL. + metadata_url: 'Uw identiteitsprovider verstrekt een metadata-URL. + + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. ' metadata_xml: 'Your identity provider provides a metadata XML download. @@ -186,6 +194,6 @@ nl: icon: 'Optionally provide a public URL to an icon graphic that will be displayed next to the provider name. ' - metadata_for_idp: 'This information might be requested by your SAML identity provider. + metadata_for_idp: 'Uw SAML-identiteitsprovider kan om deze informatie vragen. ' diff --git a/modules/auth_saml/config/locales/crowdin/no.yml b/modules/auth_saml/config/locales/crowdin/no.yml index 939dcc5b35d..5c24aeee3ed 100644 --- a/modules/auth_saml/config/locales/crowdin/no.yml +++ b/modules/auth_saml/config/locales/crowdin/no.yml @@ -12,6 +12,7 @@ sp_entity_id: Tjeneste enhet ID metadata_url: Identitetsleverandør metadata URL name_identifier_format: Navn identifikator format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identitet leverandør påloggingsendepunkt idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/pl.yml b/modules/auth_saml/config/locales/crowdin/pl.yml index 1f499792eea..b5183096289 100644 --- a/modules/auth_saml/config/locales/crowdin/pl.yml +++ b/modules/auth_saml/config/locales/crowdin/pl.yml @@ -12,6 +12,7 @@ pl: sp_entity_id: Identyfikator jednostki usługowej metadata_url: Adres URL metadanych dostawcy tożsamości name_identifier_format: Format identyfikatora nazwy + idp_entity_id: Identity provider entity ID idp_sso_service_url: Punkt końcowy logowania dostawcy tożsamości idp_slo_service_url: Punkt końcowy wylogowania dostawcy tożsamości idp_cert: Publiczny certyfikat dostawcy tożsamości @@ -44,6 +45,10 @@ pl: success: Pomyślnie zaktualizowano konfigurację, używając metadanych dostawcy tożsamości. invalid_url: Podany adres URL metadanych jest nieprawidłowy. Podaj adres URL HTTP(s). error: 'Nie udało się pobrać metadanych dostawcy identyfikacji: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Brak skonfigurowanych dostawców SAML. label_empty_description: Dodaj dostawcę, aby zobaczyć go tutaj. @@ -110,6 +115,9 @@ pl: ' metadata_url: 'Dostawca tożsamości podaje adres URL metadanych. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Twój dostawca tożsamości udostępnia metadane pobierania XML. diff --git a/modules/auth_saml/config/locales/crowdin/pt-BR.yml b/modules/auth_saml/config/locales/crowdin/pt-BR.yml index b7ca47cf570..85103a738da 100644 --- a/modules/auth_saml/config/locales/crowdin/pt-BR.yml +++ b/modules/auth_saml/config/locales/crowdin/pt-BR.yml @@ -12,6 +12,7 @@ pt-BR: sp_entity_id: ID da entidade do serviço metadata_url: URL de metadados do provedor de identidade name_identifier_format: Formato do identificador de nome + idp_entity_id: Identity provider entity ID idp_sso_service_url: Endpoint de login do provedor de identidade idp_slo_service_url: Endpoint de logout do provedor de identidade idp_cert: Certificado público de provedor de identidade @@ -44,6 +45,10 @@ pt-BR: success: Configuração atualizada com sucesso usando os metadados do provedor de identidade. invalid_url: O URL de metadados fornecido é inválido. Forneça um URL HTTP(s). error: 'Falha ao recuperar os metadados do provedor de identidade: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Nenhum provedor SAML configurado até o momento. label_empty_description: Adicione um provedor para vê-lo aqui. @@ -110,6 +115,9 @@ pt-BR: ' metadata_url: 'Seu provedor de identidade fornece uma URL de metadados. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Seu provedor de identidade oferece a opção de baixar o XML de metadados. diff --git a/modules/auth_saml/config/locales/crowdin/pt-PT.yml b/modules/auth_saml/config/locales/crowdin/pt-PT.yml index e04624c5074..fd14fc54e0a 100644 --- a/modules/auth_saml/config/locales/crowdin/pt-PT.yml +++ b/modules/auth_saml/config/locales/crowdin/pt-PT.yml @@ -12,6 +12,7 @@ pt-PT: sp_entity_id: ID da entidade de serviço metadata_url: URL dos metadados do fornecedor de identidade name_identifier_format: Formato do identificador do nome + idp_entity_id: Identity provider entity ID idp_sso_service_url: Ponto final do início de sessão do fornecedor de identidade idp_slo_service_url: Ponto final do fim de sessão do fornecedor de identidade idp_cert: Certificado público do fornecedor de identidade @@ -44,6 +45,10 @@ pt-PT: success: Atualizou a configuração utilizando os metadados do fornecedor de identidade com êxito. invalid_url: O URL de metadados fornecido é inválido. Forneça um URL HTTP(s). error: 'Falha ao recuperar os metadados do fornecedor de identidade: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Ainda não existem fornecedores SAML configurados. label_empty_description: Adicione um fornecedor para vê-lo aqui. @@ -110,6 +115,9 @@ pt-PT: ' metadata_url: 'O seu fornecedor de identidade fornece um URL de metadados. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'O seu fornecedor de identidade fornece uma transferência XML de metadados. diff --git a/modules/auth_saml/config/locales/crowdin/ro.yml b/modules/auth_saml/config/locales/crowdin/ro.yml index 306cea9d806..a981c9452a9 100644 --- a/modules/auth_saml/config/locales/crowdin/ro.yml +++ b/modules/auth_saml/config/locales/crowdin/ro.yml @@ -12,6 +12,7 @@ ro: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ ro: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ ro: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/ru.yml b/modules/auth_saml/config/locales/crowdin/ru.yml index d0229b35fce..ea725efc33b 100644 --- a/modules/auth_saml/config/locales/crowdin/ru.yml +++ b/modules/auth_saml/config/locales/crowdin/ru.yml @@ -12,6 +12,7 @@ ru: sp_entity_id: Идентификатор объекта обслуживания metadata_url: URL метаданных провайдера идентификации name_identifier_format: Формат идентификатора имени + idp_entity_id: Identity provider entity ID idp_sso_service_url: Конечная точка входа провайдера идентификации idp_slo_service_url: Конечная точка выхода провайдера идентификации idp_cert: Публичный сертификат провайдера идентификации @@ -44,6 +45,10 @@ ru: success: Конфигурация успешно обновлена с использованием метаданных провайдера идентификации. invalid_url: Предоставленный URL-адрес метаданных недействителен. Укажите URL-адрес HTTP(s). error: 'Не удалось получить метаданные провайдера идентификации: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Провайдеры SAML еще не настроены. label_empty_description: Добавьте провайдера, чтобы увидеть его здесь. @@ -110,6 +115,9 @@ ru: ' metadata_url: 'Ваш провайдер идентификации предоставляет URL-адрес метаданных. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Ваш провайдер идентификации предоставляет XML-загрузку метаданных. diff --git a/modules/auth_saml/config/locales/crowdin/rw.yml b/modules/auth_saml/config/locales/crowdin/rw.yml index d0fc8577c42..ecaf196d311 100644 --- a/modules/auth_saml/config/locales/crowdin/rw.yml +++ b/modules/auth_saml/config/locales/crowdin/rw.yml @@ -12,6 +12,7 @@ rw: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ rw: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ rw: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/si.yml b/modules/auth_saml/config/locales/crowdin/si.yml index 9259643391a..4574e12aff0 100644 --- a/modules/auth_saml/config/locales/crowdin/si.yml +++ b/modules/auth_saml/config/locales/crowdin/si.yml @@ -12,6 +12,7 @@ si: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ si: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ si: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/sk.yml b/modules/auth_saml/config/locales/crowdin/sk.yml index 4ccc15d4ec8..cbfbb2c589b 100644 --- a/modules/auth_saml/config/locales/crowdin/sk.yml +++ b/modules/auth_saml/config/locales/crowdin/sk.yml @@ -12,6 +12,7 @@ sk: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ sk: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ sk: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/sl.yml b/modules/auth_saml/config/locales/crowdin/sl.yml index ebc966a6c4c..95373bc5c08 100644 --- a/modules/auth_saml/config/locales/crowdin/sl.yml +++ b/modules/auth_saml/config/locales/crowdin/sl.yml @@ -12,6 +12,7 @@ sl: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ sl: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ sl: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/sr.yml b/modules/auth_saml/config/locales/crowdin/sr.yml index db13f4def80..64d5f8f982a 100644 --- a/modules/auth_saml/config/locales/crowdin/sr.yml +++ b/modules/auth_saml/config/locales/crowdin/sr.yml @@ -12,6 +12,7 @@ sr: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ sr: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ sr: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/sv.yml b/modules/auth_saml/config/locales/crowdin/sv.yml index 35a01d20c80..3849223553b 100644 --- a/modules/auth_saml/config/locales/crowdin/sv.yml +++ b/modules/auth_saml/config/locales/crowdin/sv.yml @@ -12,6 +12,7 @@ sv: sp_entity_id: ID för serviceenhet metadata_url: Identitetsleverantör metadata URL name_identifier_format: Format för namnidentifierare + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identitetsleverantörens inloggningsändpunkt idp_slo_service_url: Utloggningsslutpunkt för identitetsleverantör idp_cert: Offentligt certifikat för identitetsleverantör @@ -44,6 +45,10 @@ sv: success: Uppdaterade konfigurationen med hjälp av identitetsleverantörens metadata. invalid_url: Tillhandahållen metadata URL är ogiltig. Ange en HTTP(s) URL. error: 'Misslyckades med att hämta metadata för identitetsleverantören: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Inga SAML-leverantörer har konfigurerats ännu. label_empty_description: Lägg till en leverantör för att se dem här. @@ -110,6 +115,9 @@ sv: ' metadata_url: 'Din identitetsleverantör tillhandahåller en URL för metadata. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Din identitetsleverantör tillhandahåller en XML-nedladdning av metadata. diff --git a/modules/auth_saml/config/locales/crowdin/th.yml b/modules/auth_saml/config/locales/crowdin/th.yml index 1ac0e47350f..a89f84ae7ea 100644 --- a/modules/auth_saml/config/locales/crowdin/th.yml +++ b/modules/auth_saml/config/locales/crowdin/th.yml @@ -12,6 +12,7 @@ th: sp_entity_id: รหัสระบุเอนทิตีบริการ (Service Entity ID) metadata_url: URL ข้อมูลเมทาดาตาของผู้ให้บริการระบุตัวตน (IdP) name_identifier_format: รูปแบบรหัสระบุชื่อ (Name Identifier Format) + idp_entity_id: Identity provider entity ID idp_sso_service_url: จุดลงชื่อเข้าใช้ของผู้ให้บริการระบุตัวตน (IdP) idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ th: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ th: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/tr.yml b/modules/auth_saml/config/locales/crowdin/tr.yml index ff8dafdebc5..0a50087de98 100644 --- a/modules/auth_saml/config/locales/crowdin/tr.yml +++ b/modules/auth_saml/config/locales/crowdin/tr.yml @@ -12,6 +12,7 @@ tr: sp_entity_id: Hizmet kuruluşu kimliği metadata_url: Kimlik sağlayıcı meta veri URL'si name_identifier_format: Ad tanımlayıcı biçimi + idp_entity_id: Identity provider entity ID idp_sso_service_url: Kimlik sağlayıcı oturum açma uç noktası idp_slo_service_url: Kimlik sağlayıcı oturum kapatma uç noktası idp_cert: Kamu kimlik belgesi sağlayıcısı. @@ -44,6 +45,10 @@ tr: success: Kimlik sağlayıcı meta verilerini kullanarak yapılandırma başarıyla güncelledi. invalid_url: Sağlanan meta veri URL'si geçersiz. Lütfen bir HTTP(s) URL'si sağlayın. error: 'Kimlik sağlayıcı meta verilerini alma işlemi başarısız oldu: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Henüz hiçbir SAML sağlayıcısı yapılandırılmadı. label_empty_description: Onları burada görmek için bir sağlayıcı ekleyin. @@ -108,6 +113,9 @@ tr: metadata_none: '' metadata_url: 'Kimlik sağlayıcınız bir meta veri URL''si sağlar. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Kimlik sağlayıcınız bir meta veri XML indirmesi sağlar. diff --git a/modules/auth_saml/config/locales/crowdin/uk.yml b/modules/auth_saml/config/locales/crowdin/uk.yml index 2615a3d05ef..b20ef7fa663 100644 --- a/modules/auth_saml/config/locales/crowdin/uk.yml +++ b/modules/auth_saml/config/locales/crowdin/uk.yml @@ -12,6 +12,7 @@ uk: sp_entity_id: ID сервісної організації metadata_url: URL-адреса метаданих постачальника ідентифікаційних даних name_identifier_format: Формат ідентифікатора імені + idp_entity_id: Identity provider entity ID idp_sso_service_url: Кінцева точка входу постачальника ідентифікаційних даних idp_slo_service_url: Кінцева точка виходу постачальника ідентифікаційних даних idp_cert: Загальнодоступний сертифікат постачальника ідентифікаційних даних @@ -44,6 +45,10 @@ uk: success: Конфігурацію оновлено за допомогою метаданих постачальника ідентифікаційних даних. invalid_url: Надано неправильну URL-адресу метаданих. Укажіть URL-адресу HTTP(s). error: 'Не вдалось отримати метадані постачальника ідентифікаційних даних: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Поки не налаштовано жодного постачальника послуг SAML. label_empty_description: Додайте постачальника послуг, і він з’явиться тут. @@ -110,6 +115,9 @@ uk: ' metadata_url: 'Ваш постачальник ідентифікаційних надає URL-адресу метаданих. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Ваш постачальник ідентифікаційних надає можливість завантаження XML метаданих. diff --git a/modules/auth_saml/config/locales/crowdin/uz.yml b/modules/auth_saml/config/locales/crowdin/uz.yml index 1b33f8105a4..878950b5fbb 100644 --- a/modules/auth_saml/config/locales/crowdin/uz.yml +++ b/modules/auth_saml/config/locales/crowdin/uz.yml @@ -12,6 +12,7 @@ uz: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -44,6 +45,10 @@ uz: success: Successfully updated the configuration using the identity provider metadata. invalid_url: Provided metadata URL is invalid. Provide a HTTP(s) URL. error: 'Failed to retrieve the identity provider metadata: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: No SAML providers configured yet. label_empty_description: Add a provider to see them here. @@ -110,6 +115,9 @@ uz: ' metadata_url: 'Your identity provider provides a metadata URL. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Your identity provider provides a metadata XML download. diff --git a/modules/auth_saml/config/locales/crowdin/vi.yml b/modules/auth_saml/config/locales/crowdin/vi.yml index 021e7f459ad..6e527eb2a68 100644 --- a/modules/auth_saml/config/locales/crowdin/vi.yml +++ b/modules/auth_saml/config/locales/crowdin/vi.yml @@ -12,6 +12,7 @@ vi: sp_entity_id: ID thực thể dịch vụ metadata_url: URL siêu dữ liệu của nhà cung cấp danh tính name_identifier_format: Định dạng nhận dạng tên + idp_entity_id: Identity provider entity ID idp_sso_service_url: Điểm cuối đăng nhập của nhà cung cấp danh tính idp_slo_service_url: Điểm cuối đăng xuất của nhà cung cấp danh tính idp_cert: Giấy chứng nhận công khai của nhà cung cấp danh tính @@ -44,6 +45,10 @@ vi: success: Đã cập nhật thành công cấu hình bằng siêu dữ liệu của nhà cung cấp danh tính. invalid_url: URL siêu dữ liệu được cung cấp không hợp lệ. Cung cấp (các) URL HTTP. error: 'Không truy xuất được siêu dữ liệu của nhà cung cấp danh tính: %{error}' + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: Chưa có nhà cung cấp SAML nào được định cấu hình. label_empty_description: Thêm nhà cung cấp để xem chúng ở đây. @@ -110,6 +115,9 @@ vi: ' metadata_url: 'Nhà cung cấp danh tính của bạn cung cấp URL siêu dữ liệu. + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: 'Nhà cung cấp danh tính của bạn cung cấp bản tải xuống XML siêu dữ liệu. diff --git a/modules/auth_saml/config/locales/crowdin/zh-CN.yml b/modules/auth_saml/config/locales/crowdin/zh-CN.yml index dad0b72ff76..5785f55ae5e 100644 --- a/modules/auth_saml/config/locales/crowdin/zh-CN.yml +++ b/modules/auth_saml/config/locales/crowdin/zh-CN.yml @@ -12,6 +12,7 @@ zh-CN: sp_entity_id: 服务实体 ID metadata_url: 身份提供商元数据URL name_identifier_format: 名称标识符格式 + idp_entity_id: Identity provider entity ID idp_sso_service_url: 身份供应商登录端点 idp_slo_service_url: 身份供应商注销端点 idp_cert: 身份提供商公共证书 @@ -44,6 +45,10 @@ zh-CN: success: 使用身份提供商元数据成功更新配置。 invalid_url: 提供的元数据 URL 无效。请提供一个 HTTP(s) URL。 error: 检索身份提商元数据失败: %{error} + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: 尚未配置 SAML 提供商。 label_empty_description: 在这里添加一个提供商以查看它们。 @@ -110,6 +115,9 @@ zh-CN: ' metadata_url: '您的身份提供商提供了一个元数据 URL 。 + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: '您的身份提供商提供了一个元数据 XML 下载。 diff --git a/modules/auth_saml/config/locales/crowdin/zh-TW.yml b/modules/auth_saml/config/locales/crowdin/zh-TW.yml index 91b92e6066d..290de9580b0 100644 --- a/modules/auth_saml/config/locales/crowdin/zh-TW.yml +++ b/modules/auth_saml/config/locales/crowdin/zh-TW.yml @@ -12,6 +12,7 @@ zh-TW: sp_entity_id: 服務實體 ID metadata_url: 身分提供商後設資料 URL name_identifier_format: 名稱識別碼格式 + idp_entity_id: Identity provider entity ID idp_sso_service_url: 身分提供商登入端點 idp_slo_service_url: 身分提供商登出端點 idp_cert: 身分提供商的公開證書 @@ -44,6 +45,10 @@ zh-TW: success: 已成功使用身分提供者元資料更新配置設定。 invalid_url: 提供的元資料 URL 無效。提供 HTTP(s) URL。 error: 擷取身分提供者元資料失敗: %{error} + federation_metadata: 'The metadata URL points to a federation aggregate (many identity providers). Use your institution''s direct metadata URL, or enter your institution''s IdP entity ID in the metadata form and try again. + + ' + metadata_too_large: The metadata file exceeds the maximum allowed size. providers: label_empty_title: 尚未設定 SAML 提供商。 label_empty_description: 增加可供查詢之提供商 @@ -110,6 +115,9 @@ zh-TW: ' metadata_url: '您的身分提供者會提供一個 metadata URL。 + ' + idp_entity_id: 'Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. Enter the entity ID of your institution''s identity provider. Leave blank for single-entity metadata URLs. + ' metadata_xml: '您的身分提供者會提供一個 metadata URL。 diff --git a/modules/auth_saml/config/locales/en.yml b/modules/auth_saml/config/locales/en.yml index 2ac0332c26e..611a4e662dd 100644 --- a/modules/auth_saml/config/locales/en.yml +++ b/modules/auth_saml/config/locales/en.yml @@ -12,6 +12,7 @@ en: sp_entity_id: Service entity ID metadata_url: Identity provider metadata URL name_identifier_format: Name identifier format + idp_entity_id: Identity provider entity ID idp_sso_service_url: Identity provider login endpoint idp_slo_service_url: Identity provider logout endpoint idp_cert: Public certificate of identity provider @@ -43,6 +44,10 @@ en: success: "Successfully updated the configuration using the identity provider metadata." invalid_url: "Provided metadata URL is invalid. Provide a HTTP(s) URL." error: "Failed to retrieve the identity provider metadata: %{error}" + federation_metadata: > + The metadata URL points to a federation aggregate (many identity providers). + Use your institution's direct metadata URL, or enter your institution's IdP entity ID in the metadata form and try again. + metadata_too_large: "The metadata file exceeds the maximum allowed size." providers: label_empty_title: "No SAML providers configured yet." label_empty_description: "Add a provider to see them here." @@ -107,6 +112,9 @@ en: Your identity provider does not have a metadata endpoint or XML download option. You can configure it manually. metadata_url: > Your identity provider provides a metadata URL. + idp_entity_id: > + Optional: Useful when the metadata URL points to a federation aggregate with a lot of entries. + Enter the entity ID of your institution's identity provider. Leave blank for single-entity metadata URLs. metadata_xml: > Your identity provider provides a metadata XML download. limit_self_registration: > diff --git a/modules/auth_saml/spec/fixtures/federation_metadata.xml b/modules/auth_saml/spec/fixtures/federation_metadata.xml new file mode 100644 index 00000000000..7ab347030a6 --- /dev/null +++ b/modules/auth_saml/spec/fixtures/federation_metadata.xml @@ -0,0 +1,443 @@ + + + + + + + + + + State University Portal + Student and staff portal of State University + + + + + + MIIDKzCCAhOgAwIBAgIUNKP1WT7mAMRllZ3z8EDR2to1VNYwDQYJKoZIhvcNAQELBQAwJTEjMCEG +A1UEAwwaaWRwLmV4YW1wbGUtdW5pdmVyc2l0eS5lZHUwHhcNMjYwNjAzMDg1NDI3WhcNMzYwNTMx +MDg1NDI3WjAlMSMwIQYDVQQDDBppZHAuZXhhbXBsZS11bml2ZXJzaXR5LmVkdTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAK+dgrVLuW+JCM2ST/SfA1J8XX3aCgtuU18Z1Xb8PcmMjQCJ +Ow0PDIApqp/JJAyt7KDiv8cgJgAmPMGbVQpcmMcOInBu+AvTsndagVqV7V3ePLwN/WOm+NPVoB2g +EEYGhF32gwZSQ0SHtJphxy4KoJv8CspVWRTviFU/pi1t8HsWJBLW6U6Jb7eLySM/G//6AFWFULdH +GImkAk/9BfT7iCINYHsOW0MO237UKw90qShxtFCB/fqPRC6eldC2kFkod9eIw9x7cMuH74QGVsCd +XAv+HUUtd6ov8Vn0xwaDiDxneXgKEBMwdVl97B+s9egUuif2TuMSYF09Qx7KREyayC0CAwEAAaNT +MFEwHQYDVR0OBBYEFHh0ON9CYmfpcEQYlxixtd6kkmHVMB8GA1UdIwQYMBaAFHh0ON9CYmfpcEQY +lxixtd6kkmHVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABSLwFVGf8L9+alT +RU3n3D+vyUOvb5zb3hMER3WN0p323nQyeZ7WVSfIy3vsD2PcdsDinYpM9NV9P5zU+11PgAMRwqGv +UnQLbklJ3d/5ciwdCVPUk+/c8pVwOnrCa5D6m1C8Or4Pnoxihz7sdmGoaGXdlrDhcwzosKx/AcT1 +aJNor+3SzkXJLzNfrYypBeUS8XzlzH3lTY+J1aYrfzXNK06XPCMlckKVL4nFVe0yDrSUk9DiLojy +b90TaOSCqAGzoecoV8MOCxef6EvFgHmPpq8oMycWal4Ud2zdugUOtnNWxUVvWS15L7O7VG1eley/z +UrWMUi2pWJ1Gk1NAFs8/0A= + + + + + + + State University + State University + https://www.state-university.edu + + + Alex + Smith + mailto:asmith@state-university.edu + + + + + + + + + + + Tech Institute Library + Electronic resources portal for Tech Institute staff + + + + + + MIIDKzCCAhOgAwIBAgIUNKP1WT7mAMRllZ3z8EDR2to1VNYwDQYJKoZIhvcNAQELBQAwJTEjMCEG +A1UEAwwaaWRwLmV4YW1wbGUtdW5pdmVyc2l0eS5lZHUwHhcNMjYwNjAzMDg1NDI3WhcNMzYwNTMx +MDg1NDI3WjAlMSMwIQYDVQQDDBppZHAuZXhhbXBsZS11bml2ZXJzaXR5LmVkdTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAK+dgrVLuW+JCM2ST/SfA1J8XX3aCgtuU18Z1Xb8PcmMjQCJ +Ow0PDIApqp/JJAyt7KDiv8cgJgAmPMGbVQpcmMcOInBu+AvTsndagVqV7V3ePLwN/WOm+NPVoB2g +EEYGhF32gwZSQ0SHtJphxy4KoJv8CspVWRTviFU/pi1t8HsWJBLW6U6Jb7eLySM/G//6AFWFULdH +GImkAk/9BfT7iCINYHsOW0MO237UKw90qShxtFCB/fqPRC6eldC2kFkod9eIw9x7cMuH74QGVsCd +XAv+HUUtd6ov8Vn0xwaDiDxneXgKEBMwdVl97B+s9egUuif2TuMSYF09Qx7KREyayC0CAwEAAaNT +MFEwHQYDVR0OBBYEFHh0ON9CYmfpcEQYlxixtd6kkmHVMB8GA1UdIwQYMBaAFHh0ON9CYmfpcEQY +lxixtd6kkmHVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABSLwFVGf8L9+alT +RU3n3D+vyUOvb5zb3hMER3WN0p323nQyeZ7WVSfIy3vsD2PcdsDinYpM9NV9P5zU+11PgAMRwqGv +UnQLbklJ3d/5ciwdCVPUk+/c8pVwOnrCa5D6m1C8Or4Pnoxihz7sdmGoaGXdlrDhcwzosKx/AcT1 +aJNor+3SzkXJLzNfrYypBeUS8XzlzH3lTY+J1aYrfzXNK06XPCMlckKVL4nFVe0yDrSUk9DiLojy +b90TaOSCqAGzoecoV8MOCxef6EvFgHmPpq8oMycWal4Ud2zdugUOtnNWxUVvWS15L7O7VG1eley/z +UrWMUi2pWJ1Gk1NAFs8/0A= + + + + + + + Tech Institute + Tech Institute + https://www.tech-institute.ac.uk + + + Jamie + Taylor + mailto:jtaylor@tech-institute.ac.uk + + + + + + + + + + + Research Center Data Portal + Scientific data access portal + + + + + + MIIDKzCCAhOgAwIBAgIUNKP1WT7mAMRllZ3z8EDR2to1VNYwDQYJKoZIhvcNAQELBQAwJTEjMCEG +A1UEAwwaaWRwLmV4YW1wbGUtdW5pdmVyc2l0eS5lZHUwHhcNMjYwNjAzMDg1NDI3WhcNMzYwNTMx +MDg1NDI3WjAlMSMwIQYDVQQDDBppZHAuZXhhbXBsZS11bml2ZXJzaXR5LmVkdTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAK+dgrVLuW+JCM2ST/SfA1J8XX3aCgtuU18Z1Xb8PcmMjQCJ +Ow0PDIApqp/JJAyt7KDiv8cgJgAmPMGbVQpcmMcOInBu+AvTsndagVqV7V3ePLwN/WOm+NPVoB2g +EEYGhF32gwZSQ0SHtJphxy4KoJv8CspVWRTviFU/pi1t8HsWJBLW6U6Jb7eLySM/G//6AFWFULdH +GImkAk/9BfT7iCINYHsOW0MO237UKw90qShxtFCB/fqPRC6eldC2kFkod9eIw9x7cMuH74QGVsCd +XAv+HUUtd6ov8Vn0xwaDiDxneXgKEBMwdVl97B+s9egUuif2TuMSYF09Qx7KREyayC0CAwEAAaNT +MFEwHQYDVR0OBBYEFHh0ON9CYmfpcEQYlxixtd6kkmHVMB8GA1UdIwQYMBaAFHh0ON9CYmfpcEQY +lxixtd6kkmHVMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABSLwFVGf8L9+alT +RU3n3D+vyUOvb5zb3hMER3WN0p323nQyeZ7WVSfIy3vsD2PcdsDinYpM9NV9P5zU+11PgAMRwqGv +UnQLbklJ3d/5ciwdCVPUk+/c8pVwOnrCa5D6m1C8Or4Pnoxihz7sdmGoaGXdlrDhcwzosKx/AcT1 +aJNor+3SzkXJLzNfrYypBeUS8XzlzH3lTY+J1aYrfzXNK06XPCMlckKVL4nFVe0yDrSUk9DiLojy +b90TaOSCqAGzoecoV8MOCxef6EvFgHmPpq8oMycWal4Ud2zdugUOtnNWxUVvWS15L7O7VG1eley/z +UrWMUi2pWJ1Gk1NAFs8/0A= + + + + + + + Research Center + Research Center + https://www.research-center.de + + + Maria + Weber + mailto:mweber@research-center.de + + + + + + + + + + + + + State University + Identity provider of State University + https://www.state-university.edu + + + + + + MIIDJzCCAg+gAwIBAgIULPAnn8haVhQcUbxjrZLjtbFX5RkwDQYJKoZIhvcNAQELBQAwIzEhMB8G +A1UEAwwYaWRwLnN0YXRlLXVuaXZlcnNpdHkuZWR1MB4XDTI2MDYwMzA4NTQ0OVoXDTM2MDUzMTA4 +NTQ0OVowIzEhMB8GA1UEAwwYaWRwLnN0YXRlLXVuaXZlcnNpdHkuZWR1MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAwo21vefLRM/2iK6LO4Sbl++0h+zrLuSSusY/0Wu3QjPAGklaqzQ0j +Dc2jbY5bXei4ebWuGxT5PCqPOFIaTQM8uJ5q7uVAo06ab6/uSfwjDJTNE7jokhMeilNh4GuoWTsb +CyGMDUbSdfTNTDCC/ELoWlTCErce+TuIZulG8Jzmmm3AKTmMjOW+Ch3HMLoKCmEyniKs7m0eB7Az +298bFCFKp0dpqkfre5U5WTYeFe39RBbZfDPl0bN0UxF1T7ITOf6tkryXPJXfQAnXDiCnB22A936M +5ou1XFTozkE8RBbgOjq34zBbM0V69rPnhh0yqFDIVUVtULcgyJQEIB5qpigDQIDAQABo1MwUTAdBg +NVHQ4EFgQUQ4UIhO5Q3RmegmL27mKP0j5QJQ4wHwYDVR0jBBgwFoAUQ4UIhO5Q3RmegmL27mKP0j +5QJQ4wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEALUR5WnK0mbu2lPO6CXd7LTs +IcRdEq/qXRQC+KqofuS5dyZ0N2ip0zD50tG6y8YjWQHERQ89+ZEKv5VmD9+k4PnZpNfVjfmyeivq +bWohIn/0iNAUNmY/bam0qbz8SCiLPLVrKvu9BAGWcoV7UX9zf+qe+NNT8z1bFVR3+WcnnO/AEWyu +UVab0ud6HYp5xc36Jj3e98T50h5OaXpQpwfyuM7/p4WX3Ri5FRa0tNxlAy685cuL6B5zrbUOoc+Q +sc3FqNtGFM/TExrW9VY/kRQVDpuhqv/eUO7RfQJmv1FBhP+XMdXUudJ6aNFswI0P1UO/H9YGm93U +CXnNW8NGo/MwFSg== + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + + + + + State University + State University + https://www.state-university.edu + + + Alex + Smith + mailto:asmith@state-university.edu + + + + + + + + + + + Tech Institute + Identity provider of Tech Institute + https://www.tech-institute.ac.uk + + + + + + MIIDJzCCAg+gAwIBAgIUFozhkEI22FNzfgPfPg6tXhOCsLMwDQYJKoZIhvcNAQELBQAwIzEhMB8G +A1UEAwwYaWRwLnRlY2gtaW5zdGl0dXRlLmFjLnVrMB4XDTI2MDYwMzA4NTQ0OVoXDTM2MDUzMTA4 +NTQ0OVowIzEhMB8GA1UEAwwYaWRwLnRlY2gtaW5zdGl0dXRlLmFjLnVrMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAodVdylnMKJ5d3p7vZqX4za/12IJVI7/Xsyi7S1UxfB52vktX9EZo +IxqO9GLMe9lIrHFOB8jU1I7BdYp8r0E4mo44YYikncOMKNaOuHF5J1WaJOUZd807jriGO9agZor9 +AmABRpl3w/WYVL9OZPj1mHngQPWaVcosM3OkxXwdULPdcxfe3VATHcNWi7uoLZsB0hpBwua47ldS +wThmZkVNjdjlD0BRiUCSynFtSY2vGxHz+D/aBvYhrGlBX4uTPCOxqybyC3dfadD9ZlvLfY0d1Yic +ZvNEybP8bPcu8xUwnsyL6bBsdat7/XXbawOsxEXxSR9wcv42ZfgKmKyTyUdpLQIDAQABo1MwUTAd +BgNVHQ4EFgQUDVmR5rn9fYj2XkwffcZAwCWKvfowHwYDVR0jBBgwFoAUDVmR5rn9fYj2XkwffcZA +wCWKvfowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAnVbAE4SsEYhodobnZEWGu +z/747XH/m7DM9KM4lvKq6QOd/C/aJ7Lp9nwfl1gXIHdwdYozlOpak2+zfVFFbepvDOldldpScJzZ +sC+80PTta+h91OTug6Q+viRJV/OzQPozLJ6jz5Tox8dYn7T2XIfmM49jX+tAR861QopVaHLmZ3Lg +EHzsk+aIV6I6yyJfBmpy4+tO5OhKv3UHLCHmo7NPVhiX+pxe3+XCghdRtKMFCB9gwqJxYoybHb+a +NrbgZmhp6hjzd9tsFQDMSdkCSTHWCaqua5Hi4EfMIR75SKxUZvrCkTe4FOa+rG5bq26vdeKBZUCs +sd+OCMN3dWtH446Lf7Gw== + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + Tech Institute + Tech Institute + https://www.tech-institute.ac.uk + + + Jamie + Taylor + mailto:jtaylor@tech-institute.ac.uk + + + + + + + + + + + Research Center + Identity provider of Research Center + https://www.research-center.de + + + + + + MIIDIzCCAgugAwIBAgIUcxlF9USQY3nQvvO8uqXJL7C8/XgwDQYJKoZIhvcNAQELBQAwITEfMB0G +A1UEAwwWaWRwLnJlc2VhcmNoLWNlbnRlci5kZTAeFw0yNjA2MDMwODU0NDlaFw0zNjA1MzEwODU0 +NDlaMCExHzAdBgNVBAMMFmlkcC5yZXNlYXJjaC1jZW50ZXIuZGUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDPxGQuYQjgdNedu3dgelQQ5t+1SxM4an4xQav4rXqG2ZtmEmDS3WDfy7Kc +RKtSfW/6+zWmNUd6wQQnc+3VgnmOb+qRTSh9XCD3WFSrr/hG0HfrmzKtjo4nYK5gWLdXQwgwznu +R40IOxsKEEtkp2UgkFLMAtGjJ15Kyu6J3eV8MIpB468G+mXXXhbLw7y8uB+cyCTWGsG1aa1ahmZS +Rz7K9H1TafUSuarUis/+oXZO9+YJHNEi9iU4U6h9iTlqPkly146FefQlHsBys7T0Es46aIqiaCMC +ygCDxhKK4Rwf0E67I9QMFbTW1y8LF5hKs42NBzcf46iAkwYgPzisbqZtLAgMBAAGjUzBRMB0GA1Ud +DgQWBBSfqZUJOP+vllNKi2xk3Lbo8St4sDAfBgNVHSMEGDAWgBSfqZUJOP+vllNKi2xk3Lbo8St4 +sDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBAJPRIMKcogeICnsF2pfca25Gln +5w13G95as+du3wx5ZVqQLH+JYLKcM6Uq7FVvWIrBwbOjCa9FEyUs1lATOtTkCZ3q05X/sw+sGMXI +r8H/vkDhOPkwIlKRaSRJHCBGN3xk8lUxev6fwwlU3Ht0fQEiOAWlc9N231wDYFDIAXmJbN/tG3/l +OfJUT1MXHdWe7QuJzmwLQ9OXogfdV2SskSQSqH9MKYcQ+qADc1lf0J0Or0GKSLvjz8YPLkwhXLGr +NhM+VyjD50hrg0DkUtco/8RTnkC3FkAvI/6WjpSiejpjW8Muh3rRAzxnfA9FQV0S0YXmlb/isM/l +Z6NiIkQ/8eB + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + Research Center + Research Center + https://www.research-center.de + + + Maria + Weber + mailto:mweber@research-center.de + + + + + + + + + + + National Laboratory + Laboratoire National + Identity provider of National Laboratory + https://www.national-lab.fr + + + + + + MIIDHTCCAgWgAwIBAgIUUl2dXqMr4hJ6wf4fj/GOQlZAcpEwDQYJKoZIhvcNAQELBQAwHjEcMBoG +A1UEAwwTaWRwLm5hdGlvbmFsLWxhYi5mcjAeFw0yNjA2MDMwODU0NDlaFw0zNjA1MzEwODU0NDla +MB4xHDAaBgNVBAMME2lkcC5uYXRpb25hbC1sYWIuZnIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQDAlY882lrAlhuadc5xMT6U8ELf5zH7adGzGjtP76Kx9SLYewDASPXY7nXUx3aM2kqs +o+MWX0iaVpnWYvV+LMFyH6Mg/12pZhRx8S/cQysYEV3loWVSi3lESkOK9ELR2BeWOrYyZtk3Pz3q +AJ/BoSFegxe7OxC866m20LMKG9sDBB88i9svxmxXYxSR/HkAEfarSruk37aLOD++Iud+FBfJvRJR +174MZj6gecIsGcXy2Zn41WLgjGl3/sWUK27SWoa9Up5vDTIeQ8lZ5ySbRT58M+eHCOxSVf/gFf7s +49+v5i/9iDKDMo5Hy+MDbdovUaDo6KQmiPg6cfzqT52AT39lAgMBAAGjUzBRMB0GA1UdDgQWBBTj +Gvmk9xkzVe57Cte2KOEnf3k2hzAfBgNVHSMEGDAWgBTjGvmk9xkzVe57Cte2KOEnf3k2hzAPBgNV +HRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAMvHuuB2KGKl0n7d0MtJ2/fzKtJmJMMja2 +o1Mqj/rg2Nkq31wrFdXqayxypYDSXQgLoABkWYyZkWIhoWOnml2J9bUDJ8uYLulp4VbNZnAylAS5 +9hu/35ZEc9hmUrm9Q8JaevKdULneiIiR2R269oqf0QEJgF26ZzEEodH0oj7ZNOOuF2OXy+8R893Y +DSnLHCEtW6uZWjEQTsfbGVcppvYYho6/K0/saO0IPb1/LZ8z1uB7CWbsn5KRnqR0AvT2+R5xlIxE +k7uWFpPOkdfgfnJ9UbfN2tgDyiieyME3PZZ5sjGWs/StRfnt/z9FeB00T3chiF4ldtuIysmUFDLu +3fm5 + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + urn:oasis:names:tc:SAML:2.0:nameid-format:persistent + + + + + National Laboratory + National Laboratory + https://www.national-lab.fr + + + Sophie + Martin + mailto:smartin@national-lab.fr + + + + + + + + + + + Polytechnic University + Universidade Politécnica + Identity provider of Polytechnic University + https://www.polytechnic.edu.br + + + + + + MIIDIzCCAgugAwIBAgIUcX6lAS/Bq/lth/N/EA1dj6b7aI4wDQYJKoZIhvcNAQELBQAwITEfMB0G +A1UEAwwWaWRwLnBvbHl0ZWNobmljLmVkdS5icjAeFw0yNjA2MDMwODU0NDlaFw0zNjA1MzEwODU0 +NDlaMCExHzAdBgNVBAMMFmlkcC5wb2x5dGVjaG5pYy5lZHUuYnIwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDgmBYTodZcgpqaimV8nFH/YH6I6Y2euIgEIIPTHVboHUXAgErOrSU1jzjF +2S1UX7uHiyg00GSJyQPBPn2i73nTplDSyj0TzmcDdI2uWyY8kygozuGrsjVv7T+krTswlCYD+GhF +09VK18Gk8VHX0DB/5GFFB03yORHSOi0MieJ5cIWNxDpSaj3UJyVnZdvA9jfxvJKIjVE3niNG82Gc +Y70VglYRr5Gm814eDAYxhfqJNfSZxKowCmxrcTiKRN/E/hrEzFAYxXaCsyaO5WYs49+IOt2pNkJH +t86ErHQEKjTF3sf10WsN9UzYz1zv74b6sqfT8GztSjmI7XcDN36ZooJBAgMBAAGjUzBRMB0GA1Ud +DgQWBBTF0YvxRtWXlt/f1Y3//c6aX/gxxzAfBgNVHSMEGDAWgBTF0YvxRtWXlt/f1Y3//c6aX/gx +xzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDVu6t9PvJ7ewKeJ05q7sFdNw9k +MEjDdim/m3Y6j31YGjSdBXmKnaH898hliATkgv7EnzgFkCT45NtT8aX1pETDEl9kgxL/TjhdwdHK +1q+Skou1NmJM+Zd7Zm8yvreA7Gj+YTiTL2iF4jeRTR+k04KZaQCLMgoxTQNgF/uxlitapX2+L+d +IyTikGTkfINXNRjhvx2t3rUqJoxn/bl1qM6uS4A/R5aOne6xve5Kd+lyUCOxB/TZuHpDZgB6O1FT +03HXTn4lmoCIiCPsjXhXqQOgTq+g8JPMUYtGAi4diNF+CWcD9Zv/1rdqCuGlk1O105HRIPcST5LF +4MzCa1nJBoVPj + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + + Polytechnic University + Polytechnic University + https://www.polytechnic.edu.br + + + Carlos + Silva + mailto:csilva@polytechnic.edu.br + + + + diff --git a/modules/auth_saml/spec/services/saml/metadata_document_spec.rb b/modules/auth_saml/spec/services/saml/metadata_document_spec.rb new file mode 100644 index 00000000000..3f7073a2e58 --- /dev/null +++ b/modules/auth_saml/spec/services/saml/metadata_document_spec.rb @@ -0,0 +1,141 @@ +# 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 "spec_helper" + +RSpec.describe Saml::MetadataDocument do + # Fixture: 3 SPs then 5 IdPs — see spec/fixtures/federation_metadata.xml + let(:federation_xml) { Rails.root.join("modules/auth_saml/spec/fixtures/federation_metadata.xml").read } + + # Minimal single EntityDescriptor — not an aggregate, so prepare returns it unchanged + let(:single_idp_xml) do + <<~XML + + + + + + XML + end + + # Entity IDs present in the fixture + let(:first_idp_entity_id) { "https://idp.state-university.edu/idp/shibboleth" } + let(:last_idp_entity_id) { "https://idp.polytechnic.edu.br/idp/shibboleth" } + let(:sp_entity_id) { "https://sp.state-university.edu/shibboleth" } + + describe ".prepare on a single-entity document" do + it "returns the XML unchanged" do + result = described_class.prepare(single_idp_xml) + expect(result).to eq(single_idp_xml) + end + end + + describe ".prepare on a federation aggregate" do + it "detects the aggregate" do + expect(described_class.new(federation_xml).aggregate?).to be(true) + end + + context "without an entity_id" do + it "returns the first IdP entity, skipping SP-only entries" do + result = described_class.prepare(federation_xml) + + expect(result).to include(first_idp_entity_id) + expect(result).to include("IDPSSODescriptor") + expect(result).not_to include("SPSSODescriptor") + end + end + + context "with a matching entity_id" do + it "extracts the requested IdP" do + result = described_class.prepare(federation_xml, entity_id: last_idp_entity_id) + + expect(result).to include(last_idp_entity_id) + expect(result).to include("IDPSSODescriptor") + end + + it "can also extract an SP entity by entity_id" do + result = described_class.prepare(federation_xml, entity_id: sp_entity_id) + + expect(result).to include(sp_entity_id) + expect(result).to include("SPSSODescriptor") + end + end + + context "with an entity_id not present in the aggregate" do + it "raises FederationMetadataError with the missing entity_id in the message" do + expect do + described_class.prepare(federation_xml, entity_id: "https://missing.example.com/idp/shibboleth") + end.to raise_error(described_class::FederationMetadataError, /missing\.example\.com/) + end + end + + context "when the aggregate contains no IdPs and no entity_id is given" do + let(:sp_only_aggregate) do + <<~XML + + + + + + XML + end + + it "raises FederationMetadataError" do + expect do + described_class.prepare(sp_only_aggregate) + end.to raise_error(described_class::FederationMetadataError) + end + end + end + + describe ".prepare on an IO source (Tempfile)" do + it "reads a single-entity file correctly" do + Tempfile.create("spec-metadata") do |f| + f.write(single_idp_xml) + f.rewind + expect(described_class.prepare(f)).to eq(single_idp_xml) + end + end + + it "extracts the first IdP from a federation aggregate file" do + Tempfile.create("spec-metadata") do |f| + f.write(federation_xml) + f.rewind + result = described_class.prepare(f) + expect(result).to include(first_idp_entity_id) + expect(result).to include("IDPSSODescriptor") + end + end + end +end diff --git a/modules/auth_saml/spec/services/saml/metadata_fetcher_spec.rb b/modules/auth_saml/spec/services/saml/metadata_fetcher_spec.rb new file mode 100644 index 00000000000..0a989534c01 --- /dev/null +++ b/modules/auth_saml/spec/services/saml/metadata_fetcher_spec.rb @@ -0,0 +1,97 @@ +# 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 "spec_helper" + +RSpec.describe Saml::MetadataFetcher do + let(:url) { "https://example.com/metadata" } + let(:response) { instance_double(Net::HTTPSuccess) } + + before do + allow(response).to receive(:is_a?).with(Net::HTTPSuccess).and_return(true) + allow(OpenProject::SsrfProtection).to receive(:get).and_yield(response) + end + + describe ".fetch" do + context "with a successful response" do + before do + allow(response).to receive(:read_body).and_yield("") + end + + it "yields a file with the response body rewound to the start" do + described_class.fetch(url) do |file| + expect(file).to be_a(File) + expect(file.pos).to eq(0) + expect(file.read).to eq("") + end + end + + it "removes the tempfile after the block" do + path = nil + described_class.fetch(url) do |file| + path = file.path + expect(File.exist?(path)).to be(true) + end + expect(File.exist?(path)).to be(false) + end + end + + context "when the response is not successful" do + let(:response) { instance_double(Net::HTTPNotFound, code: "404", message: "Not Found") } + + before do + allow(response).to receive(:is_a?).with(Net::HTTPSuccess).and_return(false) + allow(OpenProject::SsrfProtection).to receive(:get).and_yield(response) + end + + it "raises HttpError without yielding" do + yielded = false + expect do + described_class.fetch(url) { yielded = true } + end.to raise_error(OneLogin::RubySaml::HttpError, /404/) + expect(yielded).to be(false) + end + end + + context "when the response body exceeds MAX_SIZE" do + before do + allow(response).to receive(:read_body).and_yield("x" * (Saml::MetadataDocument::MAX_SIZE + 1)) + end + + it "raises MetadataTooLargeError without yielding" do + yielded = false + expect do + described_class.fetch(url) { yielded = true } + end.to raise_error(Saml::MetadataDocument::MetadataTooLargeError) + expect(yielded).to be(false) + end + end + end +end diff --git a/modules/auth_saml/spec/services/saml/update_metadata_service_spec.rb b/modules/auth_saml/spec/services/saml/update_metadata_service_spec.rb index 342d894b2a3..bc2c9ac1f47 100644 --- a/modules/auth_saml/spec/services/saml/update_metadata_service_spec.rb +++ b/modules/auth_saml/spec/services/saml/update_metadata_service_spec.rb @@ -231,22 +231,37 @@ RSpec.describe Saml::UpdateMetadataService do let(:metadata_url) { "https://example.com/metadata" } let(:provider) { Saml::Provider.new(metadata_url:) } let(:parser_instance) { instance_double(OneLogin::RubySaml::IdpMetadataParser) } + let(:http_response) { instance_double(Net::HTTPSuccess) } before do allow(OneLogin::RubySaml::IdpMetadataParser).to receive(:new).and_return(parser_instance) - allow(parser_instance).to receive(:parse_remote_to_hash).and_return({}) + allow(parser_instance).to receive(:parse_to_hash).and_return({}) + allow(Saml::MetadataDocument).to receive(:prepare).and_return("") + allow(http_response).to receive(:is_a?).with(Net::HTTPSuccess).and_return(true) + allow(http_response).to receive(:read_body).and_yield("") + allow(OpenProject::SsrfProtection).to receive(:get) end context "when the URL host resolves to a safe IP" do before do allow(OpenProject::SsrfProtection).to receive(:safe_ip?).with("example.com").and_return(IPAddr.new("93.184.216.34")) + allow(OpenProject::SsrfProtection).to receive(:get).and_yield(http_response) end - it "checks the host and fetches metadata remotely" do + it "checks the host, fetches metadata via MetadataFetcher, and cleans up the tempfile" do + fetched_file = nil + allow(Saml::MetadataDocument).to receive(:prepare) do |file, **| + fetched_file = file + "" + end + parse_metadata expect(OpenProject::SsrfProtection).to have_received(:safe_ip?).with("example.com") - expect(parser_instance).to have_received(:parse_remote_to_hash).with(metadata_url) + expect(OpenProject::SsrfProtection).to have_received(:get).with(metadata_url) + expect(Saml::MetadataDocument).to have_received(:prepare).with(instance_of(File), entity_id: nil) + expect(parser_instance).to have_received(:parse_to_hash).with("") + expect(fetched_file).to be_closed end end @@ -261,7 +276,7 @@ RSpec.describe Saml::UpdateMetadataService do expect(result).not_to be_success expect(result.message).to include("MetadataHostNotAllowedError") expect(OpenProject::SsrfProtection).to have_received(:safe_ip?).with("example.com") - expect(parser_instance).not_to have_received(:parse_remote_to_hash) + expect(OpenProject::SsrfProtection).not_to have_received(:get) end end end diff --git a/modules/backlogs/app/components/backlogs/backlog_component.html.erb b/modules/backlogs/app/components/backlogs/backlog_component.html.erb index ec3f447674d..1f0a790e117 100644 --- a/modules/backlogs/app/components/backlogs/backlog_component.html.erb +++ b/modules/backlogs/app/components/backlogs/backlog_component.html.erb @@ -75,11 +75,18 @@ See COPYRIGHT and LICENSE files for more details. end %> - <%= render Backlogs::BucketComponent.with_collection(buckets, project:) %> - + <% buckets.each do |bucket| %> + <%= + render Backlogs::BucketComponent.new( + project:, + backlog_bucket: bucket, + work_packages: work_packages_for(bucket) + ) + %> + <% end %> <%= render Backlogs::InboxComponent.new( - work_packages: inbox_work_packages, + work_packages: work_packages_for_inbox, project: project ) %> diff --git a/modules/backlogs/app/components/backlogs/backlog_component.rb b/modules/backlogs/app/components/backlogs/backlog_component.rb index 4cd0a1f0ef2..cd3ec8e9b3e 100644 --- a/modules/backlogs/app/components/backlogs/backlog_component.rb +++ b/modules/backlogs/app/components/backlogs/backlog_component.rb @@ -34,15 +34,15 @@ module Backlogs include OpTurbo::Streamable include CommonHelper - attr_reader :inbox_work_packages, :buckets, :project, :current_user + attr_reader :work_packages_by_backlog_id, :buckets, :project, :current_user - def initialize(inbox_work_packages:, - buckets:, + def initialize(buckets:, + work_packages_by_backlog_id:, project:, current_user: User.current) super() - @inbox_work_packages = inbox_work_packages + @work_packages_by_backlog_id = work_packages_by_backlog_id @buckets = buckets @project = project @current_user = current_user @@ -55,7 +55,15 @@ module Backlogs private def total - @total ||= inbox_work_packages.count + (buckets&.sum { it.work_packages.size } || 0) + @total ||= work_packages_by_backlog_id.values.sum(&:count) + end + + def work_packages_for_inbox + work_packages_by_backlog_id[nil] || [] + end + + def work_packages_for(bucket) + work_packages_by_backlog_id[bucket.id] || [] end end end diff --git a/modules/backlogs/app/components/backlogs/bucket_component.rb b/modules/backlogs/app/components/backlogs/bucket_component.rb index 0db65776db9..579d5c6ce23 100644 --- a/modules/backlogs/app/components/backlogs/bucket_component.rb +++ b/modules/backlogs/app/components/backlogs/bucket_component.rb @@ -34,17 +34,16 @@ module Backlogs include OpTurbo::Streamable include CommonHelper - with_collection_parameter :backlog_bucket - attr_reader :backlog_bucket, :work_packages, :project, :current_user - def initialize(backlog_bucket:, project:, current_user: User.current) + def initialize(backlog_bucket:, project:, work_packages: nil, current_user: User.current) super() @backlog_bucket = backlog_bucket @project = project @current_user = current_user - @work_packages = backlog_bucket.displayed_work_packages + @work_packages = work_packages || backlog_bucket.displayed_work_packages + .includes(:status, :type, :assigned_to, :priority, :parent) end def wrapper_uniq_by diff --git a/modules/backlogs/app/components/backlogs/inbox_component.rb b/modules/backlogs/app/components/backlogs/inbox_component.rb index c569b24325d..67b21d93937 100644 --- a/modules/backlogs/app/components/backlogs/inbox_component.rb +++ b/modules/backlogs/app/components/backlogs/inbox_component.rb @@ -69,11 +69,7 @@ module Backlogs end def last_omitted_id - if work_packages.respond_to?(:reverse_order) - work_packages.reverse_order.offset(tail_size).limit(1).pick(:id) - else - work_packages[-(tail_size + 1)]&.id - end + work_packages[-(tail_size + 1)]&.id end private diff --git a/modules/backlogs/app/components/backlogs/sprint_component.rb b/modules/backlogs/app/components/backlogs/sprint_component.rb index e35a16bed51..c812c30dead 100644 --- a/modules/backlogs/app/components/backlogs/sprint_component.rb +++ b/modules/backlogs/app/components/backlogs/sprint_component.rb @@ -46,8 +46,8 @@ module Backlogs @project = project @current_user = current_user @active_sprint_ids = active_sprint_ids - @work_packages = work_packages || sprint.work_packages_for(project).includes(:status, :type, :assigned_to, :priority, - :parent) + @work_packages = work_packages || sprint.work_packages_for(project) + .includes(:status, :type, :assigned_to, :priority, :parent) end def wrapper_uniq_by diff --git a/modules/backlogs/app/components/backlogs/sprints_component.html.erb b/modules/backlogs/app/components/backlogs/sprints_component.html.erb index eb5bceca1ae..cf570b2dae7 100644 --- a/modules/backlogs/app/components/backlogs/sprints_component.html.erb +++ b/modules/backlogs/app/components/backlogs/sprints_component.html.erb @@ -63,7 +63,7 @@ See COPYRIGHT and LICENSE files for more details. <%= render Backlogs::SprintComponent.new( sprint:, project:, - work_packages: work_packages_by_sprint_id[sprint.id], + work_packages: work_packages_by_sprint_id[sprint.id] || [], active_sprint_ids: active_sprint_ids ) %> <% end %> diff --git a/modules/backlogs/app/controllers/backlogs/backlog_controller.rb b/modules/backlogs/app/controllers/backlogs/backlog_controller.rb index 035cffd2694..79c7223c426 100644 --- a/modules/backlogs/app/controllers/backlogs/backlog_controller.rb +++ b/modules/backlogs/app/controllers/backlogs/backlog_controller.rb @@ -31,6 +31,7 @@ module Backlogs class BacklogController < BaseController include ::WorkPackages::WithSplitView + include Backlogs::Concerns::ContainerLoading current_menu_item %i[show details] do :backlog @@ -39,7 +40,7 @@ module Backlogs def show case turbo_frame_request_id when "backlogs_container" - load_backlogs + load_container_data render partial: "backlogs/backlog/backlog_list", layout: false else @@ -51,7 +52,7 @@ module Backlogs if turbo_frame_request? render "work_packages/split_view", layout: false else - load_backlogs + load_container_data render "backlogs/backlog/show" end @@ -62,22 +63,5 @@ module Backlogs def split_view_base_route project_backlogs_backlog_path(@project, request.query_parameters) end - - def load_backlogs - @backlog_buckets = BacklogBucket.for_project(@project) - - @sprints = Sprint.for_project(@project) - .not_completed - .order_by_date - .includes(:project, :task_boards) - - @work_packages_by_sprint_id = WorkPackage - .where(sprint: @sprints, project: @project) - .includes(:type, :status, :assigned_to, :priority, :parent) - .order_by_position - .group_by(&:sprint_id) - @active_sprint_ids = @sprints.select(&:active?).map(&:id) - @inbox_work_packages = WorkPackage.backlogs_inbox_for(project: @project) - end end end diff --git a/modules/backlogs/app/controllers/backlogs/concerns/container_loading.rb b/modules/backlogs/app/controllers/backlogs/concerns/container_loading.rb new file mode 100644 index 00000000000..e383a2afbc1 --- /dev/null +++ b/modules/backlogs/app/controllers/backlogs/concerns/container_loading.rb @@ -0,0 +1,67 @@ +# 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 Backlogs::Concerns + module ContainerLoading + extend ActiveSupport::Concern + + def load_container_data + load_sprint_data + load_backlog_data + end + + def load_sprint_data + @sprints = Sprint.for_project(@project) + .not_completed + .order_by_date + .includes(:project, :task_boards) + @active_sprint_ids = @sprints.select(&:active?).map(&:id) + + @work_packages_by_sprint_id = WorkPackage + .where(sprint: @sprints, project: @project) + .includes(:type, :status, :assigned_to, :priority, :parent) + .order_by_position + .group_by(&:sprint_id) + end + + def load_backlog_data + @backlog_buckets = BacklogBucket.for_project(@project) + + # Includes the work packages of both the buckets and the inbox. + # This has the drawback of loading more work packages than are displayed in the inbox as pagination + # will only show the top 50 and lowest 10 work packages. + # But doing only a single query (+ includes) to the database has its benefits, and currently this seems quicker. + @work_packages_by_backlog_id = WorkPackage + .in_backlog_for(project: @project) + .includes(:type, :status, :assigned_to, :priority, :parent) + .group_by(&:backlog_bucket_id) + end + end +end diff --git a/modules/backlogs/app/controllers/backlogs/work_packages_controller.rb b/modules/backlogs/app/controllers/backlogs/work_packages_controller.rb index 83d66628fb4..83730c937b8 100644 --- a/modules/backlogs/app/controllers/backlogs/work_packages_controller.rb +++ b/modules/backlogs/app/controllers/backlogs/work_packages_controller.rb @@ -31,6 +31,7 @@ module Backlogs class WorkPackagesController < BaseController include OpTurbo::ComponentStream + include Backlogs::Concerns::ContainerLoading before_action :load_work_package @@ -112,10 +113,11 @@ module Backlogs end def backlog_component - inbox_work_packages = WorkPackage.backlogs_inbox_for(project: @project) - buckets = BacklogBucket.for_project(@project) + load_backlog_data - Backlogs::BacklogComponent.new(inbox_work_packages:, buckets:, project: @project) + Backlogs::BacklogComponent.new(buckets: @backlog_buckets, + work_packages_by_backlog_id: @work_packages_by_backlog_id, + project: @project) end def load_work_package @@ -133,7 +135,7 @@ module Backlogs elsif @work_package.backlog_bucket_id? @work_packages.merge(@work_package.backlog_bucket.displayed_work_packages) else - @work_packages.merge(WorkPackage.backlogs_inbox_for(project: @project)) + @work_packages.merge(WorkPackage.in_inbox_for(project: @project)) end end diff --git a/modules/backlogs/app/models/backlog_bucket.rb b/modules/backlogs/app/models/backlog_bucket.rb index dd7985067f5..40548040fe8 100644 --- a/modules/backlogs/app/models/backlog_bucket.rb +++ b/modules/backlogs/app/models/backlog_bucket.rb @@ -52,6 +52,6 @@ class BacklogBucket < ApplicationRecord validates :name, :project, presence: true def self.for_project(project) - where(project:).order_alphabetically.includes(displayed_work_packages: %i[assigned_to priority parent]) + where(project:).order_alphabetically end end diff --git a/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb b/modules/backlogs/app/models/work_packages/scopes/in_backlog_for.rb similarity index 85% rename from modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb rename to modules/backlogs/app/models/work_packages/scopes/in_backlog_for.rb index e1d0d077207..aeea30d0658 100644 --- a/modules/backlogs/app/models/work_packages/scopes/backlogs_inbox_for.rb +++ b/modules/backlogs/app/models/work_packages/scopes/in_backlog_for.rb @@ -28,19 +28,18 @@ # See COPYRIGHT and LICENSE files for more details. # ++ -module WorkPackages::Scopes::BacklogsInboxFor +module WorkPackages::Scopes::InBacklogFor extend ActiveSupport::Concern class_methods do - def backlogs_inbox_for(project:) + def in_backlog_for(project:) WorkPackage .visible - .where(project:, sprint_id: nil, backlog_bucket_id: nil) + .where(project:, sprint_id: nil) .without_excluded_type .without_status_considered_closed - .includes(:assigned_to, :priority, :parent) .order_by_position - .order(WorkPackage.arel_table[:id].asc) + .order(id: :asc) end end end diff --git a/modules/backlogs/app/models/work_packages/scopes/in_inbox_for.rb b/modules/backlogs/app/models/work_packages/scopes/in_inbox_for.rb new file mode 100644 index 00000000000..16a13cce5d5 --- /dev/null +++ b/modules/backlogs/app/models/work_packages/scopes/in_inbox_for.rb @@ -0,0 +1,40 @@ +# 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 WorkPackages::Scopes::InInboxFor + extend ActiveSupport::Concern + + class_methods do + def in_inbox_for(project:) + in_backlog_for(project:) + .where(backlog_bucket: nil) + end + end +end diff --git a/modules/backlogs/app/models/work_packages/scopes/without_excluded_type.rb b/modules/backlogs/app/models/work_packages/scopes/without_excluded_type.rb index 074b2cbb72e..65648bce4e6 100644 --- a/modules/backlogs/app/models/work_packages/scopes/without_excluded_type.rb +++ b/modules/backlogs/app/models/work_packages/scopes/without_excluded_type.rb @@ -34,15 +34,15 @@ module WorkPackages::Scopes::WithoutExcludedType class_methods do def without_excluded_type type_subquery = <<~SQL.squish - work_packages.type_id NOT IN ( - SELECT type_id + NOT EXISTS ( + SELECT 1 FROM backlog_excluded_types WHERE project_id = work_packages.project_id + AND type_id = work_packages.type_id ) SQL where(type_subquery) - .includes(:type) end end end diff --git a/modules/backlogs/app/models/work_packages/scopes/without_status_considered_closed.rb b/modules/backlogs/app/models/work_packages/scopes/without_status_considered_closed.rb index 03f77532fb2..00a19678b44 100644 --- a/modules/backlogs/app/models/work_packages/scopes/without_status_considered_closed.rb +++ b/modules/backlogs/app/models/work_packages/scopes/without_status_considered_closed.rb @@ -39,21 +39,21 @@ module WorkPackages::Scopes::WithoutStatusConsideredClosed # Additionally, all globally closed statuses are always treated as done, # safeguarding against empty/corrupt project configuration (per AC). status_subquery = <<~SQL.squish - work_packages.status_id NOT IN ( - SELECT status_id + NOT EXISTS ( + SELECT 1 FROM done_statuses_for_project WHERE project_id = work_packages.project_id - AND status_id IS NOT NULL + AND status_id = work_packages.status_id ) - AND work_packages.status_id NOT IN ( - SELECT id + AND NOT EXISTS ( + SELECT 1 FROM statuses - WHERE is_closed = TRUE + WHERE id = work_packages.status_id + AND is_closed = TRUE ) SQL where(status_subquery) - .includes(:status) end end end diff --git a/modules/backlogs/app/views/backlogs/backlog/_backlog_list.html.erb b/modules/backlogs/app/views/backlogs/backlog/_backlog_list.html.erb index fb11550a79e..a7e9444f36b 100644 --- a/modules/backlogs/app/views/backlogs/backlog/_backlog_list.html.erb +++ b/modules/backlogs/app/views/backlogs/backlog/_backlog_list.html.erb @@ -35,8 +35,8 @@ See COPYRIGHT and LICENSE files for more details. data-generic-drag-and-drop-target="scrollContainer"> <%= render Backlogs::BacklogComponent.new( - inbox_work_packages: @inbox_work_packages, buckets: @backlog_buckets, + work_packages_by_backlog_id: @work_packages_by_backlog_id, project: @project ) %> diff --git a/modules/backlogs/config/locales/crowdin/cs.yml b/modules/backlogs/config/locales/crowdin/cs.yml index 2e366c410c1..b74b2d748de 100644 --- a/modules/backlogs/config/locales/crowdin/cs.yml +++ b/modules/backlogs/config/locales/crowdin/cs.yml @@ -87,7 +87,7 @@ cs: sprint: Sprint backlogs: administration_blankslate: - title: Backlog admin settings are evolving + title: Nastavení backlogu se vyvíjí text: V současné době přepracováváme modul Backlogů. V blízké budoucnosti zde budou viditelná administrátorská nastavení pro sprinty a backlogy. Nastavení na úrovni projektů zůstávají k dispozici. bucket_destroy_modal_component: title: Smazat sekci backlogu? @@ -101,9 +101,9 @@ cs: delete_backlog_bucket: Smazat sekci backlogu burndown_chart: show: - blankslate_title: No burndown data available - blankslate_description: Set start and end date for the sprint to generate a burndown chart. - excluded_work_package_types_caption: 'Choose which work package types to hide from the backlog. Items of the selected types will not appear in the backlog automatically, keeping it focused on the work that matters to your team. For example, types like Epics or Milestones that are managed at a higher level can be hidden to keep the backlog focused on actionable items. + blankslate_title: Nedostupná data pro Burndown + blankslate_description: Nastavte datum začátku a konce sprintu pro vygenerování Burndown grafu. + excluded_work_package_types_caption: 'Zvolte, které typy pracovních balíčků se mají skrýt z backlogu. Položky vybraných typů se v backlogu automaticky nezobrazí, takže zůstane soustředěn na práci, která je pro váš tým důležitá. Například typy jako Epicy nebo Milníky, které jsou řízeny na vyšší úrovni, lze skrýt, aby se backlog soustředil na položky, které lze realizovat. ' finish_sprint_dialog_component: @@ -117,19 +117,19 @@ cs: select_sprint_label: Vyberte sprint button_complete_sprint: Dokončit sprint inbox_component: - title: Inbox - blankslate_title: Backlog inbox is empty + title: Příchozí + blankslate_title: Žádné příchozí položky blankslate_description: Zde se automaticky zobrazí všechny otevřené pracovní balíčky tohoto projektu. show_more: - one: Show 1 more item - few: Show %{count} more items - many: Show %{count} more items - other: Show %{count} more items - label_burndown_chart: Burndown chart + one: Zobrazit ještě 1 položku + few: Zobrazit ještě %{count} položek + many: Zobrazit ještě %{count} položek + other: Zobrazit ještě %{count} položek + label_burndown_chart: Graf Burndown label_is_done_status: Stav %{status_name} znamená hotovo label_sprint_board: Sprint board move_to_bucket_dialog_component: - title: Move to backlog bucket + title: Přesunout do sekce backlogu move_to_sprint_dialog_component: title: Přesunout do sprintu label_sprint: Sprint @@ -144,73 +144,73 @@ cs: rebuild_positions: Znovu sestavit pozice remaining_hours: Zbývající práce sharing: Sdílení - show_burndown_chart: Burndown chart + show_burndown_chart: Graf Burndown sprint_component: blankslate_title: "%{name} je prázdný" blankslate_description: Zatím nejsou naplánovány žádné položky. Přetažením položek sem je přidáte. - label_actions: Sprint actions - label_start_sprint: Start sprint - label_complete_sprint: Complete sprint - start_sprint_disabled_reason_active_sprint: Another sprint is already active. - start_sprint_disabled_reason_missing_dates: Start and finish dates are required in order to start the sprint. + label_actions: Operace sprintu + label_start_sprint: Zahájit sprint + label_complete_sprint: Dokončit sprint + start_sprint_disabled_reason_active_sprint: Jiný sprint je již aktivní. + start_sprint_disabled_reason_missing_dates: Pro zahájení sprintu je nutné datum zahájení a ukončení. action_menu: - edit_sprint: Edit sprint - add_work_package: Add work package + edit_sprint: Upravit sprint + add_work_package: Přidat pracovní balíček sprints_component: blankslate: - title: No sprints present yet - settings_link_text: project settings - receive_and_manage_description_html: This project receives sprints from a different project. Manage this in the %{settings_link}. - receive_description_text: This project receives shared sprints from a different project, but none are available right now. - create_and_manage_description_html: To start planning your sprint, create one here or go to the %{settings_link} to receive sprints from a different project. - create_description_text: To start planning your sprint, create one here. - manage_description_html: To start planning your sprint, go to the %{settings_link} to receive sprints from a different project. - no_actions_description_text: No sprints are available for this project yet. + title: Zatím nejsou přítomny žádné sprinty + settings_link_text: nastavení projektu + receive_and_manage_description_html: Tento projekt přijímá sprinty z jiného projektu. Spravujte je v %{settings_link}. + receive_description_text: Tento projekt přijímá sdílené sprinty z jiného projektu, ale žádný není momentálně k dispozici. + create_and_manage_description_html: Chcete-li začít plánovat svůj sprint, vytvořte si jeden zde, nebo přejděte na %{settings_link}, abyste mohli dostávat sprinty z jiného projektu. + create_description_text: Chcete-li začít plánovat sprint, vytvořte si ho zde. + manage_description_html: Chcete-li začít plánovat sprint, přejděte na stránku %{settings_link} a získejte sprinty z jiného projektu. + no_actions_description_text: Pro tento projekt zatím nejsou k dispozici žádné sprinty. story_points: one: "%{count} story point" - few: "%{count} story points" - many: "%{count} story points" - other: "%{count} story points" - statuses_considered_closed_caption: 'Choose the statuses that represent a closed or finished state in your workflow. These will be treated as the "Closed" state across reporting (e.g. burndown) and sprint planning. For example, statuses like Done, Resolved, or Won''t Fix may all represent a closed work item in your process. + few: "%{count} story pointy" + many: "%{count} story pointy" + other: "%{count} story pointy" + statuses_considered_closed_caption: 'Vyberte stavy, které představují uzavřený nebo dokončený stav vašeho pracovního postupu. Tyto stavy budou považovány za stav "Uzavřeno" v rámci reportingu (např. Burndown) a plánování sprintu. Například stavy jako "Hotovo", "Vyřešeno" nebo "Nebude opraveno" mohou ve vašem procesu představovat uzavřenou pracovní položku. ' - types_and_statuses: Types and statuses + types_and_statuses: Typy a stavy unassigned: Nepřiřazeno user_preference: header_backlogs: Modul backlogů button_update_backlogs: Upravit backlog modul stories: update_service: - missing_target: target_id or direction must be present. - ambiguous_target: target_id and direction cannot both be present. - invalid_target_type: 'target_type must be one of: backlog_bucket:, sprint:, inbox.' - invalid_direction: 'direction must be one of: higher, highest, lower, lowest.' + missing_target: musí být přítomno target_id nebo direction. + ambiguous_target: target_id a direction nemohou být přítomny zároveň. + invalid_target_type: 'target_type musí být jeden z následujících: backlog_bucket:, sprint:, inbox.' + invalid_direction: 'směr musí být jeden z následujících: vyšší, nejvyšší, nižší, nejnižší.' work_package_card_menu_component: action_menu: - copy_url_to_clipboard: Copy URL to clipboard - copy_work_package_id: Copy work package ID - move_menu: Move - move_to_backlog_bucket: Move to backlog bucket - move_to_inbox: Move to inbox - move_to_sprint: Move to sprint + copy_url_to_clipboard: Kopírovst adresu URL + copy_work_package_id: Kopírovat ID pracovního balíčku + move_menu: Přesunout + move_to_backlog_bucket: Přesunout do sekce backlogu + move_to_inbox: Přesunout do Příchozích + move_to_sprint: Přesunout do sprintu work_package_is_closed: Pracovní balíček je hotov, když burndown: - story_points: Story points - story_points_ideal: Story points (ideal) + story_points: Story pointy + story_points_ideal: Story pointy (ideální) ee: features: - sprint_sharing: Sprint sharing + sprint_sharing: Sdílení sprintu upsell: sprint_sharing: - description: Share sprints across projects to align teams and coordinate work in scaled agile setups (SAFe). - label_all_sprints: All sprints + description: Sdílení sprintů napříč projekty za účelem sladění týmů a koordinace práce v rámci škálovaných agilních prostředí (SAFe). + label_all_sprints: Všechny sprinty label_backlog: Backlog label_backlogs: Backlogy label_backlog_and_sprints: Backlogy a sprinty - label_backlog_bucket_edit: Edit backlog bucket - label_backlog_bucket_new: New backlog bucket - label_burndown_chart: Burndown chart - label_inbox: Inbox + label_backlog_bucket_edit: Upravit sekci backlogu + label_backlog_bucket_new: Nová sekce backlogu + label_burndown_chart: Graf Burndown + label_inbox: Příchozí label_sprint_board: Sprint board label_points_burn_down: Dolů label_points_burn_up: Nahoru @@ -223,12 +223,12 @@ cs: notice_unsuccessful_start_with_reason: 'Sprint nebylo možné zahájit: %{reason}' notice_unsuccessful_finish: Sprint nebylo možné dokončit. notice_unsuccessful_finish_with_reason: 'Sprint nebylo možné dokončit: %{reason}' - notice_work_package_invisible_after_move: 'The work package was moved to %{backlog} but is not visible because its type or status is excluded from the backlog. + notice_work_package_invisible_after_move: 'Pracovní balíček byl přesunut do %{backlog}, ale není viditelný, protože jeho typ nebo stav je vyloučen z backlogu. ' permission_create_sprints: Vytváření sprintů permission_manage_sprint_items: Správa položek sprintu - permission_select_backlog_types_and_statuses: Select backlog types and statuses + permission_select_backlog_types_and_statuses: Vyberte typy a stavy backlogu permission_select_backlog_types_and_statuses_explanation: 'Allows choosing which work package types to hide from the backlog. Also allows defining which statuses represent a closed or finished state in the project''s workflow. ' @@ -250,7 +250,7 @@ cs: share_all_projects: label: Všechny projekty caption: Sprinty vytvořené v tomto projektu budou dostupné pro všechny projekty v této instanci. Pokud tuto možnost vyberete, nebudou již dostupná pro ostatní projekty. - disabled_caption: Option not available since project "%{name}" is currently sharing with all projects and only one project can do this. + disabled_caption: Tato možnost není k dispozici, protože projekt ''%{name}" momentálně sdílí se všemi projekty, což může dělat pouze jeden projekt. disabled_caption_anonymous: Tato možnost není k dispozici, protože jiný projekt je v současné době sdílen se všemi projekty a tuto možnost může použít pouze jeden projekt. share_subprojects: label: Podprojekty @@ -260,5 +260,5 @@ cs: backlogs: sharing_form_component: sharing_description: Tento projekt může buď sdílet vlastní sprinty, přijímat sdílené sprinty, nebo sprinty zpracovávat samostatně (bez sdílení). - sharing_fallback_description: Lacking a corporate enterprise plan, the sharing options are limited to the project's own sprints. The currently active setting remains active. + sharing_fallback_description: Vzhledem k tomu, že chybí podnikový plán, jsou možnosti sdílení omezeny na vlastní sprinty projektu. Aktuálně aktivní nastavení zůstává aktivní. remaining_hours: Zbývající práce diff --git a/modules/backlogs/config/locales/crowdin/de.yml b/modules/backlogs/config/locales/crowdin/de.yml index 4ed2dfdd579..81341f860ef 100644 --- a/modules/backlogs/config/locales/crowdin/de.yml +++ b/modules/backlogs/config/locales/crowdin/de.yml @@ -28,8 +28,8 @@ de: attributes: project: sprint_sharing: Sprints teilen - backlog_excluded_types: Excluded work package types - statuses_considered_closed: Statuses considered closed + backlog_excluded_types: Ausgeschlossene Arbeitspaket-Typen + statuses_considered_closed: Als abgeschlossen geltende Status sprint: duration: Dauer finish_date: Endtermin @@ -40,7 +40,7 @@ de: in_planning: In Planung active: Aktiv completed: Abgeschlossen - work_packages: Work packages + work_packages: Arbeitspakete work_package: backlog_bucket: Backlog Bucket backlogs_work_package_type: Backlog Typ @@ -101,7 +101,7 @@ de: show: blankslate_title: Keine Burndown-Daten verfügbar blankslate_description: Legen Sie Start- und Enddatum für den Sprint fest, um ein Burndown-Diagramm zu erstellen. - excluded_work_package_types_caption: 'Choose which work package types to hide from the backlog. Items of the selected types will not appear in the backlog automatically, keeping it focused on the work that matters to your team. For example, types like Epics or Milestones that are managed at a higher level can be hidden to keep the backlog focused on actionable items. + excluded_work_package_types_caption: 'Wählen Sie, welche Arbeitspaket-Typen Sie aus dem Backlog ausblenden möchten. Elemente der ausgewählten Typen erscheinen nicht automatisch im Backlog und sind so auf die Arbeit konzentriert, die für Ihr Team wichtig ist. Typen wie Epics oder Milestones, die auf einer höheren Ebene verwaltet werden, können beispielsweise ausgeblendet werden, damit sich das Backlog auf umsetzbare Aufgaben konzentriert. ' finish_sprint_dialog_component: @@ -125,7 +125,7 @@ de: label_is_done_status: Status %{status_name} bedeutet abgeschlossen label_sprint_board: Sprint-Board move_to_bucket_dialog_component: - title: Move to backlog bucket + title: In Backlog Bucket verschieben move_to_sprint_dialog_component: title: Zum Sprint verschieben label_sprint: Sprint @@ -163,27 +163,27 @@ de: story_points: one: "%{count} Story-Punkte" other: "%{count} Story-Points" - statuses_considered_closed_caption: 'Choose the statuses that represent a closed or finished state in your workflow. These will be treated as the "Closed" state across reporting (e.g. burndown) and sprint planning. For example, statuses like Done, Resolved, or Won''t Fix may all represent a closed work item in your process. + statuses_considered_closed_caption: 'Wählen Sie die Status, die einen abgeschlossenen oder beendeten Zustand in Ihrem Arbeitsablauf darstellen. Diese werden in den Berichten (z.B. Burndown) und in der Sprint-Planung als abgeschlossen behandelt. Zum Beispiel können Status wie "Erledigt", "Gelöst" oder "Wird nicht behoben" in Ihrem Prozess ein abgeschlossenes Arbeitspaket darstellen. ' - types_and_statuses: Types and statuses + types_and_statuses: Typen und Status unassigned: Nicht zugewiesen user_preference: header_backlogs: Backlog-Modul button_update_backlogs: Backlog-Modul aktualisieren stories: update_service: - missing_target: target_id or direction must be present. - ambiguous_target: target_id and direction cannot both be present. - invalid_target_type: 'target_type must be one of: backlog_bucket:, sprint:, inbox.' - invalid_direction: 'direction must be one of: higher, highest, lower, lowest.' + missing_target: target_id oder direction muss vorhanden sein. + ambiguous_target: target_id und direction können nicht beide vorhanden sein. + invalid_target_type: 'target_type muss einer der folgenden Werte sein: backlog_bucket:, sprint:, inbox.' + invalid_direction: 'direction muss eine der folgenden sein: higher, highest, lower, lowest.' work_package_card_menu_component: action_menu: copy_url_to_clipboard: URL in die Zwischenablage kopieren copy_work_package_id: Arbeitspaket-ID kopieren move_menu: Verschieben - move_to_backlog_bucket: Move to backlog bucket - move_to_inbox: Move to inbox + move_to_backlog_bucket: In Backlog Bucket verschieben + move_to_inbox: In Posteingang verschieben move_to_sprint: Zum Sprint verschieben work_package_is_closed: Arbeitspaket ist abgeschlossen, wenn burndown: @@ -194,8 +194,8 @@ de: sprint_sharing: Sprints teilen upsell: sprint_sharing: - description: Share sprints across projects to align teams and coordinate work in scaled agile setups (SAFe). - label_all_sprints: All sprints + description: Teilen Sie Sprints über Projekte hinweg, um Teams aufeinander abzustimmen und die Arbeit in skalierten agilen Setups (SAFe) zu koordinieren. + label_all_sprints: Alle Sprints label_backlog: Backlog label_backlogs: Backlogs label_backlog_and_sprints: Backlog und Sprints @@ -215,13 +215,13 @@ de: notice_unsuccessful_start_with_reason: 'Der Sprint konnte nicht gestartet werden: %{reason}' notice_unsuccessful_finish: Der Sprint konnte nicht abgeschlossen werden. notice_unsuccessful_finish_with_reason: 'Der Sprint konnte nicht abgeschlossen werden: %{reason}' - notice_work_package_invisible_after_move: 'The work package was moved to %{backlog} but is not visible because its type or status is excluded from the backlog. + notice_work_package_invisible_after_move: 'Das Arbeitspaket wurde auf %{backlog} verschoben, ist aber nicht sichtbar, weil sein Typ oder Status gemäß Konfiguration im Backlog ausgeblendet wird. ' permission_create_sprints: Sprints erstellen permission_manage_sprint_items: Sprint-Elemente verwalten - permission_select_backlog_types_and_statuses: Select backlog types and statuses - permission_select_backlog_types_and_statuses_explanation: 'Allows choosing which work package types to hide from the backlog. Also allows defining which statuses represent a closed or finished state in the project''s workflow. + permission_select_backlog_types_and_statuses: Typen und Status für Backlogs wählen + permission_select_backlog_types_and_statuses_explanation: 'Ermöglicht die Auswahl der Arbeitspakettypen, die aus dem Backlog ausgeblendet werden sollen. Außerdem können Sie festlegen, welche Status einen abgeschlossenen oder beendeten Zustand im Projektworkflow darstellen. ' permission_share_sprint: Sprint teilen @@ -251,6 +251,6 @@ de: sprint_sharing: Sprints teilen backlogs: sharing_form_component: - sharing_description: Dieses Projekt kann entweder seine eigenen Sprints teilen, geteilte Sprints empfangen oder Sprints unabhängig bearbeiten (kein Teilen). - sharing_fallback_description: Lacking a corporate enterprise plan, the sharing options are limited to the project's own sprints. The currently active setting remains active. + sharing_description: Dieses Projekt kann entweder eigene Sprints teilen, geteilte Sprints empfangen oder Sprints eigenständig bearbeiten (ohne Teilen). + sharing_fallback_description: Ohne einen Enterprise-Plan sind die Optionen für die gemeinsame Nutzung auf die eigenen Sprints des Projekts beschränkt. Die derzeit aktive Einstellung bleibt bestehen. remaining_hours: verbleibender Aufwand diff --git a/modules/backlogs/config/locales/crowdin/js-nl.yml b/modules/backlogs/config/locales/crowdin/js-nl.yml index 6fd9b0aad01..2886ba3d64e 100644 --- a/modules/backlogs/config/locales/crowdin/js-nl.yml +++ b/modules/backlogs/config/locales/crowdin/js-nl.yml @@ -24,7 +24,7 @@ nl: js: work_packages: properties: - storyPoints: Verhaal punten + storyPoints: Story points burndown: - day: Day + day: Dag points: Points diff --git a/modules/backlogs/config/locales/crowdin/nl.yml b/modules/backlogs/config/locales/crowdin/nl.yml index b3e53a7f824..d61e239809a 100644 --- a/modules/backlogs/config/locales/crowdin/nl.yml +++ b/modules/backlogs/config/locales/crowdin/nl.yml @@ -38,7 +38,7 @@ nl: sharing: Delen statuses: in_planning: Wordt gepland - active: Actief + active: Gestart completed: Voltooid work_packages: Work packages work_package: diff --git a/modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb b/modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb index ffa558e7cd8..2f2e7a18879 100644 --- a/modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb +++ b/modules/backlogs/lib/open_project/backlogs/patches/work_package_patch.rb @@ -48,7 +48,8 @@ module OpenProject::Backlogs::Patches::WorkPackagePatch include OpenProject::Backlogs::List - scopes :backlogs_inbox_for + scopes :in_backlog_for + scopes :in_inbox_for scopes :with_backlogs_neighbours scopes :without_status_considered_closed scopes :without_excluded_type diff --git a/modules/backlogs/spec/controllers/backlogs/backlog_controller_spec.rb b/modules/backlogs/spec/controllers/backlogs/backlog_controller_spec.rb index 5827d334856..cb0e3f9cce3 100644 --- a/modules/backlogs/spec/controllers/backlogs/backlog_controller_spec.rb +++ b/modules/backlogs/spec/controllers/backlogs/backlog_controller_spec.rb @@ -38,7 +38,9 @@ RSpec.describe Backlogs::BacklogController do shared_let(:status) { create(:status, name: "status 1", is_default: true) } shared_let(:sprint) { create(:sprint, project:) } shared_let(:backlog_bucket) { create(:backlog_bucket, project:) } - shared_let(:work_package) { create(:work_package, project:, status:) } + shared_let(:inbox_work_package) { create(:work_package, project:, status:) } + shared_let(:bucket_work_package) { create(:work_package, project:, status:, backlog_bucket:) } + shared_let(:sprint_work_package) { create(:work_package, project:, status:, sprint:) } current_user { user } @@ -63,9 +65,11 @@ RSpec.describe Backlogs::BacklogController do expect(response).to render_template("backlogs/backlog/_backlog_list") expect(response).to render_template(layout: false) expect(assigns(:project)).to eq(project) - expect(assigns(:backlog_buckets)).to be_present - expect(assigns(:inbox_work_packages)).to match [work_package] - expect(assigns(:sprints)).to be_present + expect(assigns(:backlog_buckets)).to match [backlog_bucket] + expect(assigns(:sprints)).to match [sprint] + expect(assigns(:work_packages_by_sprint_id)).to eq({ sprint.id => [sprint_work_package] }) + expect(assigns(:work_packages_by_backlog_id)).to eq({ nil => [inbox_work_package], + backlog_bucket.id => [bucket_work_package] }) end end end diff --git a/modules/backlogs/spec/models/work_packages/position_spec.rb b/modules/backlogs/spec/models/work_packages/position_spec.rb index 73d815ac4fa..b948f1ad786 100644 --- a/modules/backlogs/spec/models/work_packages/position_spec.rb +++ b/modules/backlogs/spec/models/work_packages/position_spec.rb @@ -66,29 +66,34 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF let!(:bucket2_wp2) { create_work_package(subject: "Bucket 2 WorkPackage 2", backlog_bucket: bucket2) } let!(:bucket2_wp3) { create_work_package(subject: "Bucket 2 WorkPackage 3", backlog_bucket: bucket2) } - def wp_of_sprint_by_id_and_position(sprint) - WorkPackage.where(sprint:).pluck(:id, :position).to_h + def sprint_wps(sprint) + WorkPackage.where(sprint:) end - def wp_of_inbox_by_id_and_position - WorkPackage.where(sprint: nil, backlog_bucket: nil).pluck(:id, :position).to_h + def bucket_wps(bucket) + WorkPackage.where(backlog_bucket: bucket) end - def wp_of_bucket_by_id_and_position(bucket) - WorkPackage.where(backlog_bucket: bucket).pluck(:id, :position).to_h + def inbox_wps + WorkPackage.where(sprint: nil, backlog_bucket: nil) + end + + def have_positions(**) # rubocop:disable Naming/PredicatePrefix + pluck(:position, identified_by: :subject).eq(**) end context "when creating a work_package in a sprint" do it "puts them in order" do new_work_package = create_work_package(subject: "Newest WorkPackage", sprint: sprint1) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp3.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5, - new_work_package.id => 6) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp3 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5, + new_work_package => 6 + ) end end @@ -96,11 +101,12 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "puts them in order" do new_work_package = create_work_package(subject: "Newest WorkPackage") - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp2.id => 2, - inbox_wp3.id => 3, - new_work_package.id => 4) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp2 => 2, + inbox_wp3 => 3, + new_work_package => 4 + ) end end @@ -108,13 +114,14 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "puts them in order" do new_work_package = create_work_package(subject: "Newest WorkPackage", backlog_bucket: bucket1) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp3.id => 3, - bucket1_wp4.id => 4, - bucket1_wp5.id => 5, - new_work_package.id => 6) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp3 => 3, + bucket1_wp4 => 4, + bucket1_wp5 => 5, + new_work_package => 6 + ) end end @@ -123,17 +130,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF sprint1_wp2.sprint = sprint2 sprint1_wp2.save! - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp3.id => 2, - sprint1_wp4.id => 3, - sprint1_wp5.id => 4) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp5 => 4 + ) - expect(wp_of_sprint_by_id_and_position(sprint2)) - .to eq(sprint2_wp1.id => 1, - sprint2_wp2.id => 2, - sprint2_wp3.id => 3, - sprint1_wp2.id => 4) + expect(sprint_wps(sprint2)).to have_positions( + sprint2_wp1 => 1, + sprint2_wp2 => 2, + sprint2_wp3 => 3, + sprint1_wp2 => 4 + ) end end @@ -142,17 +151,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF sprint1_wp2.sprint = nil sprint1_wp2.save! - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp3.id => 2, - sprint1_wp4.id => 3, - sprint1_wp5.id => 4) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp5 => 4 + ) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp2.id => 2, - inbox_wp3.id => 3, - sprint1_wp2.id => 4) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp2 => 2, + inbox_wp3 => 3, + sprint1_wp2 => 4 + ) end end @@ -161,17 +172,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF inbox_wp2.sprint = sprint1 inbox_wp2.save! - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp3.id => 2) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp3 => 2 + ) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp3.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5, - inbox_wp2.id => 6) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp3 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5, + inbox_wp2 => 6 + ) end end @@ -179,11 +192,12 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "reorders the existing work_packages" do sprint1_wp3.destroy! - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp4.id => 3, - sprint1_wp5.id => 4) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp4 => 3, + sprint1_wp5 => 4 + ) end end @@ -191,9 +205,10 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "reorders the existing work_packages" do inbox_wp1.destroy! - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp3.id => 2) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp3 => 2 + ) end end @@ -202,17 +217,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF bucket1_wp2.backlog_bucket = bucket2 bucket1_wp2.save! - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp3.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp3 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4 + ) - expect(wp_of_bucket_by_id_and_position(bucket2)) - .to eq(bucket2_wp1.id => 1, - bucket2_wp2.id => 2, - bucket2_wp3.id => 3, - bucket1_wp2.id => 4) + expect(bucket_wps(bucket2)).to have_positions( + bucket2_wp1 => 1, + bucket2_wp2 => 2, + bucket2_wp3 => 3, + bucket1_wp2 => 4 + ) end end @@ -221,17 +238,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF bucket1_wp2.backlog_bucket = nil bucket1_wp2.save! - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp3.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp3 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4 + ) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp2.id => 2, - inbox_wp3.id => 3, - bucket1_wp2.id => 4) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp2 => 2, + inbox_wp3 => 3, + bucket1_wp2 => 4 + ) end end @@ -240,17 +259,19 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF inbox_wp2.backlog_bucket = bucket1 inbox_wp2.save! - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp3.id => 2) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp3 => 2 + ) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp3.id => 3, - bucket1_wp4.id => 4, - bucket1_wp5.id => 5, - inbox_wp2.id => 6) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp3 => 3, + bucket1_wp4 => 4, + bucket1_wp5 => 5, + inbox_wp2 => 6 + ) end end @@ -258,11 +279,12 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "reorders the existing work_packages" do bucket1_wp3.destroy! - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4 + ) end end @@ -272,19 +294,21 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF sprint1_wp4.sprint = nil sprint1_wp4.save! - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp3.id => 3, - sprint1_wp5.id => 4) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp3 => 3, + sprint1_wp5 => 4 + ) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp3.id => 3, - bucket1_wp4.id => 4, - bucket1_wp5.id => 5, - sprint1_wp4.id => 6) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp3 => 3, + bucket1_wp4 => 4, + bucket1_wp5 => 5, + sprint1_wp4 => 6 + ) end end @@ -292,19 +316,21 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "reorders the remaining sprint work_packages and the ones in the bucket" do bucket1_wp3.update(backlog_bucket: nil, sprint: sprint1) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4 + ) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp3.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5, - bucket1_wp3.id => 6) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp3 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5, + bucket1_wp3 => 6 + ) end end @@ -313,12 +339,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the sprint" do sprint1_wp4.move_after(position: 1) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp4.id => 1, - sprint1_wp1.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp4 => 1, + sprint1_wp1 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end end @@ -326,12 +353,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the sprint" do sprint1_wp1.move_after(position: 3) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp2.id => 1, - sprint1_wp3.id => 2, - sprint1_wp1.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp1 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5 + ) end end @@ -339,12 +367,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the sprint" do sprint1_wp5.move_after(position: 3) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp5.id => 3, - sprint1_wp3.id => 4, - sprint1_wp4.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp5 => 3, + sprint1_wp3 => 4, + sprint1_wp4 => 5 + ) end end @@ -352,12 +381,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the end of the sprint" do sprint1_wp2.move_after(position: 5) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp3.id => 2, - sprint1_wp4.id => 3, - sprint1_wp5.id => 4, - sprint1_wp2.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp5 => 4, + sprint1_wp2 => 5 + ) end end @@ -365,12 +395,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the sprint" do sprint1_wp2.move_after(position: 6) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp2.id => 1, - sprint1_wp1.id => 2, - sprint1_wp3.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp1 => 2, + sprint1_wp3 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5 + ) end end @@ -378,12 +409,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the second position" do sprint1_wp4.move_after(prev_id: sprint1_wp1.id) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp4.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp4 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end end @@ -391,12 +423,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do sprint1_wp1.move_after(prev_id: sprint1_wp3.id) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp2.id => 1, - sprint1_wp3.id => 2, - sprint1_wp1.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp1 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5 + ) end end @@ -404,12 +437,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do sprint1_wp5.move_after(prev_id: sprint1_wp3.id) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp2.id => 2, - sprint1_wp3.id => 3, - sprint1_wp5.id => 4, - sprint1_wp4.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp2 => 2, + sprint1_wp3 => 3, + sprint1_wp5 => 4, + sprint1_wp4 => 5 + ) end end @@ -417,12 +451,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do sprint1_wp1.move_after(prev_id: sprint1_wp5.id) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp2.id => 1, - sprint1_wp3.id => 2, - sprint1_wp4.id => 3, - sprint1_wp5.id => 4, - sprint1_wp1.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp5 => 4, + sprint1_wp1 => 5 + ) end end @@ -430,12 +465,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the sprint" do sprint1_wp4.move_after(prev_id: sprint2_wp2.id) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp4.id => 1, - sprint1_wp1.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp4 => 1, + sprint1_wp1 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end end @@ -443,12 +479,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the sprint" do sprint1_wp4.move_after(prev_id: nil) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp4.id => 1, - sprint1_wp1.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp4 => 1, + sprint1_wp1 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end end @@ -456,10 +493,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the sprint" do inbox_wp3.move_after(position: 1) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp3.id => 1, - inbox_wp1.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp3 => 1, + inbox_wp1 => 2, + inbox_wp2 => 3 + ) end end @@ -467,10 +505,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the sprint" do inbox_wp1.move_after(position: 2) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp1.id => 2, - inbox_wp3.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp1 => 2, + inbox_wp3 => 3 + ) end end @@ -478,10 +517,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the sprint" do inbox_wp3.move_after(position: 2) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp3.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp3 => 2, + inbox_wp2 => 3 + ) end end @@ -489,10 +529,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the end of the sprint" do inbox_wp1.move_after(position: 3) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp3.id => 2, - inbox_wp1.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp3 => 2, + inbox_wp1 => 3 + ) end end @@ -500,10 +541,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the sprint" do inbox_wp2.move_after(position: 4) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp1.id => 2, - inbox_wp3.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp1 => 2, + inbox_wp3 => 3 + ) end end @@ -511,10 +553,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the sprint" do inbox_wp3.move_after(prev_id: nil) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp3.id => 1, - inbox_wp1.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp3 => 1, + inbox_wp1 => 2, + inbox_wp2 => 3 + ) end end @@ -522,10 +565,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the second position" do inbox_wp3.move_after(prev_id: inbox_wp1.id) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp3.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp3 => 2, + inbox_wp2 => 3 + ) end end @@ -533,10 +577,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do inbox_wp1.move_after(prev_id: inbox_wp2.id) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp1.id => 2, - inbox_wp3.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp1 => 2, + inbox_wp3 => 3 + ) end end @@ -544,10 +589,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do inbox_wp3.move_after(prev_id: inbox_wp1.id) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp1.id => 1, - inbox_wp3.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp1 => 1, + inbox_wp3 => 2, + inbox_wp2 => 3 + ) end end @@ -555,10 +601,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do inbox_wp1.move_after(prev_id: inbox_wp3.id) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp2.id => 1, - inbox_wp3.id => 2, - inbox_wp1.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp2 => 1, + inbox_wp3 => 2, + inbox_wp1 => 3 + ) end end @@ -566,10 +613,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top position" do inbox_wp3.move_after(prev_id: sprint2_wp2.id) - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp3.id => 1, - inbox_wp1.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp3 => 1, + inbox_wp1 => 2, + inbox_wp2 => 3 + ) end end @@ -577,12 +625,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the bucket" do bucket1_wp4.move_after(position: 1) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp4.id => 1, - bucket1_wp1.id => 2, - bucket1_wp2.id => 3, - bucket1_wp3.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp4 => 1, + bucket1_wp1 => 2, + bucket1_wp2 => 3, + bucket1_wp3 => 4, + bucket1_wp5 => 5 + ) end end @@ -590,12 +639,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the bucket" do bucket1_wp1.move_after(position: 3) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp2.id => 1, - bucket1_wp3.id => 2, - bucket1_wp1.id => 3, - bucket1_wp4.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp2 => 1, + bucket1_wp3 => 2, + bucket1_wp1 => 3, + bucket1_wp4 => 4, + bucket1_wp5 => 5 + ) end end @@ -603,12 +653,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the middle of the bucket" do bucket1_wp5.move_after(position: 3) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp2.id => 2, - bucket1_wp5.id => 3, - bucket1_wp3.id => 4, - bucket1_wp4.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp2 => 2, + bucket1_wp5 => 3, + bucket1_wp3 => 4, + bucket1_wp4 => 5 + ) end end @@ -616,12 +667,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the end of the bucket" do bucket1_wp2.move_after(position: 5) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp3.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4, - bucket1_wp2.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp3 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4, + bucket1_wp2 => 5 + ) end end @@ -629,12 +681,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the second position" do bucket1_wp4.move_after(prev_id: bucket1_wp1.id) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp1.id => 1, - bucket1_wp4.id => 2, - bucket1_wp2.id => 3, - bucket1_wp3.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp1 => 1, + bucket1_wp4 => 2, + bucket1_wp2 => 3, + bucket1_wp3 => 4, + bucket1_wp5 => 5 + ) end end @@ -642,12 +695,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do bucket1_wp1.move_after(prev_id: bucket1_wp3.id) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp2.id => 1, - bucket1_wp3.id => 2, - bucket1_wp1.id => 3, - bucket1_wp4.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp2 => 1, + bucket1_wp3 => 2, + bucket1_wp1 => 3, + bucket1_wp4 => 4, + bucket1_wp5 => 5 + ) end end @@ -655,12 +709,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the last position" do bucket1_wp1.move_after(prev_id: bucket1_wp5.id) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp2.id => 1, - bucket1_wp3.id => 2, - bucket1_wp4.id => 3, - bucket1_wp5.id => 4, - bucket1_wp1.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp2 => 1, + bucket1_wp3 => 2, + bucket1_wp4 => 3, + bucket1_wp5 => 4, + bucket1_wp1 => 5 + ) end end @@ -668,12 +723,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the bucket" do bucket1_wp4.move_after(prev_id: nil) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp4.id => 1, - bucket1_wp1.id => 2, - bucket1_wp2.id => 3, - bucket1_wp3.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp4 => 1, + bucket1_wp1 => 2, + bucket1_wp2 => 3, + bucket1_wp3 => 4, + bucket1_wp5 => 5 + ) end end @@ -681,12 +737,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the top of the bucket" do bucket1_wp4.move_after(prev_id: bucket2_wp2.id) - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp4.id => 1, - bucket1_wp1.id => 2, - bucket1_wp2.id => 3, - bucket1_wp3.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp4 => 1, + bucket1_wp1 => 2, + bucket1_wp2 => 3, + bucket1_wp3 => 4, + bucket1_wp5 => 5 + ) end end @@ -695,23 +752,25 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the sprint" do sprint1_wp4.move_after(position: "1") - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp4.id => 1, - sprint1_wp1.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp4 => 1, + sprint1_wp1 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end it "moves the work_package to the middle of the sprint" do sprint1_wp1.move_after(position: "3") - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp2.id => 1, - sprint1_wp3.id => 2, - sprint1_wp1.id => 3, - sprint1_wp4.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp1 => 3, + sprint1_wp4 => 4, + sprint1_wp5 => 5 + ) end end @@ -719,12 +778,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package after the previous" do sprint1_wp4.move_after(prev_id: sprint1_wp1.id.to_s) - expect(wp_of_sprint_by_id_and_position(sprint1)) - .to eq(sprint1_wp1.id => 1, - sprint1_wp4.id => 2, - sprint1_wp2.id => 3, - sprint1_wp3.id => 4, - sprint1_wp5.id => 5) + expect(sprint_wps(sprint1)).to have_positions( + sprint1_wp1 => 1, + sprint1_wp4 => 2, + sprint1_wp2 => 3, + sprint1_wp3 => 4, + sprint1_wp5 => 5 + ) end end @@ -732,10 +792,11 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the inbox" do inbox_wp3.move_after(position: "1") - expect(wp_of_inbox_by_id_and_position) - .to eq(inbox_wp3.id => 1, - inbox_wp1.id => 2, - inbox_wp2.id => 3) + expect(inbox_wps).to have_positions( + inbox_wp3 => 1, + inbox_wp1 => 2, + inbox_wp2 => 3 + ) end end @@ -743,12 +804,13 @@ RSpec.describe WorkPackage, "positions" do # rubocop:disable RSpec/SpecFilePathF it "moves the work_package to the beginning of the bucket" do bucket1_wp4.move_after(position: "1") - expect(wp_of_bucket_by_id_and_position(bucket1)) - .to eq(bucket1_wp4.id => 1, - bucket1_wp1.id => 2, - bucket1_wp2.id => 3, - bucket1_wp3.id => 4, - bucket1_wp5.id => 5) + expect(bucket_wps(bucket1)).to have_positions( + bucket1_wp4 => 1, + bucket1_wp1 => 2, + bucket1_wp2 => 3, + bucket1_wp3 => 4, + bucket1_wp5 => 5 + ) end end end diff --git a/modules/backlogs/spec/models/work_packages/scopes/backlogs_inbox_for_spec.rb b/modules/backlogs/spec/models/work_packages/scopes/backlogs_inbox_for_spec.rb deleted file mode 100644 index 98aba91bd94..00000000000 --- a/modules/backlogs/spec/models/work_packages/scopes/backlogs_inbox_for_spec.rb +++ /dev/null @@ -1,100 +0,0 @@ -# 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 "spec_helper" - -RSpec.describe WorkPackages::Scopes::BacklogsInboxFor do - let(:open_status) { create(:status, is_closed: false) } - let(:closed_status) { create(:status, is_closed: true) } - let(:project) do - create(:project, - enabled_module_names: %w(work_package_tracking backlogs), - backlog_considered_closed_statuses: [closed_status]) - end - let(:sprint) { create(:sprint, project:) } - - before do - login_as create(:admin) - end - - subject(:inbox) { WorkPackage.backlogs_inbox_for(project:) } - - describe ".backlogs_inbox_for" do - it "returns work packages with no sprint assigned and open status" do - inbox_wp = create(:work_package, project:, status: open_status) - create(:work_package, project:, status: closed_status) - create(:work_package, project:, status: open_status, sprint:) - - expect(inbox).to contain_exactly(inbox_wp) - end - - it "excludes work packages with an excluded type from the inbox" do - excluded_type = create(:type_task) - included_type = create(:type_feature) - project.types << excluded_type - project.types << included_type - project.backlog_excluded_types << excluded_type - - visible_wp = create(:work_package, project:, status: open_status, type: included_type) - create(:work_package, project:, status: open_status, type: excluded_type) - - expect(inbox).to contain_exactly(visible_wp) - end - - it "excludes work packages with a done status (non-is_closed) from the inbox" do - done_like_status = create(:status, is_closed: false) - project.done_statuses << done_like_status - - visible_wp = create(:work_package, project:, status: open_status) - create(:work_package, project:, status: done_like_status) - - expect(inbox).to contain_exactly(visible_wp) - end - - it "excludes work packages from other projects" do - create(:work_package, status: open_status) - own_wp = create(:work_package, project:, status: open_status) - - expect(inbox).to contain_exactly(own_wp) - end - - it "orders by position ascending, falling back to id for unpositioned items" do - wp1 = create(:work_package, project:, status: open_status, position: 2) - wp2 = create(:work_package, project:, status: open_status, position: 1) - wp3 = create(:work_package, project:, status: open_status, position: nil) - wp4 = create(:work_package, project:, status: open_status, position: nil) - - wp3.update_column(:position, nil) - wp4.update_column(:position, nil) - - expect(inbox).to eq([wp2, wp1, wp3, wp4]) - end - end -end diff --git a/modules/backlogs/spec/models/work_packages/scopes/in_backlog_for_spec.rb b/modules/backlogs/spec/models/work_packages/scopes/in_backlog_for_spec.rb new file mode 100644 index 00000000000..8819a7ff70d --- /dev/null +++ b/modules/backlogs/spec/models/work_packages/scopes/in_backlog_for_spec.rb @@ -0,0 +1,158 @@ +# 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 "spec_helper" + +RSpec.describe WorkPackages::Scopes::InBacklogFor do + shared_let(:open_status) { create(:status, is_closed: false) } + shared_let(:closed_status) { create(:status, is_closed: true) } + shared_let(:excluded_type) { create(:type_task) } + shared_let(:excluded_status) { create(:status, is_closed: false) } + shared_let(:project) do + create(:project, + enabled_module_names: %w(work_package_tracking backlogs), + backlog_considered_closed_statuses: [closed_status]) do |p| + p.backlog_excluded_types << excluded_type + p.done_statuses << excluded_status + end + end + shared_let(:other_project) { create(:project) } + + shared_let(:sprint) { create(:sprint, project:) } + shared_let(:backlog_bucket) { create(:backlog_bucket, project:) } + + # Deliberately placed out of order. The before block further down will reorder them. + shared_let(:open_inbox_wp4) do + create(:work_package, subject: "Open Inbox 4", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp2) do + create(:work_package, subject: "Open Inbox 2", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp1) do + create(:work_package, subject: "Open Inbox 1", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp3) do + create(:work_package, subject: "Open Inbox 3", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:closed_inbox_wp) do + create(:work_package, status: closed_status, project:, sprint: nil, backlog_bucket: nil) + end + shared_let(:excluded_type_inbox_wp) do + create(:work_package, type: excluded_type, project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:excluded_status_inbox_wp) do + create(:work_package, status: excluded_status, project:, sprint: nil, backlog_bucket: nil) + end + + shared_let(:open_bucket_wp4) do + create(:work_package, subject: "Open Bucket 4", project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:open_bucket_wp3) do + create(:work_package, subject: "Open Bucket 3", project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:open_bucket_wp2) do + create(:work_package, subject: "Open Bucket 2", project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:open_bucket_wp1) do + create(:work_package, subject: "Open Bucket 1", project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:closed_bucket_wp) do + create(:work_package, status: closed_status, project:, sprint: nil, backlog_bucket:) + end + shared_let(:excluded_type_bucket_wp) do + create(:work_package, type: excluded_type, project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:excluded_status_bucket_wp) do + create(:work_package, status: excluded_status, project:, sprint: nil, backlog_bucket:) + end + + shared_let(:sprint_wp) do + create(:work_package, project:, status: open_status, sprint:, backlog_bucket: nil) + end + + # This is invalid as buckets are not shared. + # It is nevertheless added + shared_let(:other_project_wp) do + create(:work_package, project: other_project, status: open_status, sprint: nil, backlog_bucket:) + end + + shared_let(:user_with_permission) do + create(:user, member_with_permissions: { project => %i[view_work_packages], other_project => %i[view_work_packages] }) + end + + current_user { user_with_permission } + + subject(:backlog) { WorkPackage.in_backlog_for(project:) } + + describe ".in_backlog_for" do + before do + open_inbox_wp1.update_column(:position, 1) + open_inbox_wp2.update_column(:position, 2) + open_inbox_wp3.update_column(:position, 3) + open_inbox_wp4.update_column(:position, 4) + + open_bucket_wp1.update_column(:position, nil) + open_bucket_wp2.update_column(:position, nil) + open_bucket_wp3.update_column(:position, nil) + open_bucket_wp4.update_column(:position, nil) + end + + it "returns open work packages of the backlog (inbox + bucket) that are not excluded by type or status" do + # Excludes: + # - closed + # - excluded type + # - excluded status + # - in sprint + # - in other project + expect(backlog) + .to eq([ + # These are ordered by position + open_inbox_wp1, + open_inbox_wp2, + open_inbox_wp3, + open_inbox_wp4, + + # These are ordered by id since they don't have a position + open_bucket_wp4, + open_bucket_wp3, + open_bucket_wp2, + open_bucket_wp1 + ]) + end + + context "when the user is not allowed to view work packages" do + current_user { create(:user) } + + it "returns an empty relation" do + expect(backlog).to be_empty + end + end + end +end diff --git a/modules/backlogs/spec/models/work_packages/scopes/in_inbox_for_spec.rb b/modules/backlogs/spec/models/work_packages/scopes/in_inbox_for_spec.rb new file mode 100644 index 00000000000..c53c1f50784 --- /dev/null +++ b/modules/backlogs/spec/models/work_packages/scopes/in_inbox_for_spec.rb @@ -0,0 +1,127 @@ +# 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 "spec_helper" + +RSpec.describe WorkPackages::Scopes::InInboxFor do + shared_let(:open_status) { create(:status, is_closed: false) } + shared_let(:closed_status) { create(:status, is_closed: true) } + shared_let(:excluded_type) { create(:type_task) } + shared_let(:excluded_status) { create(:status, is_closed: false) } + shared_let(:project) do + create(:project, + enabled_module_names: %w(work_package_tracking backlogs), + backlog_considered_closed_statuses: [closed_status]) do |p| + p.backlog_excluded_types << excluded_type + p.done_statuses << excluded_status + end + end + shared_let(:other_project) { create(:project) } + + shared_let(:sprint) { create(:sprint, project:) } + shared_let(:backlog_bucket) { create(:backlog_bucket, project:) } + + # Deliberately placed out of order. The before block further down will reorder them. + shared_let(:open_inbox_wp4) do + create(:work_package, subject: "Open Inbox 4", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp2) do + create(:work_package, subject: "Open Inbox 2", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp1) do + create(:work_package, subject: "Open Inbox 1", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:open_inbox_wp3) do + create(:work_package, subject: "Open Inbox 3", project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:closed_inbox_wp) do + create(:work_package, status: closed_status, project:, sprint: nil, backlog_bucket: nil) + end + shared_let(:excluded_type_inbox_wp) do + create(:work_package, type: excluded_type, project:, status: open_status, sprint: nil, backlog_bucket: nil) + end + shared_let(:excluded_status_inbox_wp) do + create(:work_package, status: excluded_status, project:, sprint: nil, backlog_bucket: nil) + end + + shared_let(:open_bucket_wp) do + create(:work_package, subject: "Bucket", project:, status: open_status, sprint: nil, backlog_bucket:) + end + shared_let(:sprint_wp) do + create(:work_package, project:, status: open_status, sprint:, backlog_bucket: nil) + end + + # This is invalid as buckets are not shared. + # It is nevertheless added + shared_let(:other_project_wp) do + create(:work_package, project: other_project, status: open_status, sprint: nil, backlog_bucket:) + end + + shared_let(:user_with_permission) do + create(:user, member_with_permissions: { project => %i[view_work_packages], other_project => %i[view_work_packages] }) + end + + current_user { user_with_permission } + + subject(:backlog) { WorkPackage.in_inbox_for(project:) } + + describe ".in_inbox_for" do + before do + open_inbox_wp1.update_column(:position, 1) + open_inbox_wp2.update_column(:position, 2) + open_inbox_wp3.update_column(:position, 3) + open_inbox_wp4.update_column(:position, 4) + end + + it "returns open work packages of the backlog inbox that are not excluded by type or status" do + # Excludes: + # - closed + # - excluded type + # - excluded status + # - in sprint + # - in other project + expect(backlog) + .to eq([ + open_inbox_wp1, + open_inbox_wp2, + open_inbox_wp3, + open_inbox_wp4 + ]) + end + + context "when the user is not allowed to view work packages" do + current_user { create(:user) } + + it "returns an empty relation" do + expect(backlog).to be_empty + end + end + end +end diff --git a/modules/backlogs/spec/services/backlogs/work_packages/rebuild_positions_service_integration_spec.rb b/modules/backlogs/spec/services/backlogs/work_packages/rebuild_positions_service_integration_spec.rb index 610bb4c3b8a..82f617010e7 100644 --- a/modules/backlogs/spec/services/backlogs/work_packages/rebuild_positions_service_integration_spec.rb +++ b/modules/backlogs/spec/services/backlogs/work_packages/rebuild_positions_service_integration_spec.rb @@ -75,55 +75,53 @@ RSpec.describe Backlogs::WorkPackages::RebuildPositionsService, "integration", t shared_let(:bucket2_wp2) { create_work_package(subject: "Bucket 2 WorkPackage 2", backlog_bucket: bucket2, position: nil) } shared_let(:bucket2_wp3) { create_work_package(subject: "Bucket 2 WorkPackage 3", backlog_bucket: bucket2, position: nil) } + def have_positions(**) # rubocop:disable Naming/PredicatePrefix + pluck(:position).eq(**) + end + context "with the project provided" do before do described_class.new(project: project1).call end it "fixes the positions in that project while keeping those that have some in the same order" do # rubocop:disable RSpec/ExampleLength - expect(WorkPackage.where(sprint: sprint1).to_h { [it.subject, it.position] }) - .to eql( - sprint1_wp2.subject => 1, - sprint1_wp3.subject => 2, - sprint1_wp4.subject => 3, - sprint1_wp1.subject => 4, - sprint1_wp5.subject => 5 - ) + expect(WorkPackage.where(sprint: sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp1 => 4, + sprint1_wp5 => 5 + ) - expect(WorkPackage.where(sprint: sprint2).to_h { [it.subject, it.position] }) - .to eql( - sprint2_wp3.subject => 1, - sprint2_wp2.subject => 2, - sprint2_wp1.subject => 3 - ) + expect(WorkPackage.where(sprint: sprint2)).to have_positions( + sprint2_wp3 => 1, + sprint2_wp2 => 2, + sprint2_wp1 => 3 + ) - expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1).to_h { [it.subject, it.position] }) - .to eql( - inbox_wp1.subject => 1, - inbox_wp2.subject => 2, - inbox_wp3.subject => 3 - ) + expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1)).to have_positions( + inbox_wp1 => 1, + inbox_wp2 => 2, + inbox_wp3 => 3 + ) - expect(WorkPackage.where(sprint: sprint3).to_h { [it.subject, it.position] }) - .to eql( - sprint3_wp1.subject => nil, - sprint3_wp2.subject => nil, - sprint3_wp3.subject => nil - ) + expect(WorkPackage.where(sprint: sprint3)).to have_positions( + sprint3_wp1 => nil, + sprint3_wp2 => nil, + sprint3_wp3 => nil + ) - expect(WorkPackage.where(backlog_bucket: bucket1).to_h { [it.subject, it.position] }) - .to eql( - bucket1_wp3.subject => 1, - bucket1_wp2.subject => 2, - bucket1_wp1.subject => 3 - ) + expect(WorkPackage.where(backlog_bucket: bucket1)).to have_positions( + bucket1_wp3 => 1, + bucket1_wp2 => 2, + bucket1_wp1 => 3 + ) - expect(WorkPackage.where(backlog_bucket: bucket2).to_h { [it.subject, it.position] }) - .to eql( - bucket2_wp1.subject => nil, - bucket2_wp2.subject => nil, - bucket2_wp3.subject => nil - ) + expect(WorkPackage.where(backlog_bucket: bucket2)).to have_positions( + bucket2_wp1 => nil, + bucket2_wp2 => nil, + bucket2_wp3 => nil + ) end end @@ -133,49 +131,43 @@ RSpec.describe Backlogs::WorkPackages::RebuildPositionsService, "integration", t end it "fixes only the work packages in the other project" do # rubocop:disable RSpec/ExampleLength - expect(WorkPackage.where(sprint: sprint1).to_h { [it.subject, it.position] }) - .to eql( - sprint1_wp1.subject => nil, - sprint1_wp2.subject => 1, - sprint1_wp3.subject => 2, - sprint1_wp4.subject => 2, - sprint1_wp5.subject => nil - ) + expect(WorkPackage.where(sprint: sprint1)).to have_positions( + sprint1_wp1 => nil, + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 2, + sprint1_wp5 => nil + ) - expect(WorkPackage.where(sprint: sprint2).to_h { [it.subject, it.position] }) - .to eql( - sprint2_wp3.subject => 1, - sprint2_wp2.subject => 2, - sprint2_wp1.subject => 3 - ) + expect(WorkPackage.where(sprint: sprint2)).to have_positions( + sprint2_wp3 => 1, + sprint2_wp2 => 2, + sprint2_wp1 => 3 + ) - expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1).to_h { [it.subject, it.position] }) - .to eql( - inbox_wp1.subject => nil, - inbox_wp2.subject => nil, - inbox_wp3.subject => nil - ) + expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1)).to have_positions( + inbox_wp1 => nil, + inbox_wp2 => nil, + inbox_wp3 => nil + ) - expect(WorkPackage.where(sprint: sprint3).to_h { [it.subject, it.position] }) - .to eql( - sprint3_wp1.subject => 1, - sprint3_wp2.subject => 2, - sprint3_wp3.subject => 3 - ) + expect(WorkPackage.where(sprint: sprint3)).to have_positions( + sprint3_wp1 => 1, + sprint3_wp2 => 2, + sprint3_wp3 => 3 + ) - expect(WorkPackage.where(backlog_bucket: bucket1).to_h { [it.subject, it.position] }) - .to eql( - bucket1_wp1.subject => nil, - bucket1_wp2.subject => 2, - bucket1_wp3.subject => 1 - ) + expect(WorkPackage.where(backlog_bucket: bucket1)).to have_positions( + bucket1_wp1 => nil, + bucket1_wp2 => 2, + bucket1_wp3 => 1 + ) - expect(WorkPackage.where(backlog_bucket: bucket2).to_h { [it.subject, it.position] }) - .to eql( - bucket2_wp1.subject => 1, - bucket2_wp2.subject => 2, - bucket2_wp3.subject => 3 - ) + expect(WorkPackage.where(backlog_bucket: bucket2)).to have_positions( + bucket2_wp1 => 1, + bucket2_wp2 => 2, + bucket2_wp3 => 3 + ) end end @@ -185,49 +177,43 @@ RSpec.describe Backlogs::WorkPackages::RebuildPositionsService, "integration", t end it "fixes the positions while keeping those that have some in the same order in all projects" do # rubocop:disable RSpec/ExampleLength - expect(WorkPackage.where(sprint: sprint1).to_h { [it.subject, it.position] }) - .to eql( - sprint1_wp2.subject => 1, - sprint1_wp3.subject => 2, - sprint1_wp4.subject => 3, - sprint1_wp1.subject => 4, - sprint1_wp5.subject => 5 - ) + expect(WorkPackage.where(sprint: sprint1)).to have_positions( + sprint1_wp2 => 1, + sprint1_wp3 => 2, + sprint1_wp4 => 3, + sprint1_wp1 => 4, + sprint1_wp5 => 5 + ) - expect(WorkPackage.where(sprint: sprint2).to_h { [it.subject, it.position] }) - .to eql( - sprint2_wp3.subject => 1, - sprint2_wp2.subject => 2, - sprint2_wp1.subject => 3 - ) + expect(WorkPackage.where(sprint: sprint2)).to have_positions( + sprint2_wp3 => 1, + sprint2_wp2 => 2, + sprint2_wp1 => 3 + ) - expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1).to_h { [it.subject, it.position] }) - .to eql( - inbox_wp1.subject => 1, - inbox_wp2.subject => 2, - inbox_wp3.subject => 3 - ) + expect(WorkPackage.where(sprint: nil, backlog_bucket: nil, project: project1)).to have_positions( + inbox_wp1 => 1, + inbox_wp2 => 2, + inbox_wp3 => 3 + ) - expect(WorkPackage.where(sprint: sprint3).to_h { [it.subject, it.position] }) - .to eql( - sprint3_wp1.subject => 1, - sprint3_wp2.subject => 2, - sprint3_wp3.subject => 3 - ) + expect(WorkPackage.where(sprint: sprint3)).to have_positions( + sprint3_wp1 => 1, + sprint3_wp2 => 2, + sprint3_wp3 => 3 + ) - expect(WorkPackage.where(backlog_bucket: bucket1).to_h { [it.subject, it.position] }) - .to eql( - bucket1_wp3.subject => 1, - bucket1_wp2.subject => 2, - bucket1_wp1.subject => 3 - ) + expect(WorkPackage.where(backlog_bucket: bucket1)).to have_positions( + bucket1_wp3 => 1, + bucket1_wp2 => 2, + bucket1_wp1 => 3 + ) - expect(WorkPackage.where(backlog_bucket: bucket2).to_h { [it.subject, it.position] }) - .to eql( - bucket2_wp1.subject => 1, - bucket2_wp2.subject => 2, - bucket2_wp3.subject => 3 - ) + expect(WorkPackage.where(backlog_bucket: bucket2)).to have_positions( + bucket2_wp1 => 1, + bucket2_wp2 => 2, + bucket2_wp3 => 3 + ) end end end diff --git a/modules/bim/config/locales/crowdin/de.yml b/modules/bim/config/locales/crowdin/de.yml index 36b2a49e9b7..eb2bc48a9a5 100644 --- a/modules/bim/config/locales/crowdin/de.yml +++ b/modules/bim/config/locales/crowdin/de.yml @@ -74,9 +74,9 @@ de: permission_view_linked_issues: BCF-Fälle anzeigen permission_manage_bcf: BCF-Fälle importieren und verwalten permission_manage_bcf_explanation: | - Allows managing BCF issues, including bulk import and updates. - BCF import maps file metadata to project resources and can create or update work packages - and comments using author and timestamp values from the imported file, effectively acting on behalf of users. + Ermöglicht die Verwaltung von BCF-Projekten, einschließlich Massenimport und Aktualisierungen. + Der BCF-Import ordnet die Datei-Metadaten den Projektressourcen zu und kann Arbeitspakete + und Kommentare unter Verwendung von Autoren- und Zeitstempelwerten aus der importierten Datei erstellen oder aktualisieren, wobei er effektiv im Namen der Benutzer handelt. permission_delete_bcf: BCF-Fälle löschen oauth: scopes: diff --git a/modules/costs/app/views/admin/cost_types/index.html.erb b/modules/costs/app/views/admin/cost_types/index.html.erb index c82b75f30d4..9e589c86338 100644 --- a/modules/costs/app/views/admin/cost_types/index.html.erb +++ b/modules/costs/app/views/admin/cost_types/index.html.erb @@ -53,7 +53,7 @@ See COPYRIGHT and LICENSE files for more details. ) do |subheader| subheader.with_quick_filter do render( - OpPrimer::QuickFilter::SegmentedComponent.new( + OpPrimer::QuickFilter::SegmentedControlComponent.new( name: t(:label_filter_plural), query: @query, filter_key: :status, diff --git a/modules/costs/config/locales/crowdin/cs.yml b/modules/costs/config/locales/crowdin/cs.yml index 31452571fc9..55ca95b8c08 100644 --- a/modules/costs/config/locales/crowdin/cs.yml +++ b/modules/costs/config/locales/crowdin/cs.yml @@ -40,7 +40,7 @@ cs: unit_plural: Název Pluralizované jednotky default: Typ nákladů ve výchozím nastavení for_all_projects: Pro všechny projekty - rates: Rates + rates: Sazby work_package: costs_by_type: Strávené jednotky labor_costs: Náklady práce @@ -69,32 +69,32 @@ cs: entity_gid: Přihlášen models: time_entry: - one: Vstup času - few: Time entries - many: Time entries - other: Time entries + one: Časová položka + few: Časové položky + many: Časové položky + other: Časové položky cost_entry: one: Nákladová položka - few: Cost entries - many: Cost entries - other: Cost entries + few: Nákladové položky + many: Nákladových položek + other: Nákladových položek cost_type: one: Druh nákladů few: Typy nákladů many: Typy nákladů other: Typy nákladů time_entry_activity: - one: Time tracking activity - few: Sledování času - many: Sledování času - other: Sledování času + one: Položka výkazu + few: Položek výkazu + many: Položek výkazu + other: Položek výkazu rate: Sazba errors: models: time_entry: invalid_time: musí být mezi 00:00 a 23:59. - cannot_log_for_this_work_package: Cannot log time for this work package. - duplicate_ongoing: An ongoing time entry already exists for this user. + cannot_log_for_this_work_package: Nelze zaznamenat čas pro tento pracovní balíček. + duplicate_ongoing: Pro tohoto uživatele již existuje průběžný časový záznam. work_package: is_not_a_valid_target_for_cost_entries: 'Pracovní balíček #%{id} není platný cíl pro přeřazení nákladových položek.' nullify_is_not_valid_for_cost_entries: K projektu nelze přiřadit položky nákladů. @@ -130,8 +130,8 @@ cs: caption_show_locked: Zobrazit uzamčené typy caption_log_time_dialog: Čas logu description_date_for_new_rate: Datum pro nový kurz - description_costs_settings: Define the desired format for the costs in all projects. - description_time_settings: Define which fields are mandatory to fill when logging time in all projects. + description_costs_settings: Definujte požadovaný formát nákladů ve všech projektech. + description_time_settings: Definujte, která pole jsou povinná při zaznamenávání času ve všech projektech. group_by_others: není v žádné skupině label_between: mezi label_cost_filter_add: Přidat filtr nákladového vstupu @@ -157,7 +157,7 @@ cs: label_kind: Typ label_less_or_equal: "<=" label_log_costs: Logovat jednotkové náklady - label_new_time_entry_activity: New time entry activity + label_new_time_entry_activity: Nová časová položka label_time_entry_activity_form_description: Changes to this time entry activity will be reflected in all projects where it is enabled. label_no: Ne label_option_plural: Možnosti @@ -193,7 +193,7 @@ cs: label_day: Den label_today_capitalized: Dnes label_view_mode_switcher: Změnit zobrazení - label_timer_since: Started at %{time} + label_timer_since: Začalo v %{time} placeholder_activity_select_work_package_first: Nejprve je nutné vybrat pracovní balíček notice_something_wrong: Něco se pokazilo. Zkuste to prosím znovu. notice_successful_restore: Úspěšně obnoveno. @@ -248,7 +248,7 @@ cs: no_cost_types_available: No cost types are available in this project. Please contact an administrator. admin: columns: - active_projects: Active projects + active_projects: Aktivní projekty cost_type_projects: for_all_projects_blank_slate: heading: This cost type is enabled in all projects @@ -259,7 +259,7 @@ cs: rates: title: Rate history settings: - time_and_costs: Time & Costs + time_and_costs: Čas & náklady cost_types: heading: Cost types none_active: No cost types are currently active in this project. diff --git a/modules/costs/config/locales/crowdin/de.yml b/modules/costs/config/locales/crowdin/de.yml index a44af351160..434a059e86c 100644 --- a/modules/costs/config/locales/crowdin/de.yml +++ b/modules/costs/config/locales/crowdin/de.yml @@ -39,8 +39,8 @@ de: unit: Einheit unit_plural: Einheit plural default: Standardkostentyp - for_all_projects: For all projects - rates: Rates + for_all_projects: Für alle Projekte + rates: Preise work_package: costs_by_type: Gebuchte Einheiten labor_costs: Personaleinzelkosten @@ -93,7 +93,7 @@ de: cost_types_project: attributes: project_ids: - blank: Please select a project. + blank: Bitte wählen Sie ein Projekt aus. attributes: comment: Kommentar cost_type: Kostentyp @@ -234,28 +234,28 @@ de: errors: validation: start_time_different_date: Der Datumsteil der Startzeit (%{start_time}) muss mit dem Datum (%{spent_on}) übereinstimmen. - label_available_cost_types_projects: Available cost types projects + label_available_cost_types_projects: Verfügbare Kostenarten in Projekten cost_types: errors: - no_cost_types_available: No cost types are available in this project. Please contact an administrator. + no_cost_types_available: In diesem Projekt sind keine Kostenarten verfügbar. Bitte kontaktieren Sie einen Administrator. admin: columns: - active_projects: Active projects + active_projects: Aktive Projekte cost_type_projects: for_all_projects_blank_slate: - heading: This cost type is enabled in all projects - description: Uncheck "For all projects" on the details tab to limit this cost type to specific projects. + heading: Diese Kostenart ist in allen Projekten aktiviert + description: Deaktivieren Sie auf der Registerkarte "Details" die Option "Für alle Projekte", um diese Kostenart auf bestimmte Projekte zu beschränken. no_projects: - heading: No projects assigned - description: Add projects so this cost type can be used in them. + heading: Keine zugewiesenen Projekte + description: Fügen Sie Projekte hinzu, damit diese Kostenart in ihnen verwendet werden kann. rates: - title: Rate history + title: Stückpreise-Historie settings: - time_and_costs: Time & Costs + time_and_costs: Zeit und Kosten cost_types: - heading: Cost types - none_active: No cost types are currently active in this project. - for_all_projects_hint: This cost type is enabled in all projects. + heading: Kostentypen + none_active: In diesem Projekt sind derzeit keine Kostenarten aktiv. + for_all_projects_hint: Diese Kostenart ist in allen Projekten aktiviert. costs: widgets: actual_costs: diff --git a/modules/documents/app/assets/stylesheets/_index.sass b/modules/documents/app/assets/stylesheets/_index.sass index 848b2ecedc3..a1f547e0c29 100644 --- a/modules/documents/app/assets/stylesheets/_index.sass +++ b/modules/documents/app/assets/stylesheets/_index.sass @@ -4,7 +4,14 @@ $blocknote-max-width: 800px .ck-content min-height: 30vh -.block-note-editor-container +// BlockNote 0.51 stamps `.block-note-editor-container` (the className we +// pass to ) onto BOTH its outer `.bn-container` wrapper AND +// an inner wrapper without `.bn-container`. Without the `.bn-container` +// requirement, the rules below cascade onto both elements — `gap: 10px` +// and `flex-direction: column-reverse` get applied at two nesting levels, +// which shows up as a few-pixel vertical layout jump whenever the side +// menu / drag handle re-renders during selection. +.block-note-editor-container.bn-container align-items: center position: relative display: flex diff --git a/modules/documents/spec/features/block_note_editor_spec.rb b/modules/documents/spec/features/block_note_editor_spec.rb index dcb7689d0ae..1be052e1f78 100644 --- a/modules/documents/spec/features/block_note_editor_spec.rb +++ b/modules/documents/spec/features/block_note_editor_spec.rb @@ -182,6 +182,37 @@ RSpec.describe "BlockNote editor rendering", :js, :selenium, with_settings: { re editor.wait_for_autosave { document.reload.description&.include?("##{work_package.id}") } end + + describe "CTRL-Z undo behavior" do + it "undoes typed text with CTRL-Z" do + visit document_path(document) + expect(page).to have_test_selector("blocknote-document-description") + + editor.fill_in("X") + expect(editor.element).to have_text("X") + + editor.undo + + expect(editor.element).to have_no_text("X") + end + + it "undoes an inline work package chip inserted via # notation with CTRL-Z" do + visit document_path(document) + expect(page).to have_test_selector("blocknote-document-description") + + editor.element.send_keys("#tiger") + editor.wait_for_shadow_content("pet a tiger") + send_keys(:enter) + expect(editor.element).to have_no_text("#tiger") # chip replaced autocomplete text + + expect(editor.element).to have_no_text("…") # chip finished loading + expect(editor.element).to have_text(/##{work_package.display_id}/) + + editor.undo + + expect(editor.element).to have_no_text(/##{work_package.display_id}/) + end + end end end end diff --git a/modules/gantt/config/locales/crowdin/js-cs.yml b/modules/gantt/config/locales/crowdin/js-cs.yml index 6fd0725be61..7cde463be71 100644 --- a/modules/gantt/config/locales/crowdin/js-cs.yml +++ b/modules/gantt/config/locales/crowdin/js-cs.yml @@ -2,6 +2,6 @@ cs: js: work_packages: - label_gantt_chart_plural: Gantt diagramy + label_gantt_chart_plural: Ganttovy diagramy default_queries: milestones: Milníky diff --git a/modules/github_integration/frontend/module/tab-prs/tab-prs.component.ts b/modules/github_integration/frontend/module/tab-prs/tab-prs.component.ts index d553eacc43e..63e9712e4ae 100644 --- a/modules/github_integration/frontend/module/tab-prs/tab-prs.component.ts +++ b/modules/github_integration/frontend/module/tab-prs/tab-prs.component.ts @@ -58,7 +58,7 @@ export class TabPrsComponent implements OnInit { emptyText:string; ngOnInit():void { - this.emptyText = this.I18n.t('js.github_integration.tab_prs.empty', { wp_id: this.workPackage.id }); + this.emptyText = this.I18n.t('js.github_integration.tab_prs.empty', { wp_id: this.workPackage.displayId }); this.pullRequests$ = this .githubPullRequests .ofWorkPackage(this.workPackage) diff --git a/modules/gitlab_integration/config/locales/crowdin/cs.yml b/modules/gitlab_integration/config/locales/crowdin/cs.yml index 90860cf3303..6d6153864bb 100644 --- a/modules/gitlab_integration/config/locales/crowdin/cs.yml +++ b/modules/gitlab_integration/config/locales/crowdin/cs.yml @@ -36,7 +36,7 @@ cs: activerecord: attributes: gitlab_pipeline: - ci_details: CI Details + ci_details: Podrobnosti o CI gitlab_merge_request: labels: Štítky errors: @@ -49,8 +49,8 @@ cs: attributes: labels: invalid_schema: 'musí být pole hashů s klíči: barva, název' - label_gitlab_integration: GitLab Integration - label_gitlab_actor: GitLab actor + label_gitlab_integration: Integrace s GitLabem + label_gitlab_actor: Aktér GitLabu label_gitlab_webhook_secret: Webhook secret text_gitlab_actor_info: 'The OpenProject user whose API key must be used to authenticate incoming webhook requests. When set, requests authenticated with any other user''s credentials are rejected. This user also posts automated comments on work packages. Defaults to the system user when not set. diff --git a/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.component.ts b/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.component.ts index 09c0afb4772..5f72007fae3 100644 --- a/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.component.ts +++ b/modules/gitlab_integration/frontend/module/tab-mrs/tab-mrs.component.ts @@ -65,6 +65,6 @@ export class TabMrsComponent implements OnInit { } public getEmptyText() { - return this.I18n.t('js.gitlab_integration.tab_mrs.empty',{ wp_id: this.workPackage.id }); + return this.I18n.t('js.gitlab_integration.tab_mrs.empty',{ wp_id: this.workPackage.displayId }); } } diff --git a/modules/grids/config/locales/crowdin/cs.yml b/modules/grids/config/locales/crowdin/cs.yml index 20c0cd19457..70ece0a5e13 100644 --- a/modules/grids/config/locales/crowdin/cs.yml +++ b/modules/grids/config/locales/crowdin/cs.yml @@ -16,10 +16,10 @@ cs: view_all_members: Zobrazit všechny členy show_members_count: Zobrazit všech %{count} členů x_more: - one: and one more member. - few: and %{count} more members. - many: and %{count} more members. - other: and %{count} more members. + one: a ještě jeden člen. + few: a ještě %{count} členů. + many: a ještě %{count} členů. + other: a ještě %{count} členů. news: no_results: Žádné novinky. activerecord: diff --git a/modules/grids/config/locales/crowdin/js-de.yml b/modules/grids/config/locales/crowdin/js-de.yml index 67885537124..866bbbcfbc2 100644 --- a/modules/grids/config/locales/crowdin/js-de.yml +++ b/modules/grids/config/locales/crowdin/js-de.yml @@ -33,7 +33,7 @@ de: title: Unterelemente project_favorites: title: Favorisierte Projekte - no_results: You currently have no favorite projects. Add one or multiple projects as favorite through their overview or in a project list. + no_results: Sie haben derzeit keine favorisierten Projekte. Fügen Sie ein oder mehrere Projekte in der Übersicht oder in einer Projektliste als Favoriten hinzu. time_entries_current_user: title: Meine gebuchte Zeit displayed_days: 'Dargestellte Tage im Widget:' diff --git a/modules/ldap_groups/config/locales/crowdin/cs.yml b/modules/ldap_groups/config/locales/crowdin/cs.yml index f647d870ad7..300983217f6 100644 --- a/modules/ldap_groups/config/locales/crowdin/cs.yml +++ b/modules/ldap_groups/config/locales/crowdin/cs.yml @@ -33,7 +33,7 @@ cs: ldap_groups: label_menu_item: Synchronizace skupiny LDAP label_group_key: LDAP skupinový klíč filtru - label_synchronize: Discover LDAP groups + label_synchronize: Zjištění skupin LDAP settings: name_attribute: Atribut názvu LDAP skupin name_attribute_text: LDAP atribut používaný pro pojmenování skupiny OpenProject při vytváření filtrem diff --git a/modules/ldap_groups/config/locales/crowdin/de.yml b/modules/ldap_groups/config/locales/crowdin/de.yml index c895ce65e1d..2059a09aa07 100644 --- a/modules/ldap_groups/config/locales/crowdin/de.yml +++ b/modules/ldap_groups/config/locales/crowdin/de.yml @@ -22,7 +22,7 @@ de: group_name_attribute: Attribut für Gruppenname sync_users: Benutzer synchronisieren base_dn: Suchbasis DN - member_lookup_attribute: Group member attribute + member_lookup_attribute: Attribut für Gruppenmitglieder models: ldap_groups/synchronized_group: Synchronisierte LDAP-Gruppe ldap_groups/synchronized_filter: Synchronisationsfilter für LDAP-Gruppe @@ -33,7 +33,7 @@ de: ldap_groups: label_menu_item: LDAP-Gruppensynchronisierung label_group_key: LDAP-Gruppenfilter - label_synchronize: Discover LDAP groups + label_synchronize: LDAP-Gruppen entdecken settings: name_attribute: Attribut für LDAP-Gruppenname name_attribute_text: Das LDAP-Attribut für das Benennen einer OpenProject-Gruppe, wenn sie durch einen Filter angelegt wird. @@ -57,7 +57,7 @@ de: base_dn_text: 'Geben Sie den Suchbase-DN ein, der für diesen Filter verwendet werden soll. Er muss unter dem Basis-DN der gewählten LDAP-Verbindung liegen. Lassen Sie diese Option leer, um den Basis-DN der Verbindung wiederverwenden ' - member_lookup_attribute_text: 'Leave empty to use the default reverse lookup: OpenProject searches for users whose memberOf attribute matches the group DN. This requires the memberOf attribute to be present on user entries (Active Directory, OpenLDAP with memberof overlay). Set this to the attribute name on group entries that lists member DNs to use forward lookup instead. Examples: "uniqueMember" (groupOfUniqueNames), "member" (groupOfNames). Use this for LDAP servers that do not maintain the memberOf attribute on user entries. + member_lookup_attribute_text: 'Lassen Sie diese Option leer, um standardmäßig die Rückwärtssuche zu verwenden: OpenProject sucht nach Benutzern, deren memberOf-Attribut mit dem DN der Gruppe übereinstimmt. Dazu muss das Attribut memberOf in den Benutzereinträgen vorhanden sein (Active Directory, OpenLDAP mit memberof overlay). Setzen Sie dies auf den Attributnamen in Gruppeneinträgen, die Mitglieder-DNs auflisten, um stattdessen Forward Lookup zu verwenden. Beispiele: "uniqueMember" (groupOfUniqueNames), "member" (groupOfNames). Verwenden Sie dies für LDAP-Server, die das Attribut memberOf nicht für Benutzereinträge pflegen. ' synchronized_groups: @@ -68,16 +68,16 @@ de: confirmation: Wenn Sie fortfahren, werden die synchronisierte Gruppe %{name} und alle %{users_count} Benutzer, die durch sie synchronisiert wurden, entfernt. info: 'Hinweis: Die OpenProject Gruppe selbst und die Mitglieder, die außerhalb dieser LDAP-Synchronisation hinzugefügt wurden, werden nicht entfernt.' help_text_html: | - This module allows you to set up a synchronization between LDAP and OpenProject groups. + Mit diesem Modul können Sie eine Synchronisierung für Gruppen zwischen LDAP und OpenProject einrichten.
- By default, OpenProject uses reverse lookup: it searches for users whose memberOf attribute matches the group DN. - This requires the memberOf attribute to be present on user entries (Active Directory, OpenLDAP with memberof overlay). + Standardmäßig verwendet OpenProject die umgekehrte Suche: Es sucht nach Benutzern, deren memberOf-Attribut mit dem DN der Gruppe übereinstimmt. + Dazu muss das Attribut memberOf in den Benutzereinträgen vorhanden sein (Active Directory, OpenLDAP mit memberof overlay).
- If your LDAP server does not maintain memberOf on user entries (e.g. it uses groupOfUniqueNames with uniqueMember), - you can configure forward lookup by setting the Group member attribute on the synchronization filter. + Wenn Ihr LDAP-Server das Attribut memberOf für Benutzereinträge nicht enthält (er verwendet z.B. groupOfUniqueNames mit uniqueMember), + können Sie die Vorwärtssuche konfigurieren, indem Sie das Attribut Gruppenmitglied im Synchronisationsfilter setzen.
- Groups are synchronized hourly through a cron job. - [Please see our documentation on this topic](docs_url). + Die Gruppen werden stündlich über einen Cron-Job synchronisiert. + [Bitte lesen Sie unsere Dokumentation zu diesem Thema](docs_url). no_results: Keine synchronisierten Gruppen gefunden. no_members: Diese Gruppe hat noch keine synchronisierten Mitglieder. plural: Synchronisierte LDAP-Gruppen diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb index 09a288aec64..063e4434fc9 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -13,6 +13,20 @@ render(Meetings::MeetingTimeFilterComponent.new(query: @query, project: @project)) end + if @project.nil? + subheader.with_quick_filter do + render( + OpPrimer::QuickFilter::SelectPanelComponent.new( + name: I18n.t(:label_project), + query: @query, + filter_key: :project_id, + path_args: [@project, :meetings], + src: project_items_meetings_path + ) + ) + end + end + subheader.with_filter_component do render(Meetings::MeetingFilterButtonComponent.new(query: @query, project: @project)) end diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.rb b/modules/meeting/app/components/meetings/index_sub_header_component.rb index d5a2620632d..346ff5971b8 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.rb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.rb @@ -41,6 +41,8 @@ module Meetings @params = params end + private + def render_create_button? if @project User.current.allowed_in_project?(:create_meetings, @project) diff --git a/modules/meeting/app/components/meetings/meeting_time_filter_component.rb b/modules/meeting/app/components/meetings/meeting_time_filter_component.rb index 96896d8e4ac..10fa5d0b1a8 100644 --- a/modules/meeting/app/components/meetings/meeting_time_filter_component.rb +++ b/modules/meeting/app/components/meetings/meeting_time_filter_component.rb @@ -29,7 +29,7 @@ # ++ module Meetings - class MeetingTimeFilterComponent < OpPrimer::QuickFilter::SegmentedComponent + class MeetingTimeFilterComponent < OpPrimer::QuickFilter::SegmentedControlComponent def initialize(query:, project: nil) super( name: I18n.t(:label_meeting_date_time), diff --git a/modules/meeting/app/controllers/meetings_controller.rb b/modules/meeting/app/controllers/meetings_controller.rb index fbebcf7051b..6b41bf4b8e5 100644 --- a/modules/meeting/app/controllers/meetings_controller.rb +++ b/modules/meeting/app/controllers/meetings_controller.rb @@ -34,7 +34,7 @@ class MeetingsController < ApplicationController before_action :determine_date_range, only: %i[history] before_action :determine_author, only: %i[history] before_action :build_meeting, only: %i[new new_dialog fetch_timezone] - before_action :find_meeting, except: %i[index new create new_dialog fetch_timezone fetch_templates] + before_action :find_meeting, except: %i[index new create new_dialog fetch_timezone fetch_templates project_items] before_action :redirect_to_project, only: %i[show] before_action :set_activity, only: %i[history] before_action :find_copy_from_meeting, only: %i[create] @@ -383,6 +383,25 @@ class MeetingsController < ApplicationController respond_with_turbo_streams end + def project_items + @query = load_query + # Scope to projects that have meetings visible to the current user + projects = Project.where(id: @query.results.select(:project_id)).order(:name) + # The component appends ?selected=id1,id2 so we know which items to mark as selected. + # Standard filters can't be passed to the query because then the projects from @query.results + # would be *only* the already selected list + selected_ids = params[:selected]&.split(",") || [] + + respond_to do |format| + format.html_fragment do + render "meetings/project_items", + locals: { projects:, selected_ids: }, + layout: false, + formats: %i[html html_fragment] + end + end + end + def generate_pdf_dialog respond_with_dialog Meetings::Exports::ModalDialogComponent.new( meeting: @meeting, diff --git a/modules/meeting/app/services/meetings/copy_service.rb b/modules/meeting/app/services/meetings/copy_service.rb index eaa751e1e10..a0c3f6cf4fb 100644 --- a/modules/meeting/app/services/meetings/copy_service.rb +++ b/modules/meeting/app/services/meetings/copy_service.rb @@ -113,14 +113,19 @@ module Meetings attachment_target]) end - def copy_meeting_agenda(copy) + def copy_meeting_agenda(copy) # rubocop:disable Metrics/AbcSize meeting.sections.each do |section| copy.sections << section.dup copied_section = copy.reload.sections.last section.agenda_items.each do |agenda_item| copied_agenda_item = agenda_item.dup copied_agenda_item.meeting_id = copy.id - copied_section.agenda_items << copied_agenda_item + copied_agenda_item.meeting_section = copied_section + + # A work_package agenda item whose WP was deleted has work_package_id nullified but + # item_type still set. Skip validations for this state + skip_validation = copied_agenda_item.work_package? && copied_agenda_item.work_package_id.nil? + copied_agenda_item.save!(validate: !skip_validation) end end end diff --git a/modules/meeting/app/services/meetings/set_attributes_service.rb b/modules/meeting/app/services/meetings/set_attributes_service.rb index bd30307312b..c8ce03a03f4 100644 --- a/modules/meeting/app/services/meetings/set_attributes_service.rb +++ b/modules/meeting/app/services/meetings/set_attributes_service.rb @@ -60,14 +60,26 @@ module Meetings model.participants.clear model.participants_attributes = participants_attributes else - model.participants_attributes = merge_with_existing_participants(participants_attributes) + replace_participants(participants_attributes) end end - def merge_with_existing_participants(participants_attributes) - existing_user_ids = model.participants.to_set { |p| p.user_id.to_i } + def replace_participants(participants_attributes) + incoming_user_ids = participants_attributes.to_set { |attrs| attrs[:user_id].to_i } + existing_participants = model.participants.index_by { |p| p.user_id.to_i } - participants_attributes.reject { |attrs| existing_user_ids.include?(attrs[:user_id].to_i) } + mark_removed_participants(incoming_user_ids, existing_participants) + model.participants_attributes = added_participant_attributes(participants_attributes, existing_participants) + end + + def mark_removed_participants(incoming_user_ids, existing_participants) + existing_participants.each do |user_id, participant| + participant.mark_for_destruction unless incoming_user_ids.include?(user_id) + end + end + + def added_participant_attributes(participants_attributes, existing_participants) + participants_attributes.reject { |attrs| existing_participants.key?(attrs[:user_id].to_i) } end def set_default_participant diff --git a/modules/meeting/app/services/recurring_meetings/reset_to_template_service.rb b/modules/meeting/app/services/recurring_meetings/reset_to_template_service.rb index b399aa6a59e..005125417d2 100644 --- a/modules/meeting/app/services/recurring_meetings/reset_to_template_service.rb +++ b/modules/meeting/app/services/recurring_meetings/reset_to_template_service.rb @@ -90,10 +90,13 @@ module RecurringMeetings section.attributes.except("id", "meeting_id", "created_at", "updated_at") ) section.agenda_items.each do |item| - # copy_attributes excludes :id and :meeting_id; we supply both FKs explicitly - new_section.agenda_items.create!( - item.copy_attributes.except("meeting_section_id").merge("meeting_id" => meeting.id) - ) + new_item = item.dup + new_item.meeting_section = new_section + + # A work_package agenda item whose WP was deleted has work_package_id nullified but + # item_type still set. Skip validations for this state + skip_validation = new_item.work_package? && new_item.work_package_id.nil? + new_item.save!(validate: !skip_validation) end end end diff --git a/modules/meeting/app/services/recurring_meetings/update_service.rb b/modules/meeting/app/services/recurring_meetings/update_service.rb index 307875406d0..678eb8b1ddf 100644 --- a/modules/meeting/app/services/recurring_meetings/update_service.rb +++ b/modules/meeting/app/services/recurring_meetings/update_service.rb @@ -175,7 +175,7 @@ module RecurringMeetings .cancelled .find_each do |meeting| occurring = recurring_meeting.schedule.occurs_at?(meeting.recurrence_start_time) - meeting.delete unless occurring + meeting.destroy! unless occurring end end diff --git a/modules/meeting/app/views/meetings/project_items.html.erb b/modules/meeting/app/views/meetings/project_items.html.erb new file mode 100644 index 00000000000..fcee3df2f36 --- /dev/null +++ b/modules/meeting/app/views/meetings/project_items.html.erb @@ -0,0 +1,38 @@ +<%#-- 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. + +++#%> + +<%= render(Primer::Alpha::SelectPanel::ItemList.new(select_variant: :multiple)) do |list| %> + <% projects.each do |project| %> + <% list.with_item( + label: project.name, + active: selected_ids.include?(project.id.to_s), + content_arguments: { data: { value: project.id.to_s } } + ) %> + <% end %> +<% end %> diff --git a/modules/meeting/config/locales/crowdin/cs.yml b/modules/meeting/config/locales/crowdin/cs.yml index 0228cefe006..a844a59b353 100644 --- a/modules/meeting/config/locales/crowdin/cs.yml +++ b/modules/meeting/config/locales/crowdin/cs.yml @@ -32,7 +32,7 @@ cs: location: Místo duration: Doba trvání notes: Poznámky - recurrence_start_time: Scheduled start time + recurrence_start_time: Plánovaný čas zahájení participants: Účastníci participant: one: 1 Účastník @@ -41,14 +41,14 @@ cs: other: "%{count} Účastníků" participants_attended: Účastníci participants_invited: Pozvaní - participants_added: 'Participants added:' - participants_removed: 'Participants removed:' + participants_added: 'Přidaní účastníci:' + participants_removed: 'Odebraní účastníci:' project: Projekt start_date: Datum start_time: Čas zahájení start_time_hour: Čas zahájení - end_time: End time - template: Template + end_time: Čas ukončení + template: Šablona notify: Send notifications sharing: Sdílení meeting_agenda_item: @@ -68,19 +68,19 @@ cs: title: Title frequency: Frekvence interval: Interval - monthly_day: Day of month - monthly_ordinal: Position - monthly_weekday: Weekday + monthly_day: Den v měsíci + monthly_ordinal: Pozice + monthly_weekday: Pracovní den start_date: Začíná v start_time: Čas zahájení start_time_hour: Čas zahájení end_after: Řada schůzek končí end_date: Datum ukončení iterations: Výskyty - time_zone: Time zone - location: Location - duration: Duration - notify: Send notifications + time_zone: Časová zóna + location: Poloha + duration: Doba trvání + notify: Posílat oznámení recurring_meeting_interim_response: start_time: Čas zahájení meeting_participant: @@ -220,7 +220,7 @@ cs: label_notify: Odeslat k posouzení label_icalendar: Odeslat iCalendar label_icalendar_download: Stáhnout událost iCalendar - label_view_meeting: View meeting + label_view_meeting: Zobrazit schůzku label_view_meeting_series: Zobrazit sérii schůzek label_meeting_series: Řada schůzek label_version: Verze @@ -246,7 +246,7 @@ cs: apply_to_upcoming_meetings: Apply these changes to all upcoming meetings in this series text: template: Tito účastníci budou automaticky pozváni na všechna budoucí zasedání po jejich vytvoření. - manage_participants: Search for and add project members as participants to this meeting. + manage_participants: Vyhledejte a přidejte členy projektu jako účastníky této schůzky. search_for_members: Vyhledávání členů projektu blankslate: heading: Nikdo tu není @@ -303,8 +303,8 @@ cs: new_date_time: Nové datum/čas old_location: Stará lokace new_location: Nová lokace - added_participants: Added - removed_participants: Removed + added_participants: Přidáni + removed_participants: Odebráni label_mail_all_participants: Poslat e-mailovou pozvánku všem účastníkům types: one_time: Jednorázový @@ -440,7 +440,7 @@ cs: ' ended_blankslate: title: Řada schůzek skončila - message: 'This meeting series has come to an end. There are no upcoming meetings. ' + message: 'Tato série schůzek skončila a žádná nadcházející setkání se nekonají. ' action: You can still view past occurrences or edit the meeting series to extend it. occurrence: infoline: Tato schůzka je součástí opakované série schůzek. @@ -466,64 +466,64 @@ cs: frequency: x_daily: one: Každý den - few: Every %{count} days - many: Every %{count} days + few: Každých %{count} dní + many: Každých %{count} dní other: Každých %{count} dní x_weekly: one: Každý týden - few: Every %{count} weeks - many: Every %{count} weeks + few: Každých %{count} týdnů + many: Každých %{count} týdnů other: Každých %{count} týdnů x_monthly: - one: Every month - few: Every %{count} months - many: Every %{count} months - other: Every %{count} months - monthly_day_of_month: Day of month - monthly_nth_weekday: Monthly on a weekday + one: Každý měsíc + few: Každých %{count} měsíců + many: Každých %{count} měsíců + other: Každých %{count} měsíců + monthly_day_of_month: Den v měsíci + monthly_nth_weekday: Měsíčně ve všední den every_weekday: Každý %{day_of_the_week} working_days: Každý pracovní den monthly: inflected_ordinal: - first: first - second: second - third: third - fourth: fourth - last: last + first: první + second: druhý + third: třetí + fourth: čtvrtý + last: poslední ordinal_options: - first: First - second: Second - third: Third - fourth: Fourth - last: Last - actual_first_occurrence_mismatch_html: The first occurrence of this series will be %{first_occurrence} - day_of_month_skipping_info: Months with fewer than %{monthly_day} days will be skipped + first: První + second: Druhý + third: Třetí + fourth: Čtvrtý + last: Poslední + actual_first_occurrence_mismatch_html: První výskyt této série bude %{first_occurrence} + day_of_month_skipping_info: Měsíce s méně než %{monthly_day} dny budou vynechány end_after: - never: Never - specific_date: After a specific date - iterations: After a number of occurrences + never: Nikdy + specific_date: Po určitém datu + iterations: Po několika událostech starts: Začíná in_words: daily_interval: Každé %{interval} dny working_days: Každý pracovní den weekly: Každý týden na %{weekday} weekly_interval: Každý %{interval} týdny v %{weekday} - monthly_day: Every month on the %{day} - monthly_day_interval: Every %{interval} months on the %{day} - monthly_nth_weekday: Every month on the %{ordinal} %{weekday} - monthly_nth_weekday_interval: Every %{interval} months on the %{ordinal} %{weekday} + monthly_day: Každý měsíc na %{day} + monthly_day_interval: Každých %{interval} měsíců na %{day} + monthly_nth_weekday: Každý měsíc na %{ordinal} %{weekday} + monthly_nth_weekday_interval: Každých %{interval} měsíců na %{ordinal} %{weekday} frequency: "%{base} v %{time}" full: "%{base} v %{time}, končí %{end_date}" - full_past: "%{base} at %{time}, ended on %{end_date}" + full_past: "%{base} v %{time}, skončila %{end_date}" never_ending: "%{base} v %{time}" open: title: Program byl otevřen - subtitle: 'Open meetings have agendas that can be edited and show up in individual users’ ‘My meetings’ section. Changes to the meeting series template do not affect already-open meeting occurrences. + subtitle: 'Otevřené schůzky mají programy, které lze upravovat a které se zobrazují v sekci "Moje schůzky" jednotlivých uživatelů. Změny šablony série schůzek nemají vliv na již otevřené schůzky. ' blankslate: title: Momentálně žádné otevřené schůzky - desc: You can manually open a planned meeting by clicking on the 'Open' button below + desc: Plánovanou schůzku můžete otevřít ručně kliknutím na tlačítko "Otevřít" níže planned: title: Plánováno subtitle: 'Následující schůzky jsou plánovány v harmonogramu opakovaných schůzek, ale zatím nejsou otevřeny. Pokaždé, když začne plánovaná schůzka, automaticky se vám otevře další. Naplánované schůzky můžete otevřít také ručně, abyste mohli importovat šablonu a začít upravovat program. @@ -531,7 +531,7 @@ cs: ' blankslate: title: Žádné další plánované schůzky - desc: 'There are no additional meetings planned in this series. To schedule additional meetings or extend the series, go to the template and edit meeting details to change the end date, frequency or interval. + desc: 'V této sérii nejsou plánována žádné další schůzky. Chcete-li naplánovat další schůzky nebo sérii prodloužit, přejděte do šablony a upravte podrobnosti o schůzce, abyste změnili datum ukončení, frekvenci nebo interval. ' delete_dialog: @@ -567,7 +567,7 @@ cs: permission_delete_meetings: Smazat schůzku permission_view_meetings: Zobrazit schůzky permission_manage_agendas: Správa zápisů - permission_manage_agendas_explanation: Allows creating, editing and removing agenda items + permission_manage_agendas_explanation: Umožňuje vytvářet, upravovat a odebírat položky agendy permission_manage_outcomes: Spravovat výsledky permission_send_meeting_invites_and_outcomes: Odeslat pozvánky a výsledky všem účastníkům této schůzky project_module_meetings: Schůzky @@ -613,28 +613,28 @@ cs: label_agenda_item_move: Přesunout label_agenda_item_move_to_next: Přesunout na příští schůzi label_agenda_item_move_to_backlog: Přesunout do backlogu - label_agenda_item_move_to_current_meeting: Move to current meeting - label_agenda_item_move_to_section: Move to section + label_agenda_item_move_to_current_meeting: Přesunout do aktuální schůze + label_agenda_item_move_to_section: Přesun do sekce label_agenda_item_move_to_top: Přesunout nahoru label_agenda_item_move_to_bottom: Přesunout na konec label_agenda_item_move_up: Přesunout výš label_agenda_item_move_down: Přesunout níž - label_agenda_item_duplicate: Duplicate + label_agenda_item_duplicate: Kopírovat label_agenda_item_duplicate_in_next: Duplicate in next meeting label_agenda_item_duplicate_in_next_title: Duplicate in next meeting? label_agenda_item_add_notes: Přidat poznámky label_agenda_item_add_outcome: Přidat výsledek - label_agenda_item_convert_to_work_package: Convert to work package + label_agenda_item_convert_to_work_package: Zkonvertovat na pracovní balíček label_agenda_item_work_package_add: Přidat pracovní balíček label_agenda_item_work_package: Pracovní balíček k bodu programu label_section_rename: Přejmenovat sekci label_agenda_outcome: Výsledek label_agenda_new_outcome: Nový výsledek - label_agenda_outcome_actions: Agenda outcome actions + label_agenda_outcome_actions: Výsledné akce programu label_agenda_outcome_edit: Upravit výsledek label_agenda_outcome_delete: Odstranit výsledek - label_added_as_outcome: Added as outcome - label_write_outcome: Write outcome + label_added_as_outcome: Přidáno jako výsledek + label_write_outcome: Napište výsledek label_existing_work_package: Stávající pracovní balíček text_outcome_not_editable_anymore: Tento výsledek již nelze upravovat. text_outcome_cannot_be_added: Výsledek již nelze přidat. @@ -693,9 +693,9 @@ cs: text_exit_draft_mode_dialog_template_title: Otevřít první výskyt této série schůzek? text_exit_draft_mode_dialog_template_subtitle: Poté se již nelze vrátit do režimu návrhu. label_meeting_template_sharing: Sdílení - label_meeting_template_sharing_none: Only with this project - label_meeting_template_sharing_descendants: With subprojects - label_meeting_template_sharing_system: With all projects + label_meeting_template_sharing_none: Pouze s tímto projektem + label_meeting_template_sharing_descendants: S podprojekty + label_meeting_template_sharing_system: Se všemi projekty text_meeting_template_sharing_description: Tuto šablonu lze sdílet s podprojekty nebo jinými projekty v této instanci. Budou zkopírovány pouze body a přílohy pořadu jednání. text_meeting_not_editable_anymore: Tato schůzka již není upravitelná. text_meeting_not_present_anymore: Tato schůzka byla odstraněna. Vyberte prosím jinou schůzku. @@ -715,7 +715,7 @@ cs: text_agenda_item_duplicated_in_next_meeting: Agenda item duplicated in the next meeting, on %{date} text_work_package_has_no_upcoming_meeting_agenda_items: Tento pracovní balíček ještě není naplánován na nadcházející program schůzky. text_agenda_item_no_available_occurrence: No upcoming occurrences are available. - text_agenda_item_dialog_skipping_note: 'Note: Skipping %{details}.' + text_agenda_item_dialog_skipping_note: 'Poznámka: Přeskočení %{details}.' text_agenda_item_dialog_skipping_cancelled_one: cancelled meeting on %{date} text_agenda_item_dialog_skipping_cancelled_many: "%{count} cancelled meetings" text_agenda_item_dialog_skipping_closed_one: closed meeting on %{date} @@ -738,9 +738,9 @@ cs: access_token: dialog: token/ical_meeting: - dialog_title: New iCal subscription token for meetings + dialog_title: Nový token pro přihlášení k odběru iCal dialog_body: This token will generate an iCal subscription URL that lets you view all your meetings in an external calendar application. - create_button: Create subscription + create_button: Vytvořit odběr name_label: Název tokenu name_caption: You can name it after where you will use it, such as "My phone" or "Work computer". created_dialog: diff --git a/modules/meeting/config/locales/crowdin/de.yml b/modules/meeting/config/locales/crowdin/de.yml index 122a4c65e5b..5b14bf546c8 100644 --- a/modules/meeting/config/locales/crowdin/de.yml +++ b/modules/meeting/config/locales/crowdin/de.yml @@ -374,8 +374,8 @@ de: caption: Dieser Text wird auf jeder Seite in der Mitte der Fußzeile angezeigt. submit_button: Download notifications: - disabled: Participants will not receive email updates informing them of changes to the date, time or list of participants. - enabled: All participants will receive updated calendar invites informing them of changes to date, time or list of participants. + disabled: Die Teilnehmenden erhalten keine E-Mail, die sie über Änderungen des Datums, der Uhrzeit oder der Teilnehmer der Besprechung informiert. + enabled: Alle Teilnehmer erhalten aktualisierte Kalendereinladungen, die sie über Änderungen von Datum, Uhrzeit oder Teilnehmerliste informieren. sidepanel: title: E-Mail-Kalender-Aktualisierungen description: @@ -385,8 +385,8 @@ de: enable: E-Mail-Kalender-Aktualisierungen aktivieren? disable: E-Mail-Kalender-Aktualisierungen deaktivieren? message: - enable: Once enabled, an email will be sent out immediately to all participants. - disable: If they already had an invite for this meeting, it might no longer be accurate. + enable: Nach der Aktivierung wird sofort eine E-Mail an alle Teilnehmer verschickt. + disable: Wenn sie bereits eine Einladung für dieses Treffen hatten, ist diese möglicherweise nicht mehr korrekt. confirm_label: enable: E-Mail-Aktualisierungen aktivieren disable: E-Mail-Aktualisierungen deaktivieren @@ -492,8 +492,8 @@ de: weekly_interval: Alle %{interval} Wochen am %{weekday} monthly_day: Jeden Monat am %{day} monthly_day_interval: Alle %{interval} Monate am %{day} - monthly_nth_weekday: Every month on the %{ordinal} %{weekday} - monthly_nth_weekday_interval: Every %{interval} months on the %{ordinal} %{weekday} + monthly_nth_weekday: Jeden Monat am %{ordinal} %{weekday} + monthly_nth_weekday_interval: Alle %{interval} Monate am %{ordinal} %{weekday} frequency: "%{base} um %{time}" full: "%{base} um %{time}, endet %{end_date}" full_past: "%{base} um %{time}, endet am %{end_date}" @@ -602,7 +602,7 @@ de: label_agenda_item_duplicate_in_next_title: In die nächste Besprechung duplizieren? label_agenda_item_add_notes: Notiz hinzufügen label_agenda_item_add_outcome: Ergebnis hinzufügen - label_agenda_item_convert_to_work_package: Convert to work package + label_agenda_item_convert_to_work_package: In Arbeitspaket umwandeln label_agenda_item_work_package_add: Arbeitspaket hinzufügen label_agenda_item_work_package: Tagesordnungspunkt Arbeitspaket label_section_rename: Abschnitt umbenennen diff --git a/modules/meeting/config/routes.rb b/modules/meeting/config/routes.rb index acb0be0aeea..526fe05f80e 100644 --- a/modules/meeting/config/routes.rb +++ b/modules/meeting/config/routes.rb @@ -47,6 +47,7 @@ Rails.application.routes.draw do get "menu" => "meetings/menus#show" get :fetch_timezone get :fetch_templates + get :project_items get "ical/:token", controller: "meetings/ical", action: :index, as: "ical_feed" diff --git a/modules/meeting/lib/api/v3/meeting_agenda_items/agenda_items_by_meeting_api.rb b/modules/meeting/lib/api/v3/meeting_agenda_items/agenda_items_by_meeting_api.rb index c9b1f484bc5..5fc7f2dcb1a 100644 --- a/modules/meeting/lib/api/v3/meeting_agenda_items/agenda_items_by_meeting_api.rb +++ b/modules/meeting/lib/api/v3/meeting_agenda_items/agenda_items_by_meeting_api.rb @@ -36,17 +36,10 @@ module API get do items = @meeting.agenda_items.includes(:author, :presenter, :work_package, :meeting_section) MeetingAgendaItemCollectionRepresenter.new(items, - self_link: api_v3_paths.meeting_agenda_items(@meeting.id), + self_link: api_v3_paths.meeting_agenda_items(meeting_id: @meeting.id), current_user:) end - post(&::API::V3::Utilities::Endpoints::Create - .new(model: MeetingAgendaItem, - params_modifier: ->(params) { - params.except(:meeting, :meeting_id).merge(meeting: @meeting) - }) - .mount) - route_param :agenda_item_id, type: Integer, desc: "Agenda item ID" do after_validation do @meeting_agenda_item = @meeting.agenda_items.find(declared_params[:agenda_item_id]) @@ -54,10 +47,6 @@ module API get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingAgendaItem).mount - patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingAgendaItem).mount - - delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingAgendaItem).mount - mount ::API::V3::MeetingOutcomes::OutcomesByAgendaItemAPI end end diff --git a/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_item_representer.rb b/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_item_representer.rb index 16d41286ba6..9a23182b7ab 100644 --- a/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_item_representer.rb +++ b/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_item_representer.rb @@ -42,8 +42,7 @@ module API { outcomes: %i[author work_package] } ] - self_link id_attribute: ->(*) { [represented.meeting_id, represented.id] }, - title_getter: ->(*) { represented.title } + self_link title_getter: ->(*) { represented.title } property :id @@ -88,7 +87,7 @@ module API next if represented.meeting_section_id.nil? { - href: api_v3_paths.meeting_section(represented.meeting_id, represented.meeting_section_id), + href: api_v3_paths.meeting_section(represented.meeting_section_id), title: represented.meeting_section&.title } } @@ -102,8 +101,7 @@ module API link: ->(*) { represented.outcomes.map do |outcome| { - href: api_v3_paths - .meeting_agenda_item_outcome(represented.meeting_id, represented.id, outcome.id), + href: api_v3_paths.meeting_outcome(outcome.id), title: outcome.id.to_s } end diff --git a/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_items_api.rb b/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_items_api.rb new file mode 100644 index 00000000000..a1936b3c0a6 --- /dev/null +++ b/modules/meeting/lib/api/v3/meeting_agenda_items/meeting_agenda_items_api.rb @@ -0,0 +1,56 @@ +# 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 API + module V3 + module MeetingAgendaItems + class MeetingAgendaItemsAPI < ::API::OpenProjectAPI + resources :meeting_agenda_items do + post &::API::V3::Utilities::Endpoints::Create.new(model: MeetingAgendaItem).mount + + route_param :id, type: Integer, desc: "Agenda item ID" do + after_validation do + @meeting_agenda_item = MeetingAgendaItem + .joins(meeting: :project) + .merge(Meeting.visible) + .find(declared_params[:id]) + end + + get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingAgendaItem).mount + + patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingAgendaItem).mount + + delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingAgendaItem).mount + end + end + end + end + end +end diff --git a/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcome_representer.rb b/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcome_representer.rb index 153353f19fe..dac02c36edb 100644 --- a/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcome_representer.rb +++ b/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcome_representer.rb @@ -39,10 +39,7 @@ module API self.to_eager_load = [{ meeting_agenda_item: :meeting }, :author, :work_package] - self_link path: :meeting_agenda_item_outcome, - id_attribute: ->(*) { - [represented.meeting_agenda_item.meeting_id, represented.meeting_agenda_item_id, represented.id] - }, + self_link path: :meeting_outcome, title_getter: ->(*) { represented.id.to_s } property :id @@ -56,13 +53,16 @@ module API representer: ::API::V3::Users::UserRepresenter, skip_render: ->(*) { represented.author_id.nil? } - link :agendaItem do - { - href: api_v3_paths.meeting_agenda_item(represented.meeting_agenda_item.meeting_id, - represented.meeting_agenda_item_id), - title: represented.meeting_agenda_item.title - } - end + associated_resource :meeting_agenda_item, + as: :agendaItem, + link: ->(*) { + next if represented.meeting_agenda_item_id.nil? + + { + href: api_v3_paths.meeting_agenda_item(represented.meeting_agenda_item_id), + title: represented.meeting_agenda_item.title + } + } associated_visible_resource :work_package diff --git a/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcomes_api.rb b/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcomes_api.rb new file mode 100644 index 00000000000..8101c85217f --- /dev/null +++ b/modules/meeting/lib/api/v3/meeting_outcomes/meeting_outcomes_api.rb @@ -0,0 +1,56 @@ +# 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 API + module V3 + module MeetingOutcomes + class MeetingOutcomesAPI < ::API::OpenProjectAPI + resources :meeting_outcomes do + post &::API::V3::Utilities::Endpoints::Create.new(model: MeetingOutcome).mount + + route_param :id, type: Integer, desc: "Outcome ID" do + after_validation do + @meeting_outcome = MeetingOutcome + .joins(meeting_agenda_item: { meeting: :project }) + .merge(Meeting.visible) + .find(declared_params[:id]) + end + + get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingOutcome).mount + + patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingOutcome).mount + + delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingOutcome).mount + end + end + end + end + end +end diff --git a/modules/meeting/lib/api/v3/meeting_outcomes/outcomes_by_agenda_item_api.rb b/modules/meeting/lib/api/v3/meeting_outcomes/outcomes_by_agenda_item_api.rb index 9ab379fad82..298e54d3421 100644 --- a/modules/meeting/lib/api/v3/meeting_outcomes/outcomes_by_agenda_item_api.rb +++ b/modules/meeting/lib/api/v3/meeting_outcomes/outcomes_by_agenda_item_api.rb @@ -38,29 +38,17 @@ module API MeetingOutcomeCollectionRepresenter.new(outcomes, self_link: api_v3_paths - .meeting_agenda_item_outcomes(@meeting.id, @meeting_agenda_item.id), + .meeting_agenda_item_outcomes(@meeting_agenda_item.id, + meeting_id: @meeting.id), current_user:) end - post(&::API::V3::Utilities::Endpoints::Create - .new(model: MeetingOutcome, - params_modifier: ->(params) { - params - .except(:meeting_agenda_item, :meeting_agenda_item_id) - .merge(meeting_agenda_item: @meeting_agenda_item) - }) - .mount) - route_param :outcome_id, type: Integer, desc: "Outcome ID" do after_validation do @meeting_outcome = @meeting_agenda_item.outcomes.find(declared_params[:outcome_id]) end get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingOutcome).mount - - patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingOutcome).mount - - delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingOutcome).mount end end end diff --git a/modules/meeting/lib/api/v3/meeting_sections/meeting_section_representer.rb b/modules/meeting/lib/api/v3/meeting_sections/meeting_section_representer.rb index 79b6c768f62..3ffef01b4fe 100644 --- a/modules/meeting/lib/api/v3/meeting_sections/meeting_section_representer.rb +++ b/modules/meeting/lib/api/v3/meeting_sections/meeting_section_representer.rb @@ -38,8 +38,7 @@ module API self.to_eager_load = [:meeting] - self_link id_attribute: ->(*) { [represented.meeting_id, represented.id] }, - title_getter: ->(*) { represented.title } + self_link title_getter: ->(*) { represented.title } property :id diff --git a/modules/meeting/lib/api/v3/meeting_sections/meeting_sections_api.rb b/modules/meeting/lib/api/v3/meeting_sections/meeting_sections_api.rb new file mode 100644 index 00000000000..4434c35ea40 --- /dev/null +++ b/modules/meeting/lib/api/v3/meeting_sections/meeting_sections_api.rb @@ -0,0 +1,56 @@ +# 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 API + module V3 + module MeetingSections + class MeetingSectionsAPI < ::API::OpenProjectAPI + resources :meeting_sections do + post &::API::V3::Utilities::Endpoints::Create.new(model: MeetingSection).mount + + route_param :id, type: Integer, desc: "Section ID" do + after_validation do + @meeting_section = MeetingSection + .joins(meeting: :project) + .merge(Meeting.visible) + .find(declared_params[:id]) + end + + get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingSection).mount + + patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingSection).mount + + delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingSection).mount + end + end + end + end + end +end diff --git a/modules/meeting/lib/api/v3/meeting_sections/sections_by_meeting_api.rb b/modules/meeting/lib/api/v3/meeting_sections/sections_by_meeting_api.rb index efe1479a4d6..ace20bb5f02 100644 --- a/modules/meeting/lib/api/v3/meeting_sections/sections_by_meeting_api.rb +++ b/modules/meeting/lib/api/v3/meeting_sections/sections_by_meeting_api.rb @@ -36,27 +36,16 @@ module API get do sections = @meeting.sections MeetingSectionCollectionRepresenter.new(sections, - self_link: api_v3_paths.meeting_sections(@meeting.id), + self_link: api_v3_paths.meeting_sections(meeting_id: @meeting.id), current_user:) end - post(&::API::V3::Utilities::Endpoints::Create - .new(model: MeetingSection, - params_modifier: ->(params) { - params.except(:meeting, :meeting_id).merge(meeting: @meeting) - }) - .mount) - route_param :section_id, type: Integer, desc: "Section ID" do after_validation do @meeting_section = @meeting.sections.find(declared_params[:section_id]) end get &::API::V3::Utilities::Endpoints::Show.new(model: MeetingSection).mount - - patch &::API::V3::Utilities::Endpoints::Update.new(model: MeetingSection).mount - - delete &::API::V3::Utilities::Endpoints::Delete.new(model: MeetingSection).mount end end end diff --git a/modules/meeting/lib/api/v3/meetings/meeting_representer.rb b/modules/meeting/lib/api/v3/meetings/meeting_representer.rb index 11cc02bb724..793490a5a01 100644 --- a/modules/meeting/lib/api/v3/meetings/meeting_representer.rb +++ b/modules/meeting/lib/api/v3/meetings/meeting_representer.rb @@ -76,13 +76,13 @@ module API link :agendaItems do { - href: api_v3_paths.meeting_agenda_items(represented.id) + href: api_v3_paths.meeting_agenda_items(meeting_id: represented.id) } end link :sections do { - href: api_v3_paths.meeting_sections(represented.id) + href: api_v3_paths.meeting_sections(meeting_id: represented.id) } end diff --git a/modules/meeting/lib/api/v3/meetings/meetings_api.rb b/modules/meeting/lib/api/v3/meetings/meetings_api.rb index 34e793394d3..d339b4cc684 100644 --- a/modules/meeting/lib/api/v3/meetings/meetings_api.rb +++ b/modules/meeting/lib/api/v3/meetings/meetings_api.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + #-- copyright # OpenProject is an open source project management software. # Copyright (C) the OpenProject GmbH @@ -58,6 +59,10 @@ module API mount ::API::V3::MeetingSections::SectionsByMeetingAPI end end + + mount ::API::V3::MeetingAgendaItems::MeetingAgendaItemsAPI + mount ::API::V3::MeetingSections::MeetingSectionsAPI + mount ::API::V3::MeetingOutcomes::MeetingOutcomesAPI end end end diff --git a/modules/meeting/lib/open_project/meeting/engine.rb b/modules/meeting/lib/open_project/meeting/engine.rb index c7894770d41..c1f7b107581 100644 --- a/modules/meeting/lib/open_project/meeting/engine.rb +++ b/modules/meeting/lib/open_project/meeting/engine.rb @@ -44,7 +44,7 @@ module OpenProject::Meeting permission :view_meetings, { meetings: %i[index show check_for_updates download_ics - presentation generate_pdf_dialog history], + presentation generate_pdf_dialog history project_items], "meetings/filters": %i[show], "meetings/menus": %i[show], work_package_meetings_tab: %i[index count], @@ -241,28 +241,52 @@ module OpenProject::Meeting "#{root}/meetings/#{id}/form" end - add_api_path :meeting_agenda_items do |meeting_id| - "#{meeting(meeting_id)}/agenda_items" + add_api_path :meeting_agenda_items do |meeting_id: nil| + if meeting_id + "#{meeting(meeting_id)}/agenda_items" + else + "#{root}/meeting_agenda_items" + end end - add_api_path :meeting_agenda_item do |meeting_id, id| - "#{meeting(meeting_id)}/agenda_items/#{id}" + add_api_path :meeting_agenda_item do |id, meeting_id: nil| + if meeting_id + "#{meeting(meeting_id)}/agenda_items/#{id}" + else + "#{root}/meeting_agenda_items/#{id}" + end end - add_api_path :meeting_agenda_item_outcomes do |meeting_id, agenda_item_id| - "#{meeting_agenda_item(meeting_id, agenda_item_id)}/outcomes" + add_api_path :meeting_agenda_item_outcomes do |agenda_item_id, meeting_id: nil| + "#{meeting_agenda_item(agenda_item_id, meeting_id:)}/outcomes" end - add_api_path :meeting_agenda_item_outcome do |meeting_id, agenda_item_id, id| - "#{meeting_agenda_item_outcomes(meeting_id, agenda_item_id)}/#{id}" + add_api_path :meeting_outcomes do + "#{root}/meeting_outcomes" end - add_api_path :meeting_sections do |meeting_id| - "#{meeting(meeting_id)}/sections" + add_api_path :meeting_outcome do |id| + "#{root}/meeting_outcomes/#{id}" end - add_api_path :meeting_section do |meeting_id, id| - "#{meeting(meeting_id)}/sections/#{id}" + add_api_path :meeting_agenda_item_outcome do |id, agenda_item_id:, meeting_id: nil| + "#{meeting_agenda_item_outcomes(agenda_item_id, meeting_id:)}/#{id}" + end + + add_api_path :meeting_sections do |meeting_id: nil| + if meeting_id + "#{meeting(meeting_id)}/sections" + else + "#{root}/meeting_sections" + end + end + + add_api_path :meeting_section do |id, meeting_id: nil| + if meeting_id + "#{meeting(meeting_id)}/sections/#{id}" + else + "#{root}/meeting_sections/#{id}" + end end add_api_path :recurring_meetings do diff --git a/modules/meeting/spec/contracts/meeting_sections/create_contract_spec.rb b/modules/meeting/spec/contracts/meeting_sections/create_contract_spec.rb index e088c011516..31465356c6e 100644 --- a/modules/meeting/spec/contracts/meeting_sections/create_contract_spec.rb +++ b/modules/meeting/spec/contracts/meeting_sections/create_contract_spec.rb @@ -35,6 +35,7 @@ RSpec.describe MeetingSections::CreateContract do include_context "ModelContract shared context" shared_let(:project) { create(:project) } + shared_let(:other_project) { create(:project) } let(:meeting) { create(:meeting, project:) } let(:section) { build(:meeting_section, meeting:) } let(:contract) { described_class.new(section, user) } @@ -79,6 +80,14 @@ RSpec.describe MeetingSections::CreateContract do it_behaves_like "contract is invalid", base: :does_not_exist end + context "with permission in another project" do + let(:user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it_behaves_like "contract is invalid", base: :does_not_exist + end + include_examples "contract reuses the model errors" do let(:user) { build_stubbed(:user) } end diff --git a/modules/meeting/spec/contracts/meeting_sections/delete_contract_spec.rb b/modules/meeting/spec/contracts/meeting_sections/delete_contract_spec.rb index dfdcbcefa74..3f25dc9ed4a 100644 --- a/modules/meeting/spec/contracts/meeting_sections/delete_contract_spec.rb +++ b/modules/meeting/spec/contracts/meeting_sections/delete_contract_spec.rb @@ -35,6 +35,7 @@ RSpec.describe MeetingSections::DeleteContract do include_context "ModelContract shared context" shared_let(:project) { create(:project) } + shared_let(:other_project) { create(:project) } shared_let(:meeting) { create(:meeting, project:) } let(:section) { create(:meeting_section, meeting:) } let(:contract) { described_class.new(section, user) } @@ -69,6 +70,14 @@ RSpec.describe MeetingSections::DeleteContract do it_behaves_like "contract is invalid", base: :error_unauthorized end + context "with permission in another project" do + let(:user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it_behaves_like "contract is invalid", base: :error_unauthorized + end + include_examples "contract reuses the model errors" do let(:user) { build_stubbed(:user) } end diff --git a/modules/meeting/spec/contracts/meeting_sections/update_contract_spec.rb b/modules/meeting/spec/contracts/meeting_sections/update_contract_spec.rb index 84a3653fbea..a68ebe145bb 100644 --- a/modules/meeting/spec/contracts/meeting_sections/update_contract_spec.rb +++ b/modules/meeting/spec/contracts/meeting_sections/update_contract_spec.rb @@ -35,6 +35,7 @@ RSpec.describe MeetingSections::UpdateContract do include_context "ModelContract shared context" shared_let(:project) { create(:project) } + shared_let(:other_project) { create(:project) } shared_let(:meeting) { create(:meeting, project:) } shared_let(:section) { create(:meeting_section, meeting:) } let(:contract) { described_class.new(section, user) } @@ -61,6 +62,14 @@ RSpec.describe MeetingSections::UpdateContract do it_behaves_like "contract is invalid", base: :error_unauthorized end + context "with permission in another project" do + let(:user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it_behaves_like "contract is invalid", base: :error_unauthorized + end + include_examples "contract reuses the model errors" do let(:user) { build_stubbed(:user) } end diff --git a/modules/meeting/spec/features/meetings_index_spec.rb b/modules/meeting/spec/features/meetings_index_spec.rb index e77e38eeed2..da6e4fe85d2 100644 --- a/modules/meeting/spec/features/meetings_index_spec.rb +++ b/modules/meeting/spec/features/meetings_index_spec.rb @@ -374,6 +374,24 @@ RSpec.describe "Meetings", "Index", :js do end end + context 'with the "Project" quick filter' do + before do + meetings_page.visit! + meetings_page.set_sidebar_filter "All meetings" + end + + it "shows only meetings from the selected projects" do + meetings_page.set_project_filter(project) + + meetings_page.expect_meetings_listed(meeting, tomorrows_meeting) + meetings_page.expect_meetings_not_listed(other_project_meeting) + + meetings_page.set_project_filter(project, other_project) + + meetings_page.expect_meetings_listed(meeting, tomorrows_meeting, other_project_meeting) + end + end + include_examples "sidebar filtering", context: :global end @@ -407,6 +425,11 @@ RSpec.describe "Meetings", "Index", :js do end end + it 'does not show the "Project" quick filter' do + meetings_page.visit! + expect(page).to have_no_button I18n.t(:label_project), exact: true + end + include_examples "sidebar filtering", context: :project specify "with 1 meeting listed" do diff --git a/modules/meeting/spec/requests/api/v3/meeting_agenda_items/agenda_items_by_meeting_resource_spec.rb b/modules/meeting/spec/requests/api/v3/meeting_agenda_items/agenda_items_by_meeting_resource_spec.rb index 5d5bdb39574..c040a31a1ed 100644 --- a/modules/meeting/spec/requests/api/v3/meeting_agenda_items/agenda_items_by_meeting_resource_spec.rb +++ b/modules/meeting/spec/requests/api/v3/meeting_agenda_items/agenda_items_by_meeting_resource_spec.rb @@ -51,7 +51,7 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d end describe "GET /api/v3/meetings/:meeting_id/agenda_items" do - let(:path) { api_v3_paths.meeting_agenda_items(meeting.id) } + let(:path) { api_v3_paths.meeting_agenda_items(meeting_id: meeting.id) } before { get path } @@ -69,6 +69,18 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d expect(last_response.body) .to have_json_size(1) .at_path("_embedded/elements/0/_embedded/outcomes") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_outcome(outcome.id).to_json) + .at_path("_embedded/elements/0/_links/outcomes/0/href") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_agenda_item(agenda_item.id).to_json) + .at_path("_embedded/elements/0/_links/self/href") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_section(section.id).to_json) + .at_path("_embedded/elements/0/_links/section/href") end context "without view_meetings permission" do @@ -80,11 +92,16 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d end end - describe "POST /api/v3/meetings/:meeting_id/agenda_items" do - let(:path) { api_v3_paths.meeting_agenda_items(meeting.id) } + describe "POST /api/v3/meeting_agenda_items" do + let(:path) { api_v3_paths.meeting_agenda_items } let(:body) do { - title: "New agenda item" + title: "New agenda item", + _links: { + meeting: { + href: api_v3_paths.meeting(meeting.id) + } + } }.to_json end @@ -109,6 +126,44 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d .at_path("title") end + context "with a section href returned by the section collection" do + let!(:target_section) { create(:meeting_section, meeting:) } + let(:target_section_href) do + get api_v3_paths.meeting_sections(meeting_id: meeting.id) + + JSON + .parse(last_response.body) + .dig("_embedded", "elements") + .find { |item| item["id"] == target_section.id } + .dig("_links", "self", "href") + end + let(:body) do + { + title: "New agenda item in target section", + _links: { + meeting: { + href: api_v3_paths.meeting(meeting.id) + }, + section: { + href: target_section_href + } + } + }.to_json + end + + it "responds with 201" do + expect(target_section_href).to eq(api_v3_paths.meeting_section(target_section.id)) + expect(response).to have_http_status(:created) + end + + it "creates the agenda item in that section" do + response + + expect(meeting.agenda_items.find_by(title: "New agenda item in target section").meeting_section) + .to eq(target_section) + end + end + context "without manage_agendas permission" do let(:permissions) { %i[view_meetings] } @@ -119,7 +174,7 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d end describe "GET /api/v3/meetings/:meeting_id/agenda_items/:id" do - let(:path) { api_v3_paths.meeting_agenda_item(meeting.id, agenda_item.id) } + let(:path) { api_v3_paths.meeting_agenda_item(agenda_item.id, meeting_id: meeting.id) } before { get path } @@ -141,7 +196,7 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d context "with an item from another meeting" do let(:other_meeting) { create(:meeting, project:, author: current_user) } - let(:path) { api_v3_paths.meeting_agenda_item(other_meeting.id, agenda_item.id) } + let(:path) { api_v3_paths.meeting_agenda_item(agenda_item.id, meeting_id: other_meeting.id) } it "returns 404" do expect(last_response).to have_http_status(:not_found) @@ -155,7 +210,7 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d create(:wp_meeting_agenda_item, meeting:, meeting_section: section, work_package: private_work_package, author: current_user) end - let(:path) { api_v3_paths.meeting_agenda_item(meeting.id, wp_agenda_item.id) } + let(:path) { api_v3_paths.meeting_agenda_item(wp_agenda_item.id, meeting_id: meeting.id) } it "returns 200" do expect(last_response).to have_http_status(:ok) @@ -173,8 +228,34 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d end end - describe "PATCH /api/v3/meetings/:meeting_id/agenda_items/:id" do - let(:path) { api_v3_paths.meeting_agenda_item(meeting.id, agenda_item.id) } + describe "GET /api/v3/meeting_agenda_items/:id" do + let(:path) { api_v3_paths.meeting_agenda_item(agenda_item.id) } + + before { get path } + + it "returns 200 and the agenda item" do + expect(last_response).to have_http_status(:ok) + + expect(last_response.body) + .to be_json_eql("MeetingAgendaItem".to_json) + .at_path("_type") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_agenda_item(agenda_item.id).to_json) + .at_path("_links/self/href") + end + + context "without view_meetings permission" do + let(:permissions) { [] } + + it "returns 404" do + expect(last_response).to have_http_status(:not_found) + end + end + end + + describe "PATCH /api/v3/meeting_agenda_items/:id" do + let(:path) { api_v3_paths.meeting_agenda_item(agenda_item.id) } let(:body) do { title: "Updated title", @@ -193,6 +274,42 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d expect(agenda_item.reload.title).to eq("Updated title") end + context "with a section href returned by the agenda item collection" do + let(:target_section) { create(:meeting_section, meeting:) } + let!(:target_agenda_item) do + create(:meeting_agenda_item, meeting:, meeting_section: target_section, author: current_user) + end + let(:target_section_href) do + get api_v3_paths.meeting_agenda_items(meeting_id: meeting.id) + + JSON + .parse(last_response.body) + .dig("_embedded", "elements") + .find { |item| item["id"] == target_agenda_item.id } + .dig("_links", "section", "href") + end + let(:body) do + { + lockVersion: agenda_item.lock_version, + _links: { + section: { + href: target_section_href + } + } + }.to_json + end + + it "responds with 200" do + expect(target_section_href).to eq(api_v3_paths.meeting_section(target_section.id)) + expect(response).to have_http_status(:ok) + end + + it "moves the agenda item to that section" do + response + expect(agenda_item.reload.meeting_section).to eq(target_section) + end + end + context "without manage_agendas permission" do let(:permissions) { %i[view_meetings] } @@ -202,8 +319,8 @@ RSpec.describe "API v3 Meeting Agenda Items sub-resource", content_type: :json d end end - describe "DELETE /api/v3/meetings/:meeting_id/agenda_items/:id" do - let(:path) { api_v3_paths.meeting_agenda_item(meeting.id, agenda_item.id) } + describe "DELETE /api/v3/meeting_agenda_items/:id" do + let(:path) { api_v3_paths.meeting_agenda_item(agenda_item.id) } before { delete path } diff --git a/modules/meeting/spec/requests/api/v3/meeting_outcomes/outcomes_by_agenda_item_resource_spec.rb b/modules/meeting/spec/requests/api/v3/meeting_outcomes/outcomes_by_agenda_item_resource_spec.rb index dc0b3d6419a..5dfc4be0954 100644 --- a/modules/meeting/spec/requests/api/v3/meeting_outcomes/outcomes_by_agenda_item_resource_spec.rb +++ b/modules/meeting/spec/requests/api/v3/meeting_outcomes/outcomes_by_agenda_item_resource_spec.rb @@ -51,7 +51,7 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do end describe "GET /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id/outcomes" do - let(:path) { api_v3_paths.meeting_agenda_item_outcomes(meeting.id, agenda_item.id) } + let(:path) { api_v3_paths.meeting_agenda_item_outcomes(agenda_item.id, meeting_id: meeting.id) } before { get path } @@ -65,11 +65,19 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do expect(last_response.body) .to have_json_size(1) .at_path("_embedded/elements") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_outcome(outcome.id).to_json) + .at_path("_embedded/elements/0/_links/self/href") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_agenda_item(agenda_item.id).to_json) + .at_path("_embedded/elements/0/_links/agendaItem/href") end context "with an agenda item from another meeting" do let(:other_meeting) { create(:meeting, project:, author: current_user) } - let(:path) { api_v3_paths.meeting_agenda_item_outcomes(other_meeting.id, agenda_item.id) } + let(:path) { api_v3_paths.meeting_agenda_item_outcomes(agenda_item.id, meeting_id: other_meeting.id) } it "returns 404" do expect(last_response).to have_http_status(:not_found) @@ -108,12 +116,17 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do end end - describe "POST /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id/outcomes" do - let(:path) { api_v3_paths.meeting_agenda_item_outcomes(meeting.id, agenda_item.id) } + describe "POST /api/v3/meeting_outcomes" do + let(:path) { api_v3_paths.meeting_outcomes } let(:body) do { kind: "information", - notes: { raw: "Outcome created via API" } + notes: { raw: "Outcome created via API" }, + _links: { + agendaItem: { + href: api_v3_paths.meeting_agenda_item(agenda_item.id) + } + } }.to_json end @@ -153,6 +166,9 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do { kind: "work_package", _links: { + agendaItem: { + href: api_v3_paths.meeting_agenda_item(agenda_item.id) + }, workPackage: { href: api_v3_paths.work_package(work_package.id) } @@ -182,6 +198,9 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do { kind: "work_package", _links: { + agendaItem: { + href: api_v3_paths.meeting_agenda_item(agenda_item.id) + }, workPackage: { href: api_v3_paths.work_package(private_work_package.id) } @@ -197,7 +216,11 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do end describe "GET /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id/outcomes/:id" do - let(:path) { api_v3_paths.meeting_agenda_item_outcome(meeting.id, agenda_item.id, outcome.id) } + let(:path) do + api_v3_paths.meeting_agenda_item_outcome(outcome.id, + agenda_item_id: agenda_item.id, + meeting_id: meeting.id) + end before { get path } @@ -211,11 +234,19 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do expect(last_response.body) .to be_json_eql(outcome.id.to_json) .at_path("id") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_outcome(outcome.id).to_json) + .at_path("_links/self/href") end context "with an outcome from another agenda item" do let(:other_agenda_item) { create(:meeting_agenda_item, meeting:, meeting_section: section, author: current_user) } - let(:path) { api_v3_paths.meeting_agenda_item_outcome(meeting.id, other_agenda_item.id, outcome.id) } + let(:path) do + api_v3_paths.meeting_agenda_item_outcome(outcome.id, + agenda_item_id: other_agenda_item.id, + meeting_id: meeting.id) + end it "returns 404" do expect(last_response).to have_http_status(:not_found) @@ -242,13 +273,38 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do .at_path("_links/workPackage/href") expect(last_response.body).not_to have_json_path("_embedded/workPackage") - end end end - describe "PATCH /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id/outcomes/:id" do - let(:path) { api_v3_paths.meeting_agenda_item_outcome(meeting.id, agenda_item.id, outcome.id) } + describe "GET /api/v3/meeting_outcomes/:id" do + let(:path) { api_v3_paths.meeting_outcome(outcome.id) } + + before { get path } + + it "returns 200 and the outcome" do + expect(last_response).to have_http_status(:ok) + + expect(last_response.body) + .to be_json_eql("MeetingOutcome".to_json) + .at_path("_type") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_outcome(outcome.id).to_json) + .at_path("_links/self/href") + end + + context "without view_meetings permission" do + let(:permissions) { [] } + + it "returns 404" do + expect(last_response).to have_http_status(:not_found) + end + end + end + + describe "PATCH /api/v3/meeting_outcomes/:id" do + let(:path) { api_v3_paths.meeting_outcome(outcome.id) } let(:body) do { notes: { raw: "Updated outcome" } @@ -271,8 +327,8 @@ RSpec.describe "API v3 Meeting Outcomes sub-resource", content_type: :json do end end - describe "DELETE /api/v3/meetings/:meeting_id/agenda_items/:agenda_item_id/outcomes/:id" do - let(:path) { api_v3_paths.meeting_agenda_item_outcome(meeting.id, agenda_item.id, outcome.id) } + describe "DELETE /api/v3/meeting_outcomes/:id" do + let(:path) { api_v3_paths.meeting_outcome(outcome.id) } before { delete path } diff --git a/modules/meeting/spec/requests/api/v3/meeting_sections/sections_by_meeting_resource_spec.rb b/modules/meeting/spec/requests/api/v3/meeting_sections/sections_by_meeting_resource_spec.rb index 17782fcc872..3cdac775747 100644 --- a/modules/meeting/spec/requests/api/v3/meeting_sections/sections_by_meeting_resource_spec.rb +++ b/modules/meeting/spec/requests/api/v3/meeting_sections/sections_by_meeting_resource_spec.rb @@ -36,20 +36,42 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do include API::V3::Utilities::PathHelper shared_let(:project) { create(:project, enabled_module_names: %w[meetings]) } + shared_let(:other_project) { create(:project, enabled_module_names: %w[meetings]) } + shared_let(:author) { create(:user) } let(:permissions) { %i[view_meetings manage_agendas] } let(:current_user) do create(:user, member_with_permissions: { project => permissions }) end - let(:meeting) { create(:meeting, project:, author: current_user) } + let(:meeting) { create(:meeting, project:, author:) } let!(:section) { create(:meeting_section, meeting:, title: "First Section") } before do login_as current_user end + shared_examples "not found without meeting visibility" do + context "without view_meetings permission" do + let(:permissions) { [] } + + it "returns 404" do + expect(last_response).to have_http_status(:not_found) + end + end + + context "with view_meetings permission in another project" do + let(:current_user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it "returns 404" do + expect(last_response).to have_http_status(:not_found) + end + end + end + describe "GET /api/v3/meetings/:meeting_id/sections" do - let(:path) { api_v3_paths.meeting_sections(meeting.id) } + let(:path) { api_v3_paths.meeting_sections(meeting_id: meeting.id) } before { get path } @@ -59,22 +81,25 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do expect(last_response.body) .to be_json_eql("Collection".to_json) .at_path("_type") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_section(section.id).to_json) + .at_path("_embedded/elements/0/_links/self/href") end - context "without view_meetings permission" do - let(:permissions) { [] } - - it "returns 404" do - expect(last_response).to have_http_status(:not_found) - end - end + it_behaves_like "not found without meeting visibility" end - describe "POST /api/v3/meetings/:meeting_id/sections" do - let(:path) { api_v3_paths.meeting_sections(meeting.id) } + describe "POST /api/v3/meeting_sections" do + let(:path) { api_v3_paths.meeting_sections } let(:body) do { - title: "New Section" + title: "New Section", + _links: { + meeting: { + href: api_v3_paths.meeting(meeting.id) + } + } }.to_json end @@ -106,10 +131,30 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do expect(response).to have_http_status(:forbidden) end end + + context "without any permissions" do + let(:permissions) { [] } + + it "returns 422 and does not create a section" do + expect(response).to have_http_status(:unprocessable_entity) + expect(meeting.sections.find_by(title: "New Section")).to be_nil + end + end + + context "with manage_agendas permission in another project" do + let(:current_user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it "returns 422 and does not create a section" do + expect(response).to have_http_status(:unprocessable_entity) + expect(meeting.sections.find_by(title: "New Section")).to be_nil + end + end end describe "GET /api/v3/meetings/:meeting_id/sections/:id" do - let(:path) { api_v3_paths.meeting_section(meeting.id, section.id) } + let(:path) { api_v3_paths.meeting_section(section.id, meeting_id: meeting.id) } before { get path } @@ -126,17 +171,39 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do end context "with a section from another meeting" do - let(:other_meeting) { create(:meeting, project:, author: current_user) } - let(:path) { api_v3_paths.meeting_section(other_meeting.id, section.id) } + let(:other_meeting) { create(:meeting, project:, author:) } + let(:path) { api_v3_paths.meeting_section(section.id, meeting_id: other_meeting.id) } it "returns 404" do expect(last_response).to have_http_status(:not_found) end end + + it_behaves_like "not found without meeting visibility" end - describe "PATCH /api/v3/meetings/:meeting_id/sections/:id" do - let(:path) { api_v3_paths.meeting_section(meeting.id, section.id) } + describe "GET /api/v3/meeting_sections/:id" do + let(:path) { api_v3_paths.meeting_section(section.id) } + + before { get path } + + it "returns 200 and the section" do + expect(last_response).to have_http_status(:ok) + + expect(last_response.body) + .to be_json_eql("MeetingSection".to_json) + .at_path("_type") + + expect(last_response.body) + .to be_json_eql(api_v3_paths.meeting_section(section.id).to_json) + .at_path("_links/self/href") + end + + it_behaves_like "not found without meeting visibility" + end + + describe "PATCH /api/v3/meeting_sections/:id" do + let(:path) { api_v3_paths.meeting_section(section.id) } let(:body) do { title: "Updated Section Title" @@ -161,10 +228,30 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do expect(response).to have_http_status(:forbidden) end end + + context "without any permissions" do + let(:permissions) { [] } + + it "returns 404 and does not update the section" do + expect(response).to have_http_status(:not_found) + expect(section.reload.title).to eq("First Section") + end + end + + context "with manage_agendas permission in another project" do + let(:current_user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it "returns 404 and does not update the section" do + expect(response).to have_http_status(:not_found) + expect(section.reload.title).to eq("First Section") + end + end end - describe "DELETE /api/v3/meetings/:meeting_id/sections/:id" do - let(:path) { api_v3_paths.meeting_section(meeting.id, section.id) } + describe "DELETE /api/v3/meeting_sections/:id" do + let(:path) { api_v3_paths.meeting_section(section.id) } before { delete path } @@ -185,5 +272,25 @@ RSpec.describe "API v3 Meeting Sections sub-resource", content_type: :json do it_behaves_like "unauthorized access" end + + context "without any permissions" do + let(:permissions) { [] } + + it "returns 404 and does not delete the section" do + expect(subject).to have_http_status(:not_found) + expect(MeetingSection).to exist(section.id) + end + end + + context "with manage_agendas permission in another project" do + let(:current_user) do + create(:user, member_with_permissions: { other_project => %i[view_meetings manage_agendas] }) + end + + it "returns 404 and does not delete the section" do + expect(subject).to have_http_status(:not_found) + expect(MeetingSection).to exist(section.id) + end + end end end diff --git a/modules/meeting/spec/requests/api/v3/meetings/meetings_resource_spec.rb b/modules/meeting/spec/requests/api/v3/meetings/meetings_resource_spec.rb index f1dae62f395..19e89a2c769 100644 --- a/modules/meeting/spec/requests/api/v3/meetings/meetings_resource_spec.rb +++ b/modules/meeting/spec/requests/api/v3/meetings/meetings_resource_spec.rb @@ -303,6 +303,37 @@ RSpec.describe "API v3 Meeting resource", content_type: :json do end end + context "when sending a smaller list of participants to _links.participants" do + let(:participant_user) do + create(:user, member_with_permissions: { project => [:view_meetings] }) + end + let(:other_participant_user) do + create(:user, member_with_permissions: { project => [:view_meetings] }) + end + + before do + create(:meeting_participant, meeting:, user: participant_user, invited: true) + create(:meeting_participant, meeting:, user: other_participant_user, invited: true) + end + + it "removes unlisted participants" do + expect(meeting.participants.count).to eq(2) + + body = { + lockVersion: meeting.lock_version, + _links: { + participants: [{ href: api_v3_paths.user(participant_user.id) }] + } + }.to_json + + patch path, body + + expect(last_response).to have_http_status(:ok) + expect(meeting.participants.reload.map(&:user_id)).to contain_exactly(participant_user.id) + expect(last_response.body).to have_json_size(1).at_path("_embedded/participants") + end + end + context "without edit_meetings permission" do let(:permissions) { %i[view_meetings] } diff --git a/modules/meeting/spec/services/meetings/copy_service_integration_spec.rb b/modules/meeting/spec/services/meetings/copy_service_integration_spec.rb index b3f36d94d40..2694eb9ca29 100644 --- a/modules/meeting/spec/services/meetings/copy_service_integration_spec.rb +++ b/modules/meeting/spec/services/meetings/copy_service_integration_spec.rb @@ -196,4 +196,45 @@ RSpec.describe Meetings::CopyService, "integration", type: :model do end end end + + context "with a work_package agenda item whose work package was deleted" do + before do + item = create(:wp_meeting_agenda_item, meeting:) + # Simulate the work package being destroyed (dependent: :nullify) + item.update_columns(work_package_id: nil) + end + + it "copies the deleted-WP agenda item preserving its type and nil work_package_id" do + expect(service_result).to be_success + deleted_item = copy.reload.agenda_items.find_by(item_type: :work_package, work_package_id: nil) + expect(deleted_item).to be_present + expect(deleted_item).to be_work_package + expect(deleted_item.work_package_id).to be_nil + end + end + + context "with a mix of valid and deleted work_package agenda items" do + let(:work_package) { create(:work_package, project:) } + + before do + create(:wp_meeting_agenda_item, meeting:, work_package:) + deleted_item = create(:wp_meeting_agenda_item, meeting:) + # Simulate the work package being destroyed (dependent: :nullify) + deleted_item.update_columns(work_package_id: nil) + end + + it "copies both the valid and deleted-WP agenda items" do + expect(service_result).to be_success + agenda_items = copy.reload.agenda_items + expect(agenda_items.count).to eq(2) + + valid_item = agenda_items.find_by(item_type: :work_package, work_package_id: work_package.id) + expect(valid_item).to be_present + expect(valid_item.work_package_id).to eq(work_package.id) + + deleted_item = agenda_items.find_by(item_type: :work_package, work_package_id: nil) + expect(deleted_item).to be_present + expect(deleted_item.work_package_id).to be_nil + end + end end diff --git a/modules/meeting/spec/services/recurring_meetings/reset_to_template_service_spec.rb b/modules/meeting/spec/services/recurring_meetings/reset_to_template_service_spec.rb index 384c3515320..777ea21ce2b 100644 --- a/modules/meeting/spec/services/recurring_meetings/reset_to_template_service_spec.rb +++ b/modules/meeting/spec/services/recurring_meetings/reset_to_template_service_spec.rb @@ -135,4 +135,33 @@ RSpec.describe RecurringMeetings::ResetToTemplateService, type: :model do expect(cancelled_occurrence.reload.participants.count).to eq(template_participant_count) end end + + context "when the template has a work package agenda item whose work package was deleted" do + before do + template_section = series.template.sections.first + wp_item = MeetingAgendaItem.create!( + meeting: series.template, + meeting_section: template_section, + item_type: :work_package, + work_package: create(:work_package, project:), + author: user, + position: 2 + ) + + # Simulate the work package being destroyed (dependent: :nullify) + wp_item.update_columns(work_package_id: nil) + end + + it "returns a successful service result" do + expect(service_result).to be_success + end + + it "copies the deleted WP agenda item preserving its type and nil work_package_id" do + service_result + deleted_item = cancelled_occurrence.reload.agenda_items.last + expect(deleted_item).to be_present + expect(deleted_item).to be_work_package + expect(deleted_item.work_package_id).to be_nil + end + end end diff --git a/modules/meeting/spec/services/recurring_meetings/update_service_integration_spec.rb b/modules/meeting/spec/services/recurring_meetings/update_service_integration_spec.rb index 56b887f9d9d..fc5a5254507 100644 --- a/modules/meeting/spec/services/recurring_meetings/update_service_integration_spec.rb +++ b/modules/meeting/spec/services/recurring_meetings/update_service_integration_spec.rb @@ -101,6 +101,46 @@ RSpec.describe RecurringMeetings::UpdateService, "integration", type: :model do end end + context "when ending a series with a stale cancelled occurrence" do + let(:series) do + create(:recurring_meeting, + project:, + start_time: 1.month.ago + 10.hours, + frequency: "daily", + interval: 1, + end_after: "specific_date", + end_date: 1.month.from_now) + end + let(:instance) do + described_class.new(model: series, user:, contract_class: RecurringMeetings::EndSeriesContract) + end + let(:params) do + { + end_after: "specific_date", + end_date: Time.zone.yesterday + } + end + let!(:cancelled_occurrence) do + create(:recurring_meeting_occurrence, + recurring_meeting: series, + start_time: Time.zone.tomorrow + 10.hours, + recurrence_start_time: Time.zone.tomorrow + 10.hours, + state: :cancelled) + end + let!(:section) { create(:meeting_section, meeting: cancelled_occurrence) } + let!(:agenda_item) do + create(:meeting_agenda_item, meeting: cancelled_occurrence, meeting_section: section) + end + + it "destroys the cancelled occurrence with its structured meeting content" do + expect(service_result).to be_success + + expect { cancelled_occurrence.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect { section.reload }.to raise_error(ActiveRecord::RecordNotFound) + expect { agenda_item.reload }.to raise_error(ActiveRecord::RecordNotFound) + end + end + describe "rescheduling job" do context "when updating the title" do let(:params) do diff --git a/modules/meeting/spec/support/pages/meetings/index.rb b/modules/meeting/spec/support/pages/meetings/index.rb index a4f260a9a5f..c001b667b6f 100644 --- a/modules/meeting/spec/support/pages/meetings/index.rb +++ b/modules/meeting/spec/support/pages/meetings/index.rb @@ -149,6 +149,21 @@ module Pages::Meetings wait_for_network_idle end + def set_project_filter(*projects) + find_test_selector("quick-filter-select-panel-button").click + + projects.each do |project| + option = find("[role='option']", text: project.name) + option.click unless option[:"aria-selected"] == "true" + end + + within("[data-controller='quick-filter--select-panel']") do + click_link_or_button I18n.t(:button_apply) + end + + wait_for_network_idle + end + def expect_no_meetings_listed within "#content-wrapper" do expect(page) diff --git a/modules/my_page/spec/features/my/work_package_table_spec.rb b/modules/my_page/spec/features/my/work_package_table_spec.rb index e0fc6a8a15d..b61c932a5e7 100644 --- a/modules/my_page/spec/features/my/work_package_table_spec.rb +++ b/modules/my_page/spec/features/my/work_package_table_spec.rb @@ -53,7 +53,7 @@ RSpec.describe "Arbitrary WorkPackage query table widget on my page", project:, type: other_type, author: user, - responsible: user) + assigned_to: user) end let(:permissions) { %i[view_work_packages add_work_packages save_queries] } @@ -84,18 +84,21 @@ RSpec.describe "Arbitrary WorkPackage query table widget on my page", created_by_me_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(2)") expect(created_by_me_area.area) .to have_css(".subject", text: type_work_package.subject) - - my_page.add_widget(1, 2, :column, "Work packages table") - - # Actually there are two success messages displayed currently. One for the grid getting updated and one - # for the query assigned to the new widget being created. A user will not notice it but the automated - # browser can get confused. Therefore we wait. - sleep(2) - + assigned_to_me_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") + expect(assigned_to_me_area.area) + .to have_css(".subject", text: other_type_work_package.subject) my_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") - filter_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(3)") - filter_area.expect_to_span(1, 3, 2, 4) + my_page.add_widget(1, 3, :column, "Work packages table") + my_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") + + created_by_me_area.remove + my_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") + assigned_to_me_area.remove + my_page.expect_and_dismiss_toaster message: I18n.t("js.notice_successful_update") + + filter_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") + filter_area.expect_to_span(1, 1, 2, 2) # At the beginning, the default query is displayed expect(filter_area.area) @@ -108,7 +111,7 @@ RSpec.describe "Arbitrary WorkPackage query table widget on my page", filter_area.configure_wp_table modal.switch_to("Filters") - filters.expect_filter_count(3) + filters.expect_filter_count(2) filters.add_filter_by("Type", "is (OR)", type.name) modal.save @@ -167,7 +170,7 @@ RSpec.describe "Arbitrary WorkPackage query table widget on my page", my_page.visit! wait_for_network_idle - filter_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(3)") + filter_area = Components::Grids::GridArea.new(".grid--area.-widgeted:nth-of-type(1)") retry_block do # Wait for the widget to load from its persisted state before asserting. diff --git a/modules/openid_connect/app/services/openid_connect/providers/update_service.rb b/modules/openid_connect/app/services/openid_connect/providers/update_service.rb index 1c4ab6167d4..e29d05de295 100644 --- a/modules/openid_connect/app/services/openid_connect/providers/update_service.rb +++ b/modules/openid_connect/app/services/openid_connect/providers/update_service.rb @@ -114,7 +114,7 @@ module OpenIDConnect if host.present? && OpenProject::SsrfProtection.safe_ip?(host) true else - call.errors.add(:metadata_url, :host_not_allowed) + call.errors.add(:metadata_url, :ssrf_filtered) call.success = false false end diff --git a/modules/openid_connect/config/locales/crowdin/cs.yml b/modules/openid_connect/config/locales/crowdin/cs.yml index 41af368eb87..2456efaf2cf 100644 --- a/modules/openid_connect/config/locales/crowdin/cs.yml +++ b/modules/openid_connect/config/locales/crowdin/cs.yml @@ -9,15 +9,15 @@ cs: activerecord: attributes: openid_connect/group_link: - oidc_group_name: OpenID group identifier + oidc_group_name: Identifikátor skupiny OpenID openid_connect/provider: name: Název slug: Jedinečný identifikátor display_name: Zobrazovaný název client_id: ID klienta client_secret: Tajný klíč klienta - groups_claim: Groups claim - group_regexes: Patterns (regular expressions) + groups_claim: Atribut skupiny + group_regexes: Vzory (regulární výrazy) secret: Tajné scope: Rozsah sync_groups: Synchronizovat skupiny @@ -45,10 +45,10 @@ cs: response_is_not_successful: " odpovídá s %{status}." response_is_not_json: " nevrací JSON obsah." response_misses_required_attributes: " does not return required attributes. Missing attributes are: %{missing_attributes}." - invalid_claims_essential: does not define a boolean at %{attribute}. + invalid_claims_essential: nedefinuje boolean u %{attribute}. invalid_claims_location: 'contain unsupported locations: %{invalid}. Supported locations are: %{supported}.' invalid_claims_values: does not define an array at %{attribute}. - non_object_attribute: does not define a JSON object at %{attribute}. + non_object_attribute: nedefinuje objekt JSON u %{attribute}. provider: delete_warning: input_delete_confirmation_html: Enter the provider name %{name} to confirm deletion. diff --git a/modules/openid_connect/spec/services/openid_connect/providers/update_service_spec.rb b/modules/openid_connect/spec/services/openid_connect/providers/update_service_spec.rb index 8ce703e4ae3..7be98aad37f 100644 --- a/modules/openid_connect/spec/services/openid_connect/providers/update_service_spec.rb +++ b/modules/openid_connect/spec/services/openid_connect/providers/update_service_spec.rb @@ -92,7 +92,7 @@ RSpec.describe OpenIDConnect::Providers::UpdateService, type: :model do result = service_call expect(result).not_to be_success - expect(result.errors[:metadata_url]).to include("is not an allowed host.") + expect(result.errors[:metadata_url]).to include("violates the SSRF policy of this OpenProject instance.") expect(httpx_session).not_to have_received(:get) end end diff --git a/modules/resource_management/config/locales/crowdin/de.yml b/modules/resource_management/config/locales/crowdin/de.yml index a4159c2e96d..f0687b4ba8d 100644 --- a/modules/resource_management/config/locales/crowdin/de.yml +++ b/modules/resource_management/config/locales/crowdin/de.yml @@ -30,13 +30,13 @@ de: resource_work_package_list: attributes: query: - must_be_work_package_query: must be a work package query. + must_be_work_package_query: muss mit einer Arbeitspaket-Abfrage verbunden sein. models: - resource_allocation: Resource Allocation - resource_planner: Resource Planner - resource_work_package_list: Work packages list - user_card: User cards - button_next: Next + resource_allocation: Ressourcenzuteilung + resource_planner: Ressourcenplanung + resource_work_package_list: Liste von Arbeitspaketen + user_card: Benutzer-Karten + button_next: Weiter label_resource_management: Ressourcenplanung permission_allocate_user_resources: Benutzer-Ressourcen zuweisen permission_allocate_user_resources_explanation: 'Ermöglicht Benutzern das Erstellen, Aktualisieren und Löschen von Ressourcenzuweisungen innerhalb eines Ressourcenplaners. Dazu gehört die Zuweisung von Benutzern (oder Benutzerfiltern) zu einem Planer und die Anpassung des zugewiesenen Zeit- und Datumsbereichs. @@ -65,16 +65,16 @@ de: desc: Erstellen Sie einen Ressourcenplaner, um Kapazitäten für dieses Projekt zu planen. title: Keine Ressourcenplaner vorhanden configure_view_dialog: - delete_confirmation: Are you sure you want to delete this view? This cannot be undone. + delete_confirmation: Sind Sie sicher, dass Sie diese Ansicht löschen möchten? Dies kann nicht rückgängig gemacht werden. filter_mode: automatic: - caption: An automatically-generated list that displays items that meet criteria you define. - label: Automatically filtered - label: Item selection + caption: Eine automatisch generierte Liste, die Arbeitspakete anzeigt, die den von ihnen definierten Kriterien entsprechen. + label: Automatisch gefiltert + label: Auswahl manual: - caption: A custom list of items you manually add and remove. Filtering is not possible. - label: Manually hand-picked - title: Configure view + caption: Eine benutzerdefinierte Liste von Artikeln, die Sie manuell hinzufügen und entfernen. Eine Filterung ist nicht möglich. + label: Manuell ausgewählt + title: Ansicht konfigurieren favorite_caption: 'Machen Sie diese Ansicht zu einem Favoriten, um sie im oberen Bereich des Seitenleistenmenüs hinzuzufügen. ' @@ -82,7 +82,7 @@ de: label_resource_planner: Ressourcenplaner label_resource_planner_plural: Ressourcenplaner new_view_dialog: - title: Add View + title: Ansicht hinzufügen public_caption: 'Machen Sie diese Ansicht für alle Mitglieder des Projekts öffentlich. Dies hat keine Auswirkungen auf die Sichtbarkeit von Arbeitspaketen, die immer noch von den jeweiligen Benutzerrechten abhängt. ' @@ -91,42 +91,42 @@ de: sidebar: private: Privat public: Öffentlich - sub_views: Views in this resource planner + sub_views: Ansichten in dieser Ressourcenplanung view_types: resource_work_package_list: - caption: Create a view based on work packages and see its details and allocation in a list - label: Work packages list + caption: Erstellen Sie eine Ansicht auf Basis von Arbeitspaketen und sehen Sie deren Details und Zuweisungen in einer Liste + label: Liste von Arbeitspaketen user_card: - caption: Create a view based on users and see their details and allocation in a list of user cards - label: Users card list + caption: Erstellen Sie eine Ansicht auf der Basis von Benutzern und sehen Sie deren Details und Zuordnung in einer Kachelansicht von Benutzerkarten + label: Benutzer-Karten work_package_list: add_work_package_dialog: - title: Add work package + title: Arbeitspaket hinzufügen allocation_placeholder: "—" blank: - description: There are no work packages matching this view's filters yet. - title: No work packages to display + description: Es gibt noch keine Arbeitspakete, die den Filtern dieser Ansicht entsprechen. + title: Keine Arbeitspakete anzuzeigen columns: - allocated_members: Allocated members - allocation: Allocation - dates: Dates + allocated_members: Zugewiesene Benutzer + allocation: Zuweisung + dates: Daten context_menu: - add_filter_criteria: Add filter criteria - add_user_group: Add user group - edit_total_work: Edit total work - label: More actions - move: Move - move_down: Move down - move_to_bottom: Move to bottom - move_to_top: Move to top - move_up: Move up - remove: Remove - remove_confirmation: Remove this work package from the view? - see_allocation: See allocation - mobile_title: Work packages - query_name: 'Resource management work packages: %{name}' + add_filter_criteria: Filter hinzufügen + add_user_group: Benutzergruppe hinzufügen + edit_total_work: Gesamte Arbeit bearbeiten + label: Weitere Aktionen + move: Verschieben + move_down: Nach unten verschieben + move_to_bottom: Nach ganz unten verschieben + move_to_top: Nach ganz oben verschieben + move_up: Nach oben verschieben + remove: Entfernen + remove_confirmation: Dieses Arbeitspaket aus der Ansicht entfernen? + see_allocation: Zuteilung anzeigen + mobile_title: Arbeitspakete + query_name: 'Arbeitspakete zur Ressourcenverwaltung: %{name}' subheader: - add: Add - add_work_package: Add work package - allocate: Allocate - settings: Configure view + add: Hinzufügen + add_work_package: Arbeitspaket hinzufügen + allocate: Zuweisen + settings: Ansicht konfigurieren diff --git a/modules/storages/app/validator/nextcloud_compatible_host_validator.rb b/modules/storages/app/validator/nextcloud_compatible_host_validator.rb index aabdcbcf612..ef4760e1a38 100644 --- a/modules/storages/app/validator/nextcloud_compatible_host_validator.rb +++ b/modules/storages/app/validator/nextcloud_compatible_host_validator.rb @@ -50,7 +50,7 @@ class NextcloudCompatibleHostValidator < ActiveModel::EachValidator return false if host.blank? return true if OpenProject::SsrfProtection.safe_ip?(host) - contract.errors.add(attribute, :host_not_allowed) + contract.errors.add(attribute, :ssrf_filtered) false rescue URI::InvalidURIError false diff --git a/modules/storages/config/locales/crowdin/de.yml b/modules/storages/config/locales/crowdin/de.yml index a1fab3b0da4..d4597d779c5 100644 --- a/modules/storages/config/locales/crowdin/de.yml +++ b/modules/storages/config/locales/crowdin/de.yml @@ -31,15 +31,15 @@ de: authentication_method: Authentifizierungsmethode creator: Ersteller drive: Laufwerk ID - file_link_origin: File link origin ID + file_link_origin: Externe ID des Datei-Links host: Host - linkable_to_storage: Linkable to storage - linkable_to_storage_url: Linkable to storage URL + linkable_to_storage: Verlinkbar mit Dateispeicher + linkable_to_storage_url: Verlinkbar mit Dateispeicher-URL name: Name password: Anwendungspasswort provider_type: Anbieter-Typ - storage: Storage - storage_url: Storage URL + storage: Dateispeicher + storage_url: Dateispeicher-URL tenant: Verzeichnis (Tenant) ID errors: messages: @@ -113,25 +113,25 @@ de: remote_folders: 'Inhalt des Teamordners lesen:' remove_user_from_group: 'Benutzer aus Gruppe entfernen:' rename_project_folder: 'Verwalteten Projektordner umbenennen:' - set_folder_permission: 'Set managed project Folder permissions:' + set_folder_permission: 'Berechtigungen für verwaltete Projektordner festlegen:' one_drive_sync_service: create_folder: 'Verwaltete Projekt-Ordnererstellung:' ensure_root_folder_permissions: 'Basisordner-Berechtigungen festlegen:' hide_inactive_folders: 'Verstecke Inaktive Ordner:' remote_folders: 'Inhalt des Root-Ordners des Laufwerks lesen:' rename_project_folder: 'Verwalteten Projektordner umbenennen:' - set_folder_permission: 'Set managed project Folder permissions:' + set_folder_permission: 'Berechtigungen für verwaltete Projektordner festlegen:' sharepoint_sync_service: create_folder: 'Verwaltete Projekt-Ordnererstellung:' ensure_root_folder_permissions: 'Basisordner-Berechtigungen festlegen:' hide_inactive_folders: 'Verstecke Inaktive Ordner:' remote_folders: 'Inhalt des Root-Ordners des Laufwerks lesen:' rename_project_folder: 'Verwalteten Projektordner umbenennen:' - set_folder_permission: 'Set managed project Folder permissions:' + set_folder_permission: 'Berechtigungen für verwaltete Projektordner festlegen:' errors: messages: error: Ein unerwarteter Fehler ist aufgetreten. Bitte überprüfen Sie die OpenProject Logdateien für weitere Informationen oder kontaktieren Sie einen Administrator - folder_id_collision: Multiple project storages try to manage the project folder %{folder}. Its synchronization was skipped. + folder_id_collision: Mehrere Projektspeicher versuchen, den Projektordner %{folder} zu verwalten. Seine Synchronisierung wurde übersprungen. forbidden: OpenProject konnte nicht auf die angefragte Ressource zugreifen. Bitte überprüfen Sie Ihre Berechtigungskonfiguration auf dem Speicheranbieter. unauthorized: OpenProject konnte sich nicht mit dem Speicheranbieter authentifizieren. Bitte überprüfen Sie Ihre Speicherkonfiguration und dessen Zugang. models: diff --git a/modules/storages/spec/contracts/storages/storages/shared_contract_examples.rb b/modules/storages/spec/contracts/storages/storages/shared_contract_examples.rb index 0b1f83ae507..d33470a736b 100644 --- a/modules/storages/spec/contracts/storages/storages/shared_contract_examples.rb +++ b/modules/storages/spec/contracts/storages/storages/shared_contract_examples.rb @@ -275,7 +275,7 @@ RSpec.shared_examples_for "nextcloud storage contract", :storage_server_helpers, context "when host is localhost" do let(:storage_host) { "http://localhost:1234" } - include_examples "contract is invalid", host: :host_not_allowed + include_examples "contract is invalid", host: :ssrf_filtered it "does not perform metadata discovery requests" do contract.validate @@ -288,7 +288,7 @@ RSpec.shared_examples_for "nextcloud storage contract", :storage_server_helpers, context "when host uses https protocol" do let(:storage_host) { "https://172.16.193.146" } - include_examples "contract is invalid", host: :host_not_allowed + include_examples "contract is invalid", host: :ssrf_filtered end end diff --git a/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.html.erb b/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.html.erb new file mode 100644 index 00000000000..90556381cc1 --- /dev/null +++ b/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.html.erb @@ -0,0 +1,47 @@ +<%#-- 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. + +++#%> + +<%= render(Primer::Alpha::Dialog.new(id:, title: t(".title"), size: :large, **system_arguments)) do |dialog| %> + <% + dialog.with_body(classes: "Overlay-body_autocomplete_height") do + primer_form_with(**form_options) do |form| + render(::Wikis::CreateNewWikiPageForm.new(form)) + end + end + %> + + <% dialog.with_footer do %> + <%= render(Primer::Beta::Button.new(data: { "close-dialog-id": id })) { t(:button_cancel) } %> + <%= + render(Primer::Beta::Button.new(scheme: :primary, form: form_id, type: :submit)) do + show_first_step? ? t(:button_next) : t(:button_add) + end + %> + <% end %> +<% end %> diff --git a/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.rb b/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.rb new file mode 100644 index 00000000000..ca9ff5331fa --- /dev/null +++ b/modules/wikis/app/components/wikis/create_new_wiki_page_dialog.rb @@ -0,0 +1,66 @@ +# 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 Wikis + class CreateNewWikiPageDialog < ApplicationComponent + include OpTurbo::Streamable + + def id = "create-new-wiki-page-dialog" + + def form_id = "#{id}-form" + + def show_first_step? + model.page_title.blank? + end + + def form_options + if show_first_step? + { + id: form_id, + model:, + method: :get, + url: create_new_page_dialog_wiki_pages_path, + data: { turbo_stream: true } + } + else + { + id: form_id, + model:, + url: create_and_link_wiki_pages_path, + data: { turbo_frame: WorkPackageWikisTabComponent::TURBO_FRAME_ID } + } + end + end + + def system_arguments + options + end + end +end diff --git a/modules/wikis/app/components/wikis/relation_page_links_component.html.erb b/modules/wikis/app/components/wikis/relation_page_links_component.html.erb index bdbb740acae..fc01ecf67e8 100644 --- a/modules/wikis/app/components/wikis/relation_page_links_component.html.erb +++ b/modules/wikis/app/components/wikis/relation_page_links_component.html.erb @@ -52,7 +52,9 @@ See COPYRIGHT and LICENSE files for more details. ) menu.with_item( label: t(".link_new"), - disabled: true # work in progress + tag: :a, + href: create_new_page_dialog_wiki_pages_path(create_new_page_parameters), + content_arguments: { data: { controller: "async-dialog" } } ) end end diff --git a/modules/wikis/app/components/wikis/relation_page_links_component.rb b/modules/wikis/app/components/wikis/relation_page_links_component.rb index bd9fe9f2cd3..6f1556eb437 100644 --- a/modules/wikis/app/components/wikis/relation_page_links_component.rb +++ b/modules/wikis/app/components/wikis/relation_page_links_component.rb @@ -50,6 +50,16 @@ module Wikis provider.user_connected?(User.current) end + def create_new_page_parameters + { + wikis_forms_create_new_wiki_page_form_model: { + linkable_id: work_package.id, + linkable_type: work_package.class.name, + provider_id: provider.id + } + } + end + private def page_link_service diff --git a/modules/wikis/app/controllers/wikis/admin/internal_wiki_provider_controller.rb b/modules/wikis/app/controllers/wikis/admin/internal_wiki_provider_controller.rb new file mode 100644 index 00000000000..babc03aebc6 --- /dev/null +++ b/modules/wikis/app/controllers/wikis/admin/internal_wiki_provider_controller.rb @@ -0,0 +1,57 @@ +# 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 Wikis + module Admin + class InternalWikiProviderController < ApplicationController + layout "admin" + + before_action :require_admin + + menu_item :internal_wiki_provider + + def show + @provider = Wikis::InternalProvider.first + end + + def update + provider = Wikis::InternalProvider.first + provider.update!(enabled: internal_provider_params[:enabled]) + redirect_to admin_settings_internal_wiki_provider_path + end + + private + + def internal_provider_params + params.expect(wikis_internal_provider: :enabled) + end + end + end +end diff --git a/modules/wikis/app/controllers/wikis/admin/wiki_providers_controller.rb b/modules/wikis/app/controllers/wikis/admin/wiki_providers_controller.rb index e509182c55e..0475bf0ce38 100644 --- a/modules/wikis/app/controllers/wikis/admin/wiki_providers_controller.rb +++ b/modules/wikis/app/controllers/wikis/admin/wiki_providers_controller.rb @@ -39,7 +39,7 @@ module Wikis before_action :require_admin before_action :find_wiki_provider, only: %i[edit update destroy confirm_destroy edit_general_info replace_oauth_application] - menu_item :wiki_providers + menu_item :external_wiki_providers def index @wiki_providers = editable_wiki_providers diff --git a/modules/wikis/app/controllers/wikis/search_pages_controller.rb b/modules/wikis/app/controllers/wikis/pages_controller.rb similarity index 59% rename from modules/wikis/app/controllers/wikis/search_pages_controller.rb rename to modules/wikis/app/controllers/wikis/pages_controller.rb index 636d2f1338b..d1c94680813 100644 --- a/modules/wikis/app/controllers/wikis/search_pages_controller.rb +++ b/modules/wikis/app/controllers/wikis/pages_controller.rb @@ -29,14 +29,34 @@ #++ module Wikis - class SearchPagesController < ApplicationController + class PagesController < ApplicationController + include OpTurbo::ComponentStream include Dry::Monads[:result] + before_action :authorize, except: %i[search] + # The search is project independent and thus permission independent. The user will see results according to # the permissions set in each wiki. - no_authorization_required! :show + no_authorization_required! :search - def show + def create_and_link + # TODO: implement service to create page and link + render_error_flash_message_via_turbo_stream( + message: "Not implemented yet. Trying to create a new page with #{create_new_page_params.to_h}" + ) + respond_to_with_turbo_streams + end + + def create_new_page_dialog + params = create_new_page_params + form_object = Forms::CreateNewWikiPageFormModel.new(linkable_id: params[:linkable_id], + linkable_type: params[:linkable_type], + provider_id: params[:provider_id], + page_title: params[:page_title]) + respond_with_dialog Wikis::CreateNewWikiPageDialog.new(form_object) + end + + def search provider = Provider.visible.find(params.expect(:provider_id)) query = params[:query] form_name = params[:name] @@ -57,5 +77,19 @@ module Wikis end end end + + def create_new_page_params + params.expect(wikis_forms_create_new_wiki_page_form_model: %i[provider_id linkable_type linkable_id page_title]) + .merge(parent_page_identifier: parse_identifier(params[:wiki_page_selection])) + end + + def parse_identifier(wiki_page_selection) + case wiki_page_selection + in [selected_page] + MultiJson.load(selected_page, symbolize_keys: true)[:value] + else + nil + end + end end end diff --git a/modules/wikis/app/forms/wikis/admin/internal_provider_form.rb b/modules/wikis/app/forms/wikis/admin/internal_provider_form.rb new file mode 100644 index 00000000000..61e7e8df168 --- /dev/null +++ b/modules/wikis/app/forms/wikis/admin/internal_provider_form.rb @@ -0,0 +1,43 @@ +# 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 Wikis::Admin + class InternalProviderForm < ApplicationForm + form do |f| + f.check_box( + name: :enabled, + label: I18n.t("wikis.admin.internal_provider_form.checkbox_label"), + caption: I18n.t("wikis.admin.internal_provider_form.checkbox_caption") + ) + + f.submit(name: :save, label: I18n.t("button_save"), scheme: :primary) + end + end +end diff --git a/modules/wikis/app/forms/wikis/create_new_wiki_page_form.rb b/modules/wikis/app/forms/wikis/create_new_wiki_page_form.rb new file mode 100644 index 00000000000..e0f2791a84f --- /dev/null +++ b/modules/wikis/app/forms/wikis/create_new_wiki_page_form.rb @@ -0,0 +1,85 @@ +# 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 Wikis + class CreateNewWikiPageForm < ApplicationForm + form do |f| + f.hidden(name: :provider_id) + f.hidden(name: :linkable_type) + f.hidden(name: :linkable_id) + + if first_step? + f.text_field(name: :page_title, label: I18n.t("wikis.create_new_wiki_page_dialog.page_title"), required: true) + else + f.hidden(name: :page_title) + + f.html_content do + render(Primer::Beta::Text.new) { I18n.t("wikis.create_new_wiki_page_dialog.parent_help_text") } + end + + f.html_content do + render( + Primer::OpenProject::FilterableTreeView.new( + src: helpers.search_wiki_pages_path(provider_id: model.provider_id, name: "wiki_page_selection"), + form_arguments: { builder: rails_builder(f), name: "wiki_page_selection" }, + filter_mode_control_arguments: { hidden: true }, + filter_input_arguments: { + placeholder: I18n.t("wikis.link_existing_wiki_page_form.placeholder"), + # every other property is just refilling the default values, + # as those are not merged into custom arguments + name: :filter, + label: I18n.t(:button_filter), + type: :search, + leading_visual: { icon: :search }, + visually_hide_label: true, + show_clear_button: true + }, + include_sub_items_check_box_arguments: { hidden: true }, + no_results_node_arguments: { label: I18n.t("wikis.link_existing_wiki_page_form.no_results") } + ) + ) + end + end + end + + private + + # Primer's FormObject stores the underlying ActionView/Primer form builder + # as @builder. FilterableTreeView requires an ActionView::FormBuilder to + # generate its hidden form inputs via hidden_field. + def rails_builder(form) + form.instance_variable_get(:@builder) + end + + def first_step? + model.page_title.blank? + end + end +end diff --git a/modules/wikis/app/models/queries/wikis/page_links/filter/wiki_page_link_type_filter.rb b/modules/wikis/app/models/queries/wikis/page_links/filter/wiki_page_link_type_filter.rb new file mode 100644 index 00000000000..c3c41356874 --- /dev/null +++ b/modules/wikis/app/models/queries/wikis/page_links/filter/wiki_page_link_type_filter.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 Queries + module Wikis + module PageLinks + module Filter + class WikiPageLinkTypeFilter < Filters::Base + self.model = ::Wikis::PageLink + + def type = :list + + def human_name + ::Wikis::PageLink.human_attribute_name(:type) + end + + def allowed_values + API::V3::PageLinks::URN_PAGE_LINK_TYPE.invert.to_a + end + + def values=(values) + @values = Array(values).map { API::V3::PageLinks::URN_PAGE_LINK_TYPE.invert[it] } + end + + def where + operator_strategy.sql_for_field(values, model.table_name, "type") + end + end + end + end + end +end diff --git a/modules/wikis/app/models/wikis/forms/create_new_wiki_page_form_model.rb b/modules/wikis/app/models/wikis/forms/create_new_wiki_page_form_model.rb new file mode 100644 index 00000000000..d3553a24aa4 --- /dev/null +++ b/modules/wikis/app/models/wikis/forms/create_new_wiki_page_form_model.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 Wikis + module Forms + class CreateNewWikiPageFormModel + extend ActiveModel::Naming + + attr_reader :linkable_id, :linkable_type, :provider_id, :page_title + + def initialize(linkable_id:, linkable_type:, provider_id:, page_title:) + @linkable_id = linkable_id + @linkable_type = linkable_type + @provider_id = provider_id + @page_title = page_title + end + end + end +end diff --git a/modules/wikis/app/seeders/basic_data/wikis/internal_provider_seeder.rb b/modules/wikis/app/seeders/basic_data/wikis/internal_provider_seeder.rb new file mode 100644 index 00000000000..639c93f5d53 --- /dev/null +++ b/modules/wikis/app/seeders/basic_data/wikis/internal_provider_seeder.rb @@ -0,0 +1,43 @@ +# 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 BasicData + module Wikis + class InternalProviderSeeder < Seeder + def seed_data! + ::Wikis::InternalProvider.create!(universal_identifier: "internal", name: "internal", enabled: true) + end + + def applicable? + !::Wikis::InternalProvider.exists? + end + end + end +end diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/page_reference.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/canonical_page_reference.rb similarity index 83% rename from modules/wikis/app/services/wikis/adapters/providers/xwiki/page_reference.rb rename to modules/wikis/app/services/wikis/adapters/providers/xwiki/canonical_page_reference.rb index e73e89b5f82..6ff8767b2e1 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/page_reference.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/canonical_page_reference.rb @@ -32,10 +32,9 @@ module Wikis module Adapters module Providers module XWiki - # Represents a parsed XWiki stable page identifier in canonical document reference format: + # Represents an XWiki page identifier in canonical document reference format: # "wikiName:Space1.Space2.PageName" — e.g. "xwiki:Main.WebHome" - # Maps to the REST API path: /wikis/{wiki}/spaces/{s1}/spaces/{s2}/pages/{page} - PageReference = Data.define(:wiki, :spaces, :page) do + CanonicalPageReference = Data.define(:wiki, :spaces, :page) do def self.parse(identifier) wiki, page_path = identifier.split(":", 2) return nil if page_path.blank? @@ -46,10 +45,16 @@ module Wikis new(wiki:, spaces:, page:) end + # Maps the reference to the REST API path, excluding the `/rest` prefix, e.g. + # /wikis/{wiki}/spaces/{s1}/spaces/{s2}/pages/{page} def rest_path spaces_path = spaces.map { "/spaces/#{CGI.escapeURIComponent(it)}" }.join "/wikis/#{CGI.escapeURIComponent(wiki)}#{spaces_path}/pages/#{CGI.escapeURIComponent(page)}" end + + def to_s + "#{wiki}:#{spaces.join('.')}.#{page}" + end end end end diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/concerns/xwiki_query.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/concerns/xwiki_query.rb index 1a317968ab9..dde1eb644c3 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/concerns/xwiki_query.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/concerns/xwiki_query.rb @@ -37,6 +37,16 @@ module Wikis module XWikiQuery ACCEPT_HEADERS = { "Accept" => "application/json" }.freeze + def self.included(base) + base.prepend Prepended + end + + module Prepended + def call(**) + catch(:xwiki_error) { super } + end + end + def authenticated(auth_strategy) Adapters::Authentication[auth_strategy].call do |http| yield http.with(headers: ACCEPT_HEADERS) @@ -71,6 +81,10 @@ module Wikis failure(code: :request_failed) end end + + def fetch_json(json_hash, key) + json_hash.fetch(key) { throw :xwiki_error, failure(code: :invalid_response) } + end end end end diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info.rb new file mode 100644 index 00000000000..831d97623ff --- /dev/null +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info.rb @@ -0,0 +1,72 @@ +# 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 Wikis + module Adapters + module Providers + module XWiki + module Queries + module Internal + # Fetch page information using a canonical XWiki identifier + class CanonicalPageInfo < BaseQuery + include Concerns::XWikiQuery + + def call(input_data:, auth_strategy:) + ref = CanonicalPageReference.parse(input_data.identifier) + return failure(code: :not_found) unless ref + + perform_request(ref, auth_strategy:) do |data| + success( + Results::PageInfo.new( + identifier: StablePageReference.parse(fetch_json(data, "id")).to_s, + title: data.fetch("title"), + href: data.fetch("xwikiAbsoluteUrl"), + provider: + ) + ) + end + end + + def perform_request(reference, auth_strategy:, &) + authenticated(auth_strategy) do |http| + handle_response( + http.with(headers: { "Content-Type": "application/json" }) + .get(rest_url("openproject/documents", query: { docRef: reference.to_s })), + & + ) + end + end + end + end + end + end + end + end +end diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/search_pages.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/search_pages.rb index 5c09cabb327..e0f3c7b02e9 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/search_pages.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/search_pages.rb @@ -36,7 +36,9 @@ module Wikis class SearchPages < BaseQuery include Concerns::XWikiQuery - MAXIMUM_RESULTS = 50 + # Limiting result size rather strictly, because each result will cause another HTTP call to XWiki, this does not + # scale well. A stricter limit improves the worst case latency. + MAXIMUM_RESULTS = 20 def call(input_data:, auth_strategy:) query = { q: "\"#{escape_quotes input_data.query}\"", number: MAXIMUM_RESULTS } @@ -44,14 +46,14 @@ module Wikis authenticated(auth_strategy) do |http| handle_response(http.get(rest_url("wikis/query", query:))) do |json| success( - json.fetch("searchResults") - .uniq { |r| r.fetch("id") } - .map do |r| - result = page_info(identifier: r.fetch("id"), auth_strategy:) - return result if result.failure? + fetch_json(json, "searchResults") + .uniq { |r| fetch_json(r, "id") } + .map do |r| + result = canonical_page_info(identifier: fetch_json(r, "id"), auth_strategy:) + return result if result.failure? - result.value! - end + result.value! + end ) end end @@ -62,6 +64,12 @@ module Wikis def escape_quotes(string) string.gsub("\\", "\\\\").gsub('"', '\"') end + + def canonical_page_info(identifier:, auth_strategy:) + Input::PageInfo.build(identifier:).bind do |input_data| + Internal::CanonicalPageInfo.new(model: provider).call(input_data:, auth_strategy:) + end + end end end end diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/page_info.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/stable_page_info.rb similarity index 84% rename from modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/page_info.rb rename to modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/stable_page_info.rb index 53a25638026..59603e6a4e7 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/page_info.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/queries/stable_page_info.rb @@ -33,20 +33,21 @@ module Wikis module Providers module XWiki module Queries - class PageInfo < BaseQuery + # Fetch page information using a stable XWiki identifier + class StablePageInfo < BaseQuery include Concerns::XWikiQuery def call(input_data:, auth_strategy:) - ref = PageReference.parse(input_data.identifier) + ref = StablePageReference.parse(input_data.identifier) return failure(code: :not_found) unless ref authenticated(auth_strategy) do |http| handle_response(http.get(rest_url(ref.rest_path))) do |data| success( Results::PageInfo.new( - identifier: input_data.identifier, - title: data["title"], - href: data["xwikiAbsoluteUrl"], + identifier: ref.to_s, + title: fetch_json(data, "title"), + href: fetch_json(data, "xwikiAbsoluteUrl"), provider: ) ) diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/registry.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/registry.rb index 534328ecf15..057136c3ade 100644 --- a/modules/wikis/app/services/wikis/adapters/providers/xwiki/registry.rb +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/registry.rb @@ -61,7 +61,7 @@ module Wikis namespace("queries") do register(:user, Queries::User) - register(:page_info, Queries::PageInfo) + register(:page_info, Queries::StablePageInfo) register(:referencing_pages, Queries::ReferencingPages) register(:relation_page_links, Queries::RelationPageLinks) register(:search_pages, Queries::SearchPages) diff --git a/modules/wikis/app/services/wikis/adapters/providers/xwiki/stable_page_reference.rb b/modules/wikis/app/services/wikis/adapters/providers/xwiki/stable_page_reference.rb new file mode 100644 index 00000000000..d92675cf8cc --- /dev/null +++ b/modules/wikis/app/services/wikis/adapters/providers/xwiki/stable_page_reference.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 Wikis + module Adapters + module Providers + module XWiki + # Represents an XWiki page identifier using the "stable" page identifier format: e.g. 0b89a + StablePageReference = Data.define(:uid) do + class << self + private :new + + def parse(uid) + return nil if uid.nil? + + new(uid:) + end + end + + # Maps the reference to the REST API path, excluding the `/rest` prefix, e.g. + # /openproject/documents/0b89a + def rest_path + "/openproject/documents/#{CGI.escapeURIComponent(uid)}" + end + + def to_s + uid + end + end + end + end + end +end diff --git a/modules/wikis/app/views/wikis/admin/internal_wiki_provider/show.html.erb b/modules/wikis/app/views/wikis/admin/internal_wiki_provider/show.html.erb new file mode 100644 index 00000000000..bff9216d6a9 --- /dev/null +++ b/modules/wikis/app/views/wikis/admin/internal_wiki_provider/show.html.erb @@ -0,0 +1,48 @@ +<%#-- 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(:label_administration), Wikis::InternalProvider.model_name.human %> + +<% content_for :content_header do %> + <%= render(Primer::OpenProject::PageHeader.new) do |header| %> + <% header.with_title { Wikis::InternalProvider.model_name.human } %> + <% header.with_description { t(".description") } %> + <% header.with_breadcrumbs([ + { href: admin_index_path, text: t(:label_administration) }, + { href: admin_settings_wiki_providers_path, text: t("menus.admin.wikis") }, + Wikis::InternalProvider.model_name.human + ]) %> + <% end %> +<% end %> + +<%= + primer_form_with(model: @provider, url: admin_settings_internal_wiki_provider_path) do |form| + render(Wikis::Admin::InternalProviderForm.new(form)) + end +%> diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb index b8afd7cbb11..a2c995b122f 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/edit.html.erb @@ -43,6 +43,7 @@ See COPYRIGHT and LICENSE files for more details. header.with_breadcrumbs( [ { href: admin_index_path, text: t(:label_administration) }, + { href: admin_settings_wiki_providers_path, text: t("menus.admin.wikis") }, { href: admin_settings_wiki_providers_path, text: t(:project_module_wiki_platforms) }, page_title ] diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb index fb08ec6d2e5..51dcb921429 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/index.html.erb @@ -35,6 +35,7 @@ See COPYRIGHT and LICENSE files for more details. <% header.with_description { t("wikis.admin.wiki_providers.index_description") } %> <% header.with_breadcrumbs([ { href: admin_index_path, text: t(:label_administration) }, + { href: admin_settings_wiki_providers_path, text: t("menus.admin.wikis") }, t(:project_module_wiki_platforms) ]) %> <% end %> diff --git a/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb b/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb index 9128d2f50de..eeefe962726 100644 --- a/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb +++ b/modules/wikis/app/views/wikis/admin/wiki_providers/new.html.erb @@ -36,6 +36,7 @@ See COPYRIGHT and LICENSE files for more details. <% header.with_breadcrumbs([ { href: admin_index_path, text: t(:label_administration) }, + { href: admin_settings_wiki_providers_path, text: t("menus.admin.wikis") }, { href: admin_settings_wiki_providers_path, text: t(:project_module_wiki_platforms) }, t("wikis.admin.wiki_providers.label_new_provider") ]) %> diff --git a/modules/wikis/app/views/wikis/search_pages/show.html.erb b/modules/wikis/app/views/wikis/pages/search.html.erb similarity index 100% rename from modules/wikis/app/views/wikis/search_pages/show.html.erb rename to modules/wikis/app/views/wikis/pages/search.html.erb diff --git a/modules/wikis/config/locales/crowdin/af.yml b/modules/wikis/config/locales/crowdin/af.yml index 79fbc8fe43d..44a09fa544b 100644 --- a/modules/wikis/config/locales/crowdin/af.yml +++ b/modules/wikis/config/locales/crowdin/af.yml @@ -31,68 +31,19 @@ af: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ af: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ af: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ar.yml b/modules/wikis/config/locales/crowdin/ar.yml index 38ac9df5dcf..3f88169edd0 100644 --- a/modules/wikis/config/locales/crowdin/ar.yml +++ b/modules/wikis/config/locales/crowdin/ar.yml @@ -47,68 +47,19 @@ ar: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -130,6 +81,12 @@ ar: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -174,3 +131,61 @@ ar: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/az.yml b/modules/wikis/config/locales/crowdin/az.yml index d2b8923e0f8..290da11ad2a 100644 --- a/modules/wikis/config/locales/crowdin/az.yml +++ b/modules/wikis/config/locales/crowdin/az.yml @@ -31,68 +31,19 @@ az: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ az: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ az: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/be.yml b/modules/wikis/config/locales/crowdin/be.yml index 4b24c8a10a8..a25c745786d 100644 --- a/modules/wikis/config/locales/crowdin/be.yml +++ b/modules/wikis/config/locales/crowdin/be.yml @@ -39,68 +39,19 @@ be: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ be: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ be: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/bg.yml b/modules/wikis/config/locales/crowdin/bg.yml index 203988bfcd9..62e83e38d2d 100644 --- a/modules/wikis/config/locales/crowdin/bg.yml +++ b/modules/wikis/config/locales/crowdin/bg.yml @@ -31,68 +31,19 @@ bg: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ bg: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ bg: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ca.yml b/modules/wikis/config/locales/crowdin/ca.yml index e06c307161e..32e72f4a0f9 100644 --- a/modules/wikis/config/locales/crowdin/ca.yml +++ b/modules/wikis/config/locales/crowdin/ca.yml @@ -31,68 +31,19 @@ ca: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ ca: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ ca: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ckb-IR.yml b/modules/wikis/config/locales/crowdin/ckb-IR.yml index a24dc0ff028..db8d5af8500 100644 --- a/modules/wikis/config/locales/crowdin/ckb-IR.yml +++ b/modules/wikis/config/locales/crowdin/ckb-IR.yml @@ -31,68 +31,19 @@ ckb-IR: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ ckb-IR: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ ckb-IR: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/cs.yml b/modules/wikis/config/locales/crowdin/cs.yml index 33ac90db0e1..adbcdb2be66 100644 --- a/modules/wikis/config/locales/crowdin/cs.yml +++ b/modules/wikis/config/locales/crowdin/cs.yml @@ -3,15 +3,15 @@ cs: activerecord: attributes: wikis/page_link: - identifier: Identifier - provider: Wiki Provider + identifier: Identifikátor + provider: Poskytovatel Wiki wikis/provider: - name: Name - universal_identifier: Universal identifier + name: Název + universal_identifier: Univerzální identifikátor wikis/xwiki_provider: authentication_method: Způsob ověření authentication_methods: - oauth2_sso: Single-Sign-On through OpenID Connect Identity Provider + oauth2_sso: Jednotné přihlášení prostřednictvím poskytovatele identit OpenID Connect two_way_oauth2: Two-way OAuth 2.0 authorization code flow token_exchange_scope: XWiki Scope url: Adresa URL instance @@ -39,68 +39,19 @@ cs: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ cs: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ cs: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/da.yml b/modules/wikis/config/locales/crowdin/da.yml index 66776c1336d..caaf1308254 100644 --- a/modules/wikis/config/locales/crowdin/da.yml +++ b/modules/wikis/config/locales/crowdin/da.yml @@ -31,68 +31,19 @@ da: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ da: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ da: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/de.yml b/modules/wikis/config/locales/crowdin/de.yml index 11954d33314..9c6c0276f62 100644 --- a/modules/wikis/config/locales/crowdin/de.yml +++ b/modules/wikis/config/locales/crowdin/de.yml @@ -3,11 +3,11 @@ de: activerecord: attributes: wikis/page_link: - identifier: Identifier + identifier: Kennung provider: Wiki-Anbieter wikis/provider: name: Name - universal_identifier: Universal identifier + universal_identifier: Universelle Kennung wikis/xwiki_provider: authentication_method: Authentifizierungsmethode authentication_methods: @@ -30,80 +30,31 @@ de: other: Verwandte Seitenlinks wikis/xwiki_provider: one: XWiki-Anbieter - other: XWiki providers + other: XWiki-Anbieter + menus: + admin: + external_wiki_providers: Wiki-Anbieter + internal_wiki_provider: Internes Wiki + wikis: Wikis permission_manage_wiki_page_links: Wiki-Seitenlinks verwalten project_module_wiki_platforms: Wiki-Anbieter wikis: - buttons: - connect_account: "%{provider}-Konto verbinden" - done_continue: Fertig, fortfahren - open_wiki: Open wiki - save_and_continue: Speichern und fortsetzen - wiki_page: Wiki-Seite - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: Benutzer Token - header: Authentifizierung - user_bound_request: Benutzerbasierte Anfrageauthentifizierung - base_configuration: - header: Konfiguration - provider_configured: Konfiguration abgeschlossen - errors: - not_configured: Die Verbindung konnte nicht validiert werden. Bitte schließen Sie zuerst die Konfiguration ab. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline-Seitenlinks - referencing_pages: Referenziert in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Seitenlink entfernen - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: Keine verwandten Seiten - empty_text: Fügen Sie manuell Links zu anderen verwandten Wikiseiten hinzu. - oauth_login_component: - heading: Nicht verbunden mit %{provider} - description: Melden Sie sich bei %{provider} an, um verwandte Wiki-Seiten aus dieser OpenProject-Instanz anzuzeigen und zu verwalten. - connect_button: "%{provider}-Konto verbinden" admin: destroy_confirmation_dialog_component: + description_html: Der Wiki-Anbieter %{wiki_provider} und alle zugehörigen Wikiseiten-Links werden gelöscht. Zusätzlich wird jeder Inline-Wiki-Link nicht mehr zugänglich sein. Diese Aktion kann nicht rückgängig gemacht werden. + heading: Diesen Wiki-Anbieter dauerhaft löschen? title: Wiki-Anbieter löschen - heading: Permanently delete this wiki provider? - description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. forms: general_info_form_component: - provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. + provider_description: Vergewissern Sie sich, dass Sie über Administratorrechte in Ihrer XWiki-Instanz verfügen, bevor Sie diese Einrichtung starten. oauth_application_form_component: - application_id: OpenProject OAuth Application ID - application_secret: OpenProject OAuth Application secret + application_id: OpenProject OAuth Anwendungs-ID + application_secret: OpenProject OAuth-Anwendungsgeheimnis oauth_client_form_component: - client_id: Wiki OAuth Client ID - client_secret: Wiki OAuth Client secret - redirect_uri: Redirect URI - redirect_uri_caption: Copy this value into the Redirect URI field of your XWiki OIDC client registration. + client_id: Wiki OAuth-Client-ID + client_secret: Wiki OAuth-Client Geheimnis + redirect_uri: Umleitungs-URI + redirect_uri_caption: Kopieren Sie diesen Wert in das Redirect URI Feld Ihrer XWiki OIDC Client-Registrierung. health_status: show: actions: @@ -114,13 +65,19 @@ de: no_health_report: Kein Bericht verfügbar no_health_report_description: Führen Sie jetzt die Prüfungen für einen vollständigen Statusbericht dieses Dateispeichers durch. title: Systemstatusbericht + internal_provider_form: + checkbox_caption: Erlauben Sie Projekten, das interne OpenProject-Wiki zusammen mit externen Wiki-Anbietern zu verwenden + checkbox_label: Aktivieren Sie das interne OpenProject-Wiki + internal_wiki_provider: + show: + description: Aktivieren oder deaktivieren Sie das interne OpenProject-Wiki oauth_application_info_component: confirm_replace_oauth_application: Diese Aktion setzt die aktuellen OAuth-Anmeldedaten zurück. Nach der Bestätigung müssen Sie die Anmeldedaten erneut in Ihre XWiki-Instanz eingeben und alle Konten müssen sich erneut autorisieren. Sind Sie sicher, dass Sie fortfahren möchten? - label_oauth_client_id: OAuth Client ID + label_oauth_client_id: OAuth-Client-ID replace_oauth_application: OpenProject OAuth-Anwendung ersetzen oauth_client_info_component: confirm_replace_oauth_client: Diese Aktion setzt die aktuellen XWiki OAuth-Zugangsdaten zurück. Alle Konten müssen sich erneut gegenüber XWiki autorisieren. Sind Sie sicher, dass Sie fortfahren möchten? - label_oauth_client_id: OAuth Client ID + label_oauth_client_id: OAuth-Client-ID replace_oauth_client: XWiki OAuth-Anwendung ersetzen side_panel: health_status_component: @@ -138,23 +95,81 @@ de: index_description: Fügen Sie einen externen Wiki-Dienst hinzu, um Arbeitspakete mit bestehenden Wiki-Seiten zu verknüpfen oder neue Seiten direkt von OpenProject aus zu erstellen. label_add_new: Neuen Wiki-Anbieter hinzufügen label_edit: XWiki-Anbieter bearbeiten - label_new_provider: New XWiki provider + label_new_provider: Neuer XWiki-Anbieter label_wiki_platform: Wiki-Anbieter - name_caption: Give your wiki provider a name so that users can differentiate between multiple wiki platforms. + name_caption: Geben Sie Ihrem Wiki-Provider einen Namen, damit Benutzer zwischen mehreren Wiki-Plattformen unterscheiden können. name_placeholder: XWiki Wissensdatenbank new_provider_html: Lesen Sie unsere Dokumentation über das [Einrichten einer XWiki-Integration](docs_url) für weitere Informationen. oauth: openproject_oauth: OpenProject OAuth sections: - general_information: General information + general_information: Allgemeine Informationen oauth_configuration: OAuth-Konfiguration - url_caption: The host address of your wiki platform including the https://. It should not be longer than 255 characters. + url_caption: Die Host-Adresse Ihrer Wiki-Plattform einschließlich der https://. Sie sollte nicht länger als 255 Zeichen sein. xwiki: oauth: - openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth application. + openproject_oauth_description: Erlauben Sie XWiki den Zugriff auf OpenProject Daten über OAuth. provider_oauth: Wiki OAuth - provider_oauth_configuration: Copy these values to the [XWiki OIDC Connection client](xwiki_oidc_link). - provider_oauth_description: Allow OpenProject to access XWiki data using OAuth. + provider_oauth_configuration: Kopieren Sie diese Werte in den [XWiki OIDC Connection Client](xwiki_oidc_link). + provider_oauth_description: Erlauben Sie OpenProject Zugriff auf XWiki Daten über OAuth. openproject_oauth_description: Erlauben Sie XWiki den Zugriff auf OpenProject Daten über OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Erlauben Sie OpenProject Zugriff auf XWiki Daten über OAuth. + buttons: + connect_account: "%{provider}-Konto verbinden" + done_continue: Fertig, fortfahren + open_wiki: Wiki öffnen + save_and_continue: Speichern und fortsetzen + wiki_page: Wiki-Seite + create_new_wiki_page_dialog: + page_title: Titel + parent_help_text: Wählen Sie eine übergeordnete Seite für diese neue Wikiseite. + title: Neue Wikiseite anlegen + delete_relation_page_link_confirmation_dialog: + heading: Link zur verknüpften Wikiseite löschen? + title: Link zur verknüpften Wikiseite löschen + health_checks: + authentication: + existing_token: Benutzer Token + header: Authentifizierung + user_bound_request: Benutzerbasierte Anfrageauthentifizierung + base_configuration: + header: Konfiguration + provider_configured: Konfiguration abgeschlossen + errors: + not_configured: Die Verbindung konnte nicht validiert werden. Bitte schließen Sie zuerst die Konfiguration ab. + xwiki_oauth_connection_error: OpenProject konnte sich nicht mit der konfigurierten XWiki-Instanz verbinden. + xwiki_oauth_request_error: Beim Versuch, mit der XWiki-Instanz zu kommunizieren, ist ein unerwarteter Fehler aufgetreten. + xwiki_oauth_token_missing: OpenProject kann die Kommunikation auf Benutzerebene mit XWiki nicht testen, da noch kein XWiki-Konto verknüpft wurde. + xwiki_oauth_unauthorized: Das Benutzer-Token wurde von XWiki nicht erkannt. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: Das Client Secret wird nach dem Schließen dieses Fensters nicht mehr zugänglich sein. Bitte kopieren Sie diese Werte in die [XWiki OpenProject Integrationseinstellungen](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Vorhandene Wikiseite hinzufügen + link_existing_wiki_page_form: + no_results: Keine Wikiseiten gefunden + placeholder: Suche nach einer Wikiseite + oauth_login_component: + connect_button: "%{provider}-Konto verbinden" + description: Melden Sie sich bei %{provider} an, um verwandte Wiki-Seiten aus dieser OpenProject-Instanz anzuzeigen und zu verwalten. + heading: Nicht verbunden mit %{provider} + page_link_component: + remove: Seitenlink entfernen + page_links: + errors: + page_access_forbidden: Sie haben keine Berechtigung, auf diese Wikiseite zuzugreifen + page_not_found: Verlinkte Wikiseite nicht mehr verfügbar + unexpected: Ein unbekannter Fehler ist aufgetreten + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Keine verwandten Seiten + empty_text: Fügen Sie manuell Links zu anderen verwandten Wikiseiten hinzu. + link_existing: Vorhandene Wikiseite + link_new: Neue Wikiseite + work_package_wikis_tab_component: + inline_page_links: Inline-Seitenlinks + referencing_pages: Referenziert in diff --git a/modules/wikis/config/locales/crowdin/el.yml b/modules/wikis/config/locales/crowdin/el.yml index df9907d7e45..3bae307fee0 100644 --- a/modules/wikis/config/locales/crowdin/el.yml +++ b/modules/wikis/config/locales/crowdin/el.yml @@ -31,68 +31,19 @@ el: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ el: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ el: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/eo.yml b/modules/wikis/config/locales/crowdin/eo.yml index b98323e9c9d..6899f65da67 100644 --- a/modules/wikis/config/locales/crowdin/eo.yml +++ b/modules/wikis/config/locales/crowdin/eo.yml @@ -31,68 +31,19 @@ eo: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ eo: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ eo: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/es.yml b/modules/wikis/config/locales/crowdin/es.yml index 1b50a03903e..03e4d974ae6 100644 --- a/modules/wikis/config/locales/crowdin/es.yml +++ b/modules/wikis/config/locales/crowdin/es.yml @@ -31,68 +31,19 @@ es: wikis/xwiki_provider: one: Proveedor de XWiki other: Proveedores de XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Gestionar enlaces de páginas wiki project_module_wiki_platforms: Proveedores de Wiki wikis: - buttons: - connect_account: Conectar cuenta de %{provider} - done_continue: Hecho, continuar - open_wiki: Abrir wiki - save_and_continue: Guardar y continuar - wiki_page: Página wiki - instructions: - xwiki: - integration: Administración de XWiki - oauth_application_details_html: No podrás volver a acceder al valor del secreto de cliente una vez que cierres esta ventana. Copia estos valores en la [configuración de integración de XWiki con OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Eliminar el enlace a la página wiki relacionada - heading: "¿Eliminar el enlace a la página wiki relacionada?" - health_checks: - authentication: - existing_token: Token de usuario - header: Autentificación - user_bound_request: Autenticación de solicitud basada en el usuario - base_configuration: - header: Configuración - provider_configured: Configuración completada - errors: - not_configured: No se ha podido validar la conexión. Finalice primero la configuración. - xwiki_oauth_connection_error: OpenProject no ha podido conectarse a la instancia de XWiki configurada. - xwiki_oauth_request_error: Se ha producido un error inesperado al intentar conectarse con la instancia de XWiki. - xwiki_oauth_token_missing: OpenProject no puede comprobar la comunicación a nivel de usuario con XWiki, ya que aún no has vinculado tu cuenta de XWiki. - xwiki_oauth_unauthorized: XWiki no ha reconocido el token de usuario. - link_existing_wiki_page_dialog: - title: Añadir una página wiki ya existente - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Enlaces a la página integrada - referencing_pages: Se hace referencia en - page_links: - errors: - page_not_found: La página wiki enlazada ya no está disponible - page_access_forbidden: No tienes permiso para acceder a esta página wiki - unexpected: Se ha producido un error desconocido - page_link_component: - remove: Eliminar enlace de página - relation_page_links_component: - link_existing: Página wiki ya existente - link_new: Nueva página wiki - empty_heading: No hay páginas relacionadas - empty_text: Añada manualmente enlaces a otras páginas wiki relacionadas. - oauth_login_component: - heading: No conectado a %{provider} - description: Inicie sesión en %{provider} para ver y gestionar las páginas wiki relacionadas desde esta instancia de OpenProject. - connect_button: Conectar cuenta de %{provider} admin: destroy_confirmation_dialog_component: - title: Eliminar proveedor wiki - heading: "¿Eliminar este proveedor de wiki de forma permanente?" description_html: Se eliminarán el proveedor de wiki %{wiki_provider} y todos los enlaces a páginas wiki relacionados. Además, ya no se podrá acceder a ningún enlace a páginas wiki incrustado. Esta acción es irreversible. + heading: "¿Eliminar este proveedor de wiki de forma permanente?" + title: Eliminar proveedor wiki forms: general_info_form_component: provider_description: Asegúrate de tener permisos de administrador en tu instancia de XWiki antes de realizar la configuración. @@ -114,6 +65,12 @@ es: no_health_report: No hay informes disponibles no_health_report_description: Ejecuta ahora las comprobaciones para obtener un informe completo del estado de este proveedor de wiki. title: Informe de salud + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Esta acción restablecerá las credenciales de OAuth actuales. Una vez confirmada, deberá volver a introducir las credenciales en su instancia de XWiki y todos los usuarios deberán volver a autorizarse. ¿Seguro que desea continuar? label_oauth_client_id: ID de cliente OAuth @@ -158,3 +115,61 @@ es: openproject_oauth_description: Permita que XWiki acceda a los datos de OpenProject utilizando un OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Permita que OpenProject acceda a los datos de XWiki mediante OAuth. + buttons: + connect_account: Conectar cuenta de %{provider} + done_continue: Hecho, continuar + open_wiki: Abrir wiki + save_and_continue: Guardar y continuar + wiki_page: Página wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: "¿Eliminar el enlace a la página wiki relacionada?" + title: Eliminar el enlace a la página wiki relacionada + health_checks: + authentication: + existing_token: Token de usuario + header: Autentificación + user_bound_request: Autenticación de solicitud basada en el usuario + base_configuration: + header: Configuración + provider_configured: Configuración completada + errors: + not_configured: No se ha podido validar la conexión. Finalice primero la configuración. + xwiki_oauth_connection_error: OpenProject no ha podido conectarse a la instancia de XWiki configurada. + xwiki_oauth_request_error: Se ha producido un error inesperado al intentar conectarse con la instancia de XWiki. + xwiki_oauth_token_missing: OpenProject no puede comprobar la comunicación a nivel de usuario con XWiki, ya que aún no has vinculado tu cuenta de XWiki. + xwiki_oauth_unauthorized: XWiki no ha reconocido el token de usuario. + instructions: + xwiki: + integration: Administración de XWiki + oauth_application_details_html: No podrás volver a acceder al valor del secreto de cliente una vez que cierres esta ventana. Copia estos valores en la [configuración de integración de XWiki con OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Añadir una página wiki ya existente + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Conectar cuenta de %{provider} + description: Inicie sesión en %{provider} para ver y gestionar las páginas wiki relacionadas desde esta instancia de OpenProject. + heading: No conectado a %{provider} + page_link_component: + remove: Eliminar enlace de página + page_links: + errors: + page_access_forbidden: No tienes permiso para acceder a esta página wiki + page_not_found: La página wiki enlazada ya no está disponible + unexpected: Se ha producido un error desconocido + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No hay páginas relacionadas + empty_text: Añada manualmente enlaces a otras páginas wiki relacionadas. + link_existing: Página wiki ya existente + link_new: Nueva página wiki + work_package_wikis_tab_component: + inline_page_links: Enlaces a la página integrada + referencing_pages: Se hace referencia en diff --git a/modules/wikis/config/locales/crowdin/et.yml b/modules/wikis/config/locales/crowdin/et.yml index eb798cdb2b5..8a5b8623cc2 100644 --- a/modules/wikis/config/locales/crowdin/et.yml +++ b/modules/wikis/config/locales/crowdin/et.yml @@ -31,68 +31,19 @@ et: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ et: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ et: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/eu.yml b/modules/wikis/config/locales/crowdin/eu.yml index d501e2e4798..e95eb573795 100644 --- a/modules/wikis/config/locales/crowdin/eu.yml +++ b/modules/wikis/config/locales/crowdin/eu.yml @@ -31,68 +31,19 @@ eu: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ eu: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ eu: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/fa.yml b/modules/wikis/config/locales/crowdin/fa.yml index a2ee0a4d83c..e7f9bd1b24a 100644 --- a/modules/wikis/config/locales/crowdin/fa.yml +++ b/modules/wikis/config/locales/crowdin/fa.yml @@ -31,68 +31,19 @@ fa: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ fa: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ fa: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/fi.yml b/modules/wikis/config/locales/crowdin/fi.yml index 51baa03156d..fd1c0c98161 100644 --- a/modules/wikis/config/locales/crowdin/fi.yml +++ b/modules/wikis/config/locales/crowdin/fi.yml @@ -31,68 +31,19 @@ fi: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ fi: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ fi: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/fil.yml b/modules/wikis/config/locales/crowdin/fil.yml index 4f65110714d..0f2f0637875 100644 --- a/modules/wikis/config/locales/crowdin/fil.yml +++ b/modules/wikis/config/locales/crowdin/fil.yml @@ -31,68 +31,19 @@ fil: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ fil: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ fil: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/fr.yml b/modules/wikis/config/locales/crowdin/fr.yml index ca86f9b1c02..48506ef37fd 100644 --- a/modules/wikis/config/locales/crowdin/fr.yml +++ b/modules/wikis/config/locales/crowdin/fr.yml @@ -31,68 +31,19 @@ fr: wikis/xwiki_provider: one: Fournisseur XWiki other: Fournisseur XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Gérer les liens de la page wiki project_module_wiki_platforms: Fournisseurs de wiki wikis: - buttons: - connect_account: Connectez votre compte %{provider} - done_continue: Terminé, continuer - open_wiki: Ouvrir le wiki - save_and_continue: Enregistrer et continuer - wiki_page: Page wiki - instructions: - xwiki: - integration: Administration de XWiki - oauth_application_details_html: La valeur du secret client ne sera plus accessible après la fermeture de cette fenêtre. Veuillez copier ces valeurs dans les [paramètres de l'intégration XWiki OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Supprimer le lien vers la page wiki associée - heading: Supprimer le lien vers la page wiki associée ? - health_checks: - authentication: - existing_token: Jeton d'utilisateur - header: Authentification - user_bound_request: Authentification des requêtes basée sur l’utilisateur - base_configuration: - header: Configuration - provider_configured: Configuration terminée - errors: - not_configured: La connexion n'a pas pu être validée. Veuillez d'abord terminer la configuration. - xwiki_oauth_connection_error: OpenProject n'a pas pu se connecter à l'instance XWiki configurée. - xwiki_oauth_request_error: Une erreur inattendue s'est produite lors de la communication avec l'instance XWiki. - xwiki_oauth_token_missing: OpenProject ne peut pas tester la communication au niveau de l'utilisateur avec XWiki car l'utilisateur n'a pas encore connecté son compte XWiki. - xwiki_oauth_unauthorized: Le jeton d'utilisateur n'a pas été reconnu par XWiki. - link_existing_wiki_page_dialog: - title: Ajouter une page wiki existante - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Liens intégrés dans la page - referencing_pages: Référencé dans - page_links: - errors: - page_not_found: La page wiki liée n'est plus disponible - page_access_forbidden: Vous n'avez pas l'autorisation d'accéder à cette page wiki - unexpected: Une erreur inattendue s'est produite - page_link_component: - remove: Supprimer le lien de la page - relation_page_links_component: - link_existing: Page wiki existante - link_new: Nouvelle page wiki - empty_heading: Aucune page liée - empty_text: Ajoutez manuellement des liens vers d'autres pages wiki liées. - oauth_login_component: - heading: Non connecté à %{provider} - description: Connectez-vous à %{provider} pour voir et gérer les pages wiki liées à cette instance d'OpenProject. - connect_button: Connecter le compte %{provider} admin: destroy_confirmation_dialog_component: - title: Supprimer le fournisseur de wiki - heading: Supprimer définitivement ce fournisseur wiki ? description_html: Le fournisseur du wiki %{wiki_provider} et tous les liens de la page wiki correspondante seront supprimés. En outre, chaque lien de page wiki en ligne ne sera plus accessible. Cette action est irréversible. + heading: Supprimer définitivement ce fournisseur wiki ? + title: Supprimer le fournisseur de wiki forms: general_info_form_component: provider_description: Veuillez vous assurer que vous disposez des privilèges d'administration dans votre instance XWiki avant de procéder à l'installation. @@ -114,6 +65,12 @@ fr: no_health_report: Aucun rapport disponible no_health_report_description: Lancez les contrôles maintenant pour obtenir un rapport complet sur l'état de santé de ce fournisseur wiki. title: Bilan de santé + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Cette action réinitialisera les informations d'identification OAuth actuelles. Après confirmation, vous devrez saisir à nouveau les informations d'identification dans votre instance XWiki et tous les utilisateurs devront se réautoriser. Voulez-vous vraiment continuer ? label_oauth_client_id: ID client OAuth @@ -158,3 +115,61 @@ fr: openproject_oauth_description: Autoriser XWiki à accéder aux données d'OpenProject via OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Autoriser OpenProject à accéder aux données XWiki via OAuth. + buttons: + connect_account: Connectez votre compte %{provider} + done_continue: Terminé, continuer + open_wiki: Ouvrir le wiki + save_and_continue: Enregistrer et continuer + wiki_page: Page wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Supprimer le lien vers la page wiki associée ? + title: Supprimer le lien vers la page wiki associée + health_checks: + authentication: + existing_token: Jeton d'utilisateur + header: Authentification + user_bound_request: Authentification des requêtes basée sur l’utilisateur + base_configuration: + header: Configuration + provider_configured: Configuration terminée + errors: + not_configured: La connexion n'a pas pu être validée. Veuillez d'abord terminer la configuration. + xwiki_oauth_connection_error: OpenProject n'a pas pu se connecter à l'instance XWiki configurée. + xwiki_oauth_request_error: Une erreur inattendue s'est produite lors de la communication avec l'instance XWiki. + xwiki_oauth_token_missing: OpenProject ne peut pas tester la communication au niveau de l'utilisateur avec XWiki car l'utilisateur n'a pas encore connecté son compte XWiki. + xwiki_oauth_unauthorized: Le jeton d'utilisateur n'a pas été reconnu par XWiki. + instructions: + xwiki: + integration: Administration de XWiki + oauth_application_details_html: La valeur du secret client ne sera plus accessible après la fermeture de cette fenêtre. Veuillez copier ces valeurs dans les [paramètres de l'intégration XWiki OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Ajouter une page wiki existante + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connecter le compte %{provider} + description: Connectez-vous à %{provider} pour voir et gérer les pages wiki liées à cette instance d'OpenProject. + heading: Non connecté à %{provider} + page_link_component: + remove: Supprimer le lien de la page + page_links: + errors: + page_access_forbidden: Vous n'avez pas l'autorisation d'accéder à cette page wiki + page_not_found: La page wiki liée n'est plus disponible + unexpected: Une erreur inattendue s'est produite + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Aucune page liée + empty_text: Ajoutez manuellement des liens vers d'autres pages wiki liées. + link_existing: Page wiki existante + link_new: Nouvelle page wiki + work_package_wikis_tab_component: + inline_page_links: Liens intégrés dans la page + referencing_pages: Référencé dans diff --git a/modules/wikis/config/locales/crowdin/he.yml b/modules/wikis/config/locales/crowdin/he.yml index 2c01fb92bb7..9b7920755de 100644 --- a/modules/wikis/config/locales/crowdin/he.yml +++ b/modules/wikis/config/locales/crowdin/he.yml @@ -39,68 +39,19 @@ he: two: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ he: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ he: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/hi.yml b/modules/wikis/config/locales/crowdin/hi.yml index 6610968edfe..0de5471a384 100644 --- a/modules/wikis/config/locales/crowdin/hi.yml +++ b/modules/wikis/config/locales/crowdin/hi.yml @@ -31,68 +31,19 @@ hi: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ hi: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ hi: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/hr.yml b/modules/wikis/config/locales/crowdin/hr.yml index 5f9a732b75f..6599ea083bc 100644 --- a/modules/wikis/config/locales/crowdin/hr.yml +++ b/modules/wikis/config/locales/crowdin/hr.yml @@ -35,68 +35,19 @@ hr: one: XWiki provider few: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -118,6 +69,12 @@ hr: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -162,3 +119,61 @@ hr: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/hu.yml b/modules/wikis/config/locales/crowdin/hu.yml index 3999913f2f4..3a95e494e58 100644 --- a/modules/wikis/config/locales/crowdin/hu.yml +++ b/modules/wikis/config/locales/crowdin/hu.yml @@ -31,68 +31,19 @@ hu: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ hu: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ hu: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/hy.yml b/modules/wikis/config/locales/crowdin/hy.yml index ce54c3bf831..22f92c77077 100644 --- a/modules/wikis/config/locales/crowdin/hy.yml +++ b/modules/wikis/config/locales/crowdin/hy.yml @@ -31,68 +31,19 @@ hy: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ hy: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ hy: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/id.yml b/modules/wikis/config/locales/crowdin/id.yml index 7202fbabd6f..b6f39942cbd 100644 --- a/modules/wikis/config/locales/crowdin/id.yml +++ b/modules/wikis/config/locales/crowdin/id.yml @@ -27,68 +27,19 @@ id: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ id: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ id: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/it.yml b/modules/wikis/config/locales/crowdin/it.yml index c541b2d2bbb..5ff50327a87 100644 --- a/modules/wikis/config/locales/crowdin/it.yml +++ b/modules/wikis/config/locales/crowdin/it.yml @@ -31,68 +31,19 @@ it: wikis/xwiki_provider: one: Fornitore XWiki other: Fornitori XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Gestire i link delle pagine Wiki project_module_wiki_platforms: Fornitori Wiki wikis: - buttons: - connect_account: Connetti account %{provider} - done_continue: Fatto, continua - open_wiki: Apri wiki - save_and_continue: Salva e continua - wiki_page: Pagina wiki - instructions: - xwiki: - integration: Amministrazione XWiki - oauth_application_details_html: Il valore del client secret non sarà più accessibile dopo la chiusura di questa finestra. Copia questi valori nelle [impostazioni di integrazione OpenProject di XWiki](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Elimina il link relativo alla pagina wiki - heading: Eliminare il link relativo alla pagina wiki? - health_checks: - authentication: - existing_token: Token utente - header: Autenticazione - user_bound_request: Autenticazione richiesta basata sull'utente - base_configuration: - header: Configurazione - provider_configured: Configurazione completa - errors: - not_configured: Non è stato possibile verificare la connessione. Prima è necessario completare la configurazione. - xwiki_oauth_connection_error: OpenProject non è riuscito a connettersi all'istanza XWiki configurata. - xwiki_oauth_request_error: Si è verificato un errore imprevisto durante il tentativo di comunicare con l'istanza XWiki. - xwiki_oauth_token_missing: OpenProject non può testare la comunicazione a livello utente con XWiki poiché l'utente non ha ancora collegato il proprio account XWiki. - xwiki_oauth_unauthorized: Il token utente non è stato riconosciuto da XWiki. - link_existing_wiki_page_dialog: - title: Aggiungi una pagina wiki esistente - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Collegamenti alle pagine inline - referencing_pages: Citata in - page_links: - errors: - page_not_found: La pagina wiki collegata non è più disponibile - page_access_forbidden: Non hai i permessi per accedere a questa pagina wiki - unexpected: Si è verificato un errore inaspettato - page_link_component: - remove: Rimuovi link della pagina - relation_page_links_component: - link_existing: Pagina wiki esistente - link_new: Nuova pagina wiki - empty_heading: Nessuna pagina correlata - empty_text: Aggiunga manualmente i link ad altre pagine wiki correlate. - oauth_login_component: - heading: Non collegato a %{provider} - description: Accedi a %{provider} per visualizzare e gestire le pagine wiki correlate da questa istanza di OpenProject. - connect_button: Connetti account %{provider} admin: destroy_confirmation_dialog_component: - title: Elimina fornitore wiki - heading: Eliminare definitivamente questo fornitore wiki? description_html: Il fornitore wiki %{wiki_provider} e tutti i collegamenti alle pagine wiki associati verranno eliminati. Inoltre, tutti i collegamenti incorporati alle pagine wiki non saranno più accessibili. Questa azione è irreversibile. + heading: Eliminare definitivamente questo fornitore wiki? + title: Elimina fornitore wiki forms: general_info_form_component: provider_description: Assicurati di avere privilegi di amministrazione nella tua istanza XWiki prima di procedere con la configurazione. @@ -114,6 +65,12 @@ it: no_health_report: Nessun report disponibile no_health_report_description: Esegui subito i controlli per ottenere un report completo sullo stato di integrità di questo fornitore wiki. title: Report sullo stato + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Questa azione reimposterà le credenziali OAuth correnti. Dopo la conferma dovrai reinserire le credenziali nella tua istanza XWiki e tutti gli utenti dovranno autorizzare nuovamente l'accesso. Vuoi davvero procedere? label_oauth_client_id: ID client OAuth @@ -158,3 +115,61 @@ it: openproject_oauth_description: Consenti a XWiki di accedere ai dati di OpenProject utilizzando un OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Consenti a OpenProject di accedere ai dati XWiki utilizzando OAuth. + buttons: + connect_account: Connetti account %{provider} + done_continue: Fatto, continua + open_wiki: Apri wiki + save_and_continue: Salva e continua + wiki_page: Pagina wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Eliminare il link relativo alla pagina wiki? + title: Elimina il link relativo alla pagina wiki + health_checks: + authentication: + existing_token: Token utente + header: Autenticazione + user_bound_request: Autenticazione richiesta basata sull'utente + base_configuration: + header: Configurazione + provider_configured: Configurazione completa + errors: + not_configured: Non è stato possibile verificare la connessione. Prima è necessario completare la configurazione. + xwiki_oauth_connection_error: OpenProject non è riuscito a connettersi all'istanza XWiki configurata. + xwiki_oauth_request_error: Si è verificato un errore imprevisto durante il tentativo di comunicare con l'istanza XWiki. + xwiki_oauth_token_missing: OpenProject non può testare la comunicazione a livello utente con XWiki poiché l'utente non ha ancora collegato il proprio account XWiki. + xwiki_oauth_unauthorized: Il token utente non è stato riconosciuto da XWiki. + instructions: + xwiki: + integration: Amministrazione XWiki + oauth_application_details_html: Il valore del client secret non sarà più accessibile dopo la chiusura di questa finestra. Copia questi valori nelle [impostazioni di integrazione OpenProject di XWiki](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Aggiungi una pagina wiki esistente + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connetti account %{provider} + description: Accedi a %{provider} per visualizzare e gestire le pagine wiki correlate da questa istanza di OpenProject. + heading: Non collegato a %{provider} + page_link_component: + remove: Rimuovi link della pagina + page_links: + errors: + page_access_forbidden: Non hai i permessi per accedere a questa pagina wiki + page_not_found: La pagina wiki collegata non è più disponibile + unexpected: Si è verificato un errore inaspettato + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Nessuna pagina correlata + empty_text: Aggiunga manualmente i link ad altre pagine wiki correlate. + link_existing: Pagina wiki esistente + link_new: Nuova pagina wiki + work_package_wikis_tab_component: + inline_page_links: Collegamenti alle pagine inline + referencing_pages: Citata in diff --git a/modules/wikis/config/locales/crowdin/ja.yml b/modules/wikis/config/locales/crowdin/ja.yml index d293568f194..8d15793bd6a 100644 --- a/modules/wikis/config/locales/crowdin/ja.yml +++ b/modules/wikis/config/locales/crowdin/ja.yml @@ -27,68 +27,19 @@ ja: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ ja: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ ja: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ka.yml b/modules/wikis/config/locales/crowdin/ka.yml index b0984d748b3..11a1a6eb2bb 100644 --- a/modules/wikis/config/locales/crowdin/ka.yml +++ b/modules/wikis/config/locales/crowdin/ka.yml @@ -31,68 +31,19 @@ ka: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ ka: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ ka: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/kk.yml b/modules/wikis/config/locales/crowdin/kk.yml index c1555cc629b..8ec1b38fb80 100644 --- a/modules/wikis/config/locales/crowdin/kk.yml +++ b/modules/wikis/config/locales/crowdin/kk.yml @@ -31,68 +31,19 @@ kk: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ kk: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ kk: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ko.yml b/modules/wikis/config/locales/crowdin/ko.yml index f7b2d1036d5..b3d3c7aa702 100644 --- a/modules/wikis/config/locales/crowdin/ko.yml +++ b/modules/wikis/config/locales/crowdin/ko.yml @@ -27,68 +27,19 @@ ko: other: 관련 페이지 링크 wikis/xwiki_provider: other: XWiki 공급자 + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: 위키 페이지 링크 관리 project_module_wiki_platforms: 위키 공급자 wikis: - buttons: - connect_account: "%{provider} 계정 연결" - done_continue: 완료, 계속 - open_wiki: 위키 열기 - save_and_continue: 저장 및 계속 - wiki_page: 위키 페이지 - instructions: - xwiki: - integration: XWiki 관리 - oauth_application_details_html: '이 창을 닫으면 클라이언트 비밀번호 값에 다시 액세스할 수 없습니다. 다음 값을 [XWiki OpenProject 통합 설정](xwiki_admin_link)에 복사하세요:' - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: 관련 위키 페이지 링크 삭제 - heading: 관련 위키 페이지 링크를 삭제하시겠습니까? - health_checks: - authentication: - existing_token: 사용자 토큰 - header: 인증 - user_bound_request: 사용자 기반 요청 인증 - base_configuration: - header: 구성 - provider_configured: 구성 완료 - errors: - not_configured: 연결에 대한 유효성 검사를 할 수 없습니다. 먼저 구성을 완료하세요. - xwiki_oauth_connection_error: 구성된 XWiki 인스턴스에 OpenProject가 연결할 수 없습니다. - xwiki_oauth_request_error: XWiki 인스턴스와 통신을 시도할 때 예기치 않은 오류가 발생했습니다. - xwiki_oauth_token_missing: 사용자가 아직 XWiki 계정을 연결하지 않았기 때문에 OpenProject가 XWiki와의 사용자 수준 통신을 테스트할 수 없습니다. - xwiki_oauth_unauthorized: 사용자 토큰이 XWiki에서 인식되지 않았습니다. - link_existing_wiki_page_dialog: - title: 기존 위키 페이지 추가 - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: 인라인 페이지 링크 - referencing_pages: '다음에서 참조됨:' - page_links: - errors: - page_not_found: 링크된 위키 페이지를 더 이상 사용할 수 없음 - page_access_forbidden: 이 위키 페이지에 액세스할 수 있는 권한이 없습니다 - unexpected: 예기치 않은 오류가 발생했습니다 - page_link_component: - remove: 페이지 링크 제거 - relation_page_links_component: - link_existing: 기존 위키 페이지 - link_new: 새 위키 페이지 - empty_heading: 관련 페이지 없음 - empty_text: 다른 관련 위키 페이지에 대한 링크를 수동으로 추가합니다. - oauth_login_component: - heading: "%{provider}에 연결되지 않음" - description: "%{provider}에 로그인하여 이 OpenProject 인스턴스의 관련 위키 페이지를 보고 관리합니다." - connect_button: "%{provider} 계정 연결" admin: destroy_confirmation_dialog_component: - title: 위키 공급자 삭제 - heading: 이 위키 공급자를 영구적으로 삭제하시겠습니까? description_html: 위키 공급자 %{wiki_provider} 및 모든 관련 위키 페이지 링크가 삭제됩니다. 또한 모든 인라인 위키 페이지 링크에 더 이상 액세스할 수 없습니다. 이 작업은 되돌릴 수 없습니다. + heading: 이 위키 공급자를 영구적으로 삭제하시겠습니까? + title: 위키 공급자 삭제 forms: general_info_form_component: provider_description: 설정을 수행하기 전에 XWiki 인스턴스에서 관리 권한이 있는지 확인하세요. @@ -110,6 +61,12 @@ ko: no_health_report: 사용 가능한 보고서 없음 no_health_report_description: 이 위키 공급자에 대한 전체 상태 보고서를 보려면 지금 검사를 실행하세요. title: 상태 보고서 + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: 이 작업은 현재 OAuth 자격 증명을 재설정합니다. 확인 후 XWiki 인스턴스에서 자격 증명을 다시 입력해야 하며 모든 사용자가 다시 인증해야 합니다. 계속하시겠습니까? label_oauth_client_id: OAuth 클라이언트 ID @@ -154,3 +111,61 @@ ko: openproject_oauth_description: XWiki가 OAuth를 사용하여 OpenProject 데이터에 액세스하도록 허용합니다. xwiki_oauth: XWiki OAuth xwiki_oauth_description: OpenProject가 OAuth를 사용하여 XWiki 데이터에 액세스하도록 허용합니다. + buttons: + connect_account: "%{provider} 계정 연결" + done_continue: 완료, 계속 + open_wiki: 위키 열기 + save_and_continue: 저장 및 계속 + wiki_page: 위키 페이지 + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: 관련 위키 페이지 링크를 삭제하시겠습니까? + title: 관련 위키 페이지 링크 삭제 + health_checks: + authentication: + existing_token: 사용자 토큰 + header: 인증 + user_bound_request: 사용자 기반 요청 인증 + base_configuration: + header: 구성 + provider_configured: 구성 완료 + errors: + not_configured: 연결에 대한 유효성 검사를 할 수 없습니다. 먼저 구성을 완료하세요. + xwiki_oauth_connection_error: 구성된 XWiki 인스턴스에 OpenProject가 연결할 수 없습니다. + xwiki_oauth_request_error: XWiki 인스턴스와 통신을 시도할 때 예기치 않은 오류가 발생했습니다. + xwiki_oauth_token_missing: 사용자가 아직 XWiki 계정을 연결하지 않았기 때문에 OpenProject가 XWiki와의 사용자 수준 통신을 테스트할 수 없습니다. + xwiki_oauth_unauthorized: 사용자 토큰이 XWiki에서 인식되지 않았습니다. + instructions: + xwiki: + integration: XWiki 관리 + oauth_application_details_html: '이 창을 닫으면 클라이언트 비밀번호 값에 다시 액세스할 수 없습니다. 다음 값을 [XWiki OpenProject 통합 설정](xwiki_admin_link)에 복사하세요:' + link_existing_wiki_page_dialog: + title: 기존 위키 페이지 추가 + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: "%{provider} 계정 연결" + description: "%{provider}에 로그인하여 이 OpenProject 인스턴스의 관련 위키 페이지를 보고 관리합니다." + heading: "%{provider}에 연결되지 않음" + page_link_component: + remove: 페이지 링크 제거 + page_links: + errors: + page_access_forbidden: 이 위키 페이지에 액세스할 수 있는 권한이 없습니다 + page_not_found: 링크된 위키 페이지를 더 이상 사용할 수 없음 + unexpected: 예기치 않은 오류가 발생했습니다 + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: 관련 페이지 없음 + empty_text: 다른 관련 위키 페이지에 대한 링크를 수동으로 추가합니다. + link_existing: 기존 위키 페이지 + link_new: 새 위키 페이지 + work_package_wikis_tab_component: + inline_page_links: 인라인 페이지 링크 + referencing_pages: '다음에서 참조됨:' diff --git a/modules/wikis/config/locales/crowdin/lt.yml b/modules/wikis/config/locales/crowdin/lt.yml index 8f2b0bfb408..b26c55a4235 100644 --- a/modules/wikis/config/locales/crowdin/lt.yml +++ b/modules/wikis/config/locales/crowdin/lt.yml @@ -39,68 +39,19 @@ lt: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ lt: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ lt: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/lv.yml b/modules/wikis/config/locales/crowdin/lv.yml index d319932b84d..b5e655c4d3d 100644 --- a/modules/wikis/config/locales/crowdin/lv.yml +++ b/modules/wikis/config/locales/crowdin/lv.yml @@ -35,68 +35,19 @@ lv: zero: XWiki providers one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -118,6 +69,12 @@ lv: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -162,3 +119,61 @@ lv: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/mn.yml b/modules/wikis/config/locales/crowdin/mn.yml index 417cfb948c4..d4d8c6ba532 100644 --- a/modules/wikis/config/locales/crowdin/mn.yml +++ b/modules/wikis/config/locales/crowdin/mn.yml @@ -31,68 +31,19 @@ mn: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ mn: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ mn: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ms.yml b/modules/wikis/config/locales/crowdin/ms.yml index 40a530dd43d..f23c1d8ef6f 100644 --- a/modules/wikis/config/locales/crowdin/ms.yml +++ b/modules/wikis/config/locales/crowdin/ms.yml @@ -27,68 +27,19 @@ ms: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ ms: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ ms: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ne.yml b/modules/wikis/config/locales/crowdin/ne.yml index e61774046f3..c54206f4c32 100644 --- a/modules/wikis/config/locales/crowdin/ne.yml +++ b/modules/wikis/config/locales/crowdin/ne.yml @@ -31,68 +31,19 @@ ne: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ ne: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ ne: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/nl.yml b/modules/wikis/config/locales/crowdin/nl.yml index a61f9139b50..905040f0275 100644 --- a/modules/wikis/config/locales/crowdin/nl.yml +++ b/modules/wikis/config/locales/crowdin/nl.yml @@ -31,68 +31,19 @@ nl: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ nl: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ nl: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/no.yml b/modules/wikis/config/locales/crowdin/no.yml index d7475463b1b..38fe5c7b1d8 100644 --- a/modules/wikis/config/locales/crowdin/no.yml +++ b/modules/wikis/config/locales/crowdin/no.yml @@ -31,68 +31,19 @@ wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/pl.yml b/modules/wikis/config/locales/crowdin/pl.yml index fdce7fc9112..a5c52e9826d 100644 --- a/modules/wikis/config/locales/crowdin/pl.yml +++ b/modules/wikis/config/locales/crowdin/pl.yml @@ -39,68 +39,19 @@ pl: few: Dostawca XWiki many: Dostawcy XWiki other: Dostawcy XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Zarządzanie linkami do stron Wiki project_module_wiki_platforms: Dostawcy wiki wikis: - buttons: - connect_account: Podłącz konto %{provider} - done_continue: Gotowe, kontynuuj - open_wiki: Otwórz wiki - save_and_continue: Zapisz i kontynuuj - wiki_page: Strona wiki - instructions: - xwiki: - integration: Administracja XWiki - oauth_application_details_html: Wartość klucza tajnego klienta nie będzie ponownie dostępna po zamknięciu tego okna. Skopiuj te wartości do [ustawień integracji XWiki z OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Usuń powiązany link do strony wiki - heading: Usunąć powiązany link do strony wiki? - health_checks: - authentication: - existing_token: Token użytkownika - header: Uwierzytelnianie - user_bound_request: Uwierzytelnianie żądań po stronie użytkownika - base_configuration: - header: Konfiguracja - provider_configured: Ukończono konfigurację - errors: - not_configured: Nie można zweryfikować połączenia. Najpierw zakończ konfigurację. - xwiki_oauth_connection_error: OpenProject nie może połączyć się ze skonfigurowanym wystąpieniem XWiki. - xwiki_oauth_request_error: Podczas próby komunikacji z wystąpieniem XWiki wystąpił nieoczekiwany błąd. - xwiki_oauth_token_missing: Aplikacja OpenProject nie może przetestować komunikacji z XWiki na poziomie użytkownika, ponieważ użytkownik nie powiązał jeszcze swojego konta XWiki. - xwiki_oauth_unauthorized: Token użytkownika nie został rozpoznany przez XWiki. - link_existing_wiki_page_dialog: - title: Dodaj istniejącą stronę wiki - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Wbudowane linki strony - referencing_pages: Wymieniono w - page_links: - errors: - page_not_found: Powiązana linkiem strona wiki nie jest już dostępna - page_access_forbidden: Nie masz uprawnień dostępu do tej strony wiki - unexpected: Wystąpił nieoczekiwany błąd - page_link_component: - remove: Usuń link do strony - relation_page_links_component: - link_existing: Istniejąca strona wiki - link_new: Nowa strona wiki - empty_heading: Brak powiązanych stron - empty_text: Ręcznie dodaj linki do innych powiązanych stron wiki. - oauth_login_component: - heading: Nie połączono z %{provider} - description: Zaloguj się do %{provider}, aby przeglądać strony wiki powiązane z tym wystąpieniem OpenProject i zarządzać nimi. - connect_button: Podłącz konto %{provider} admin: destroy_confirmation_dialog_component: - title: Usuń dostawcę wiki - heading: Czy trwale usunąć tego dostawcę wiki? description_html: Zostanie usunięty dostawca wiki %{wiki_provider} i wszystkie powiązane linki do stron wiki. Ponadto nie będzie już dostępny żaden link do strony wiki. To działanie jest nieodwracalne. + heading: Czy trwale usunąć tego dostawcę wiki? + title: Usuń dostawcę wiki forms: general_info_form_component: provider_description: Przed wykonaniem konfiguracji upewnij się, że masz uprawnienia administracyjne w swoim wystąpieniu XWiki. @@ -122,6 +73,12 @@ pl: no_health_report: Brak dostępnych raportów no_health_report_description: Uruchom kontrole teraz, aby uzyskać pełny raport o stanie tego dostawcy wiki. title: Raport o stanie + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: To działanie spowoduje zresetowanie bieżących poświadczeń OAuth. Po potwierdzeniu trzeba będzie ponownie wprowadzić poświadczenia w swoim wystąpieniu XWiki, a wszyscy użytkownicy będą musieli dokonać ponownej autoryzacji. Czy na pewno chcesz kontynuować? label_oauth_client_id: Identyfikator klienta OAuth @@ -166,3 +123,61 @@ pl: openproject_oauth_description: Zezwalaj XWiki na dostęp do danych OpenProject za pomocą OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Zezwalaj OpenProject na dostęp do danych XWiki za pomocą OAuth. + buttons: + connect_account: Podłącz konto %{provider} + done_continue: Gotowe, kontynuuj + open_wiki: Otwórz wiki + save_and_continue: Zapisz i kontynuuj + wiki_page: Strona wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Usunąć powiązany link do strony wiki? + title: Usuń powiązany link do strony wiki + health_checks: + authentication: + existing_token: Token użytkownika + header: Uwierzytelnianie + user_bound_request: Uwierzytelnianie żądań po stronie użytkownika + base_configuration: + header: Konfiguracja + provider_configured: Ukończono konfigurację + errors: + not_configured: Nie można zweryfikować połączenia. Najpierw zakończ konfigurację. + xwiki_oauth_connection_error: OpenProject nie może połączyć się ze skonfigurowanym wystąpieniem XWiki. + xwiki_oauth_request_error: Podczas próby komunikacji z wystąpieniem XWiki wystąpił nieoczekiwany błąd. + xwiki_oauth_token_missing: Aplikacja OpenProject nie może przetestować komunikacji z XWiki na poziomie użytkownika, ponieważ użytkownik nie powiązał jeszcze swojego konta XWiki. + xwiki_oauth_unauthorized: Token użytkownika nie został rozpoznany przez XWiki. + instructions: + xwiki: + integration: Administracja XWiki + oauth_application_details_html: Wartość klucza tajnego klienta nie będzie ponownie dostępna po zamknięciu tego okna. Skopiuj te wartości do [ustawień integracji XWiki z OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Dodaj istniejącą stronę wiki + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Podłącz konto %{provider} + description: Zaloguj się do %{provider}, aby przeglądać strony wiki powiązane z tym wystąpieniem OpenProject i zarządzać nimi. + heading: Nie połączono z %{provider} + page_link_component: + remove: Usuń link do strony + page_links: + errors: + page_access_forbidden: Nie masz uprawnień dostępu do tej strony wiki + page_not_found: Powiązana linkiem strona wiki nie jest już dostępna + unexpected: Wystąpił nieoczekiwany błąd + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Brak powiązanych stron + empty_text: Ręcznie dodaj linki do innych powiązanych stron wiki. + link_existing: Istniejąca strona wiki + link_new: Nowa strona wiki + work_package_wikis_tab_component: + inline_page_links: Wbudowane linki strony + referencing_pages: Wymieniono w diff --git a/modules/wikis/config/locales/crowdin/pt-BR.yml b/modules/wikis/config/locales/crowdin/pt-BR.yml index 4bdd52e20d4..f1f519a5b4c 100644 --- a/modules/wikis/config/locales/crowdin/pt-BR.yml +++ b/modules/wikis/config/locales/crowdin/pt-BR.yml @@ -31,68 +31,19 @@ pt-BR: wikis/xwiki_provider: one: Provedor de Xwiki other: Provedores de Xwiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Gerenciar links da página Wiki project_module_wiki_platforms: Provedores de wiki wikis: - buttons: - connect_account: Conectar conta %{provider} - done_continue: Pronto, continuar - open_wiki: Abrir Wiki - save_and_continue: Salvar e continuar - wiki_page: Página wiki - instructions: - xwiki: - integration: Administração do XWiki - oauth_application_details_html: O valor do segredo do cliente não poderá ser acessado novamente depois que você fechar esta janela. Copie esses valores para as [configurações de integração XWiki OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Excluir link da página wiki relacionada - heading: Excluir link da página wiki relacionada? - health_checks: - authentication: - existing_token: Token do usuário - header: Autenticação - user_bound_request: Autenticação de solicitação baseada no usuário - base_configuration: - header: Configuração - provider_configured: Configuração concluída - errors: - not_configured: Não foi possível validar a conexão. Primeiro, conclua a configuração. - xwiki_oauth_connection_error: O OpenProject não conseguiu se conectar à instância do XWiki configurada. - xwiki_oauth_request_error: Ocorreu um erro inesperado ao tentar comunicar com a instância do XWiki. - xwiki_oauth_token_missing: O OpenProject não pode testar a comunicação ao nível do utilizador com o XWiki, pois o utilizador ainda não conectou a sua conta XWiki. - xwiki_oauth_unauthorized: O token do utilizador não foi reconhecido pelo XWiki. - link_existing_wiki_page_dialog: - title: Adicionar página wiki existente - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Links de página embutidos - referencing_pages: Referenciado em - page_links: - errors: - page_not_found: Página wiki vinculada não está mais disponível - page_access_forbidden: Você não tem permissão para acessar esta página wiki - unexpected: Ocorreu um erro inesperado - page_link_component: - remove: Remover link de página - relation_page_links_component: - link_existing: Página wiki existente - link_new: Nova página da wiki - empty_heading: Nenhuma página relacionada - empty_text: Adicionar manualmente links para outras páginas wiki relacionadas. - oauth_login_component: - heading: Não conectado a %{provider} - description: Faça login em %{provider} para visualizar e gerenciar páginas wiki relacionadas nesta instância do OpenProject. - connect_button: Conectar conta %{provider} admin: destroy_confirmation_dialog_component: - title: Excluir provedor wiki - heading: Excluir este provedor de wiki de forma permanente? description_html: O provedor de wiki %{wiki_provider} e todos os links de páginas wiki relacionados serão excluídos. Além disso, todos os links inline de páginas wiki deixarão de estar acessíveis. Esta ação é irreversível. + heading: Excluir este provedor de wiki de forma permanente? + title: Excluir provedor wiki forms: general_info_form_component: provider_description: Certifique-se de que você tem privilégios de administração na sua instância XWiki antes de realizar a configuração. @@ -114,6 +65,12 @@ pt-BR: no_health_report: Nenhum relatório disponível no_health_report_description: Executar as verificações agora para obter um relatório completo de estado de saúde deste provedor de wiki. title: Relatório de integridade + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Esta ação irá redefinir as credenciais OAuth atuais. Após confirmar, será necessário inserir novamente as credenciais na sua instância do XWiki e todos os usuários terão de reautorizar. Tem certeza de que deseja continuar? label_oauth_client_id: ID do cliente OAuth @@ -158,3 +115,61 @@ pt-BR: openproject_oauth_description: Permitir que o XWiki acesse dados do OpenProject usando OAuth. xwiki_oauth: OAuth do XWiki xwiki_oauth_description: Permitir que o OpenProject acesse dados do XWiki usando OAuth. + buttons: + connect_account: Conectar conta %{provider} + done_continue: Pronto, continuar + open_wiki: Abrir Wiki + save_and_continue: Salvar e continuar + wiki_page: Página wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Excluir link da página wiki relacionada? + title: Excluir link da página wiki relacionada + health_checks: + authentication: + existing_token: Token do usuário + header: Autenticação + user_bound_request: Autenticação de solicitação baseada no usuário + base_configuration: + header: Configuração + provider_configured: Configuração concluída + errors: + not_configured: Não foi possível validar a conexão. Primeiro, conclua a configuração. + xwiki_oauth_connection_error: O OpenProject não conseguiu se conectar à instância do XWiki configurada. + xwiki_oauth_request_error: Ocorreu um erro inesperado ao tentar comunicar com a instância do XWiki. + xwiki_oauth_token_missing: O OpenProject não pode testar a comunicação ao nível do utilizador com o XWiki, pois o utilizador ainda não conectou a sua conta XWiki. + xwiki_oauth_unauthorized: O token do utilizador não foi reconhecido pelo XWiki. + instructions: + xwiki: + integration: Administração do XWiki + oauth_application_details_html: O valor do segredo do cliente não poderá ser acessado novamente depois que você fechar esta janela. Copie esses valores para as [configurações de integração XWiki OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Adicionar página wiki existente + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Conectar conta %{provider} + description: Faça login em %{provider} para visualizar e gerenciar páginas wiki relacionadas nesta instância do OpenProject. + heading: Não conectado a %{provider} + page_link_component: + remove: Remover link de página + page_links: + errors: + page_access_forbidden: Você não tem permissão para acessar esta página wiki + page_not_found: Página wiki vinculada não está mais disponível + unexpected: Ocorreu um erro inesperado + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Nenhuma página relacionada + empty_text: Adicionar manualmente links para outras páginas wiki relacionadas. + link_existing: Página wiki existente + link_new: Nova página da wiki + work_package_wikis_tab_component: + inline_page_links: Links de página embutidos + referencing_pages: Referenciado em diff --git a/modules/wikis/config/locales/crowdin/pt-PT.yml b/modules/wikis/config/locales/crowdin/pt-PT.yml index 64b32b3283a..c006a227f04 100644 --- a/modules/wikis/config/locales/crowdin/pt-PT.yml +++ b/modules/wikis/config/locales/crowdin/pt-PT.yml @@ -31,68 +31,19 @@ pt-PT: wikis/xwiki_provider: one: Fornecedor XWiki other: Fornecedores XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Gerir ligações de páginas Wiki project_module_wiki_platforms: Fornecedor de wiki wikis: - buttons: - connect_account: Ligar a conta %{provider} - done_continue: Concluído, continuar - open_wiki: Abrir wiki - save_and_continue: Guardar e continuar - wiki_page: Página wiki - instructions: - xwiki: - integration: Administração de XWiki - oauth_application_details_html: O valor do segredo do cliente deixará de estar acessível depois de fechar esta janela. Copie estes valores para as [Definições de integração do XWiki com o OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Eliminar a ligação à página wiki relacionada - heading: Eliminar a ligação à página wiki relacionada? - health_checks: - authentication: - existing_token: Token de utilizador - header: Autenticação - user_bound_request: Autenticação da solicitação com base no utilizador - base_configuration: - header: Configuração - provider_configured: Configuração concluída - errors: - not_configured: Não foi possível validar a ligação. Termine primeiro a configuração. - xwiki_oauth_connection_error: O OpenProject não conseguiu ligar-se à instância XWiki configurada. - xwiki_oauth_request_error: Ocorreu um erro inesperado ao tentar comunicar com a instância XWiki. - xwiki_oauth_token_missing: OpenProject não pode testar a comunicação ao nível do utilizador com o XWiki porque o utilizador ainda não ligou a sua conta XWiki. - xwiki_oauth_unauthorized: O token de utilizador não foi reconhecido pelo XWiki. - link_existing_wiki_page_dialog: - title: Adicionar uma página wiki existente - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Ligações diretas de página - referencing_pages: Referenciado em - page_links: - errors: - page_not_found: A página wiki ligada já não está disponível - page_access_forbidden: Não tem permissão para aceder a esta página wiki - unexpected: Ocorreu um erro inesperado - page_link_component: - remove: Remover ligação da página - relation_page_links_component: - link_existing: Página wiki existente - link_new: Nova página wiki - empty_heading: Nenhuma página relacionada - empty_text: Adicionar manualmente ligações a outras páginas wiki relacionadas. - oauth_login_component: - heading: Não ligado a %{provider} - description: Inicie sessão em %{provider} para ver e gerir as páginas wiki relacionadas com esta instância do OpenProject. - connect_button: Ligar a conta %{provider} admin: destroy_confirmation_dialog_component: - title: Eliminar fornecedor de wiki - heading: Eliminar permanentemente este fornecedor de wiki? description_html: O fornecedor de wiki %{wiki_provider} e todas as ligações relacionadas com páginas wiki serão eliminados. Além disso, todas as ligações em linha para páginas wiki deixarão de estar acessíveis. Esta ação é irreversível. + heading: Eliminar permanentemente este fornecedor de wiki? + title: Eliminar fornecedor de wiki forms: general_info_form_component: provider_description: Confirme se tem privilégios de administração na sua instância XWiki antes de fazer a configuração. @@ -114,6 +65,12 @@ pt-PT: no_health_report: Nenhum relatório disponível no_health_report_description: Execute agora as verificações para obter um relatório de estado de saúde completo para este fornecedor de wiki. title: Relatório de saúde + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Esta ação irá repor as credenciais OAuth atuais. Depois de confirmar, terá de voltar a introduzir as credenciais na sua instância XWiki, e todos os utilizadores terão de voltar a autorizar. Tem a certeza de que quer continuar? label_oauth_client_id: ID de Cliente OAuth @@ -158,3 +115,61 @@ pt-PT: openproject_oauth_description: Permitir que XWiki aceda aos dados do OpenProject com um OAuth. xwiki_oauth: OAuth XWiki xwiki_oauth_description: Permita que o OpenProject aceda aos dados do XWiki com um OAuth. + buttons: + connect_account: Ligar a conta %{provider} + done_continue: Concluído, continuar + open_wiki: Abrir wiki + save_and_continue: Guardar e continuar + wiki_page: Página wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Eliminar a ligação à página wiki relacionada? + title: Eliminar a ligação à página wiki relacionada + health_checks: + authentication: + existing_token: Token de utilizador + header: Autenticação + user_bound_request: Autenticação da solicitação com base no utilizador + base_configuration: + header: Configuração + provider_configured: Configuração concluída + errors: + not_configured: Não foi possível validar a ligação. Termine primeiro a configuração. + xwiki_oauth_connection_error: O OpenProject não conseguiu ligar-se à instância XWiki configurada. + xwiki_oauth_request_error: Ocorreu um erro inesperado ao tentar comunicar com a instância XWiki. + xwiki_oauth_token_missing: OpenProject não pode testar a comunicação ao nível do utilizador com o XWiki porque o utilizador ainda não ligou a sua conta XWiki. + xwiki_oauth_unauthorized: O token de utilizador não foi reconhecido pelo XWiki. + instructions: + xwiki: + integration: Administração de XWiki + oauth_application_details_html: O valor do segredo do cliente deixará de estar acessível depois de fechar esta janela. Copie estes valores para as [Definições de integração do XWiki com o OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Adicionar uma página wiki existente + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Ligar a conta %{provider} + description: Inicie sessão em %{provider} para ver e gerir as páginas wiki relacionadas com esta instância do OpenProject. + heading: Não ligado a %{provider} + page_link_component: + remove: Remover ligação da página + page_links: + errors: + page_access_forbidden: Não tem permissão para aceder a esta página wiki + page_not_found: A página wiki ligada já não está disponível + unexpected: Ocorreu um erro inesperado + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Nenhuma página relacionada + empty_text: Adicionar manualmente ligações a outras páginas wiki relacionadas. + link_existing: Página wiki existente + link_new: Nova página wiki + work_package_wikis_tab_component: + inline_page_links: Ligações diretas de página + referencing_pages: Referenciado em diff --git a/modules/wikis/config/locales/crowdin/ro.yml b/modules/wikis/config/locales/crowdin/ro.yml index f74bc677a3a..74bca6dbb1d 100644 --- a/modules/wikis/config/locales/crowdin/ro.yml +++ b/modules/wikis/config/locales/crowdin/ro.yml @@ -35,68 +35,19 @@ ro: one: XWiki provider few: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -118,6 +69,12 @@ ro: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -162,3 +119,61 @@ ro: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/ru.yml b/modules/wikis/config/locales/crowdin/ru.yml index 19f09b99d9e..b4390744af9 100644 --- a/modules/wikis/config/locales/crowdin/ru.yml +++ b/modules/wikis/config/locales/crowdin/ru.yml @@ -39,68 +39,19 @@ ru: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Управление ссылками Вики-страницы project_module_wiki_platforms: Провайдеры вики wikis: - buttons: - connect_account: Подключите учетную запись %{provider} - done_continue: Готово, продолжить - open_wiki: Open wiki - save_and_continue: Сохранить и продолжить - wiki_page: Wiki-страница - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Ссылки на внутренние страницы - referencing_pages: Ссылается в - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Удалить ссылку на страницу - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: Нет связанных страниц - empty_text: Добавьте ссылки вручную на другие связанные вики-страницы. - oauth_login_component: - heading: Не подключен к %{provider} - description: Войдите в %{provider} для просмотра и управления связанными страницами вики из этого экземпляра OpenProject. - connect_button: Подключить учетную запись %{provider} admin: destroy_confirmation_dialog_component: - title: Удалить вики-провайдера - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Удалить вики-провайдера forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ ru: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Это действие сбросит текущие учетные данные OAuth. После подтверждения Вам придется заново ввести учетные данные в Вашем экземпляре XWiki, а все пользователи должны будут заново авторизоваться. Вы уверены, что хотите продолжить? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ ru: openproject_oauth_description: Разрешить XWiki доступ к данным OpenProject с помощью OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Разрешить OpenProject доступ к данным XWiki с помощью OAuth. + buttons: + connect_account: Подключите учетную запись %{provider} + done_continue: Готово, продолжить + open_wiki: Open wiki + save_and_continue: Сохранить и продолжить + wiki_page: Wiki-страница + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Подключить учетную запись %{provider} + description: Войдите в %{provider} для просмотра и управления связанными страницами вики из этого экземпляра OpenProject. + heading: Не подключен к %{provider} + page_link_component: + remove: Удалить ссылку на страницу + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Нет связанных страниц + empty_text: Добавьте ссылки вручную на другие связанные вики-страницы. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Ссылки на внутренние страницы + referencing_pages: Ссылается в diff --git a/modules/wikis/config/locales/crowdin/rw.yml b/modules/wikis/config/locales/crowdin/rw.yml index 7820df2c68c..efc1d80676f 100644 --- a/modules/wikis/config/locales/crowdin/rw.yml +++ b/modules/wikis/config/locales/crowdin/rw.yml @@ -31,68 +31,19 @@ rw: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ rw: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ rw: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/si.yml b/modules/wikis/config/locales/crowdin/si.yml index 31280d78cd3..f53b1f2b09b 100644 --- a/modules/wikis/config/locales/crowdin/si.yml +++ b/modules/wikis/config/locales/crowdin/si.yml @@ -31,68 +31,19 @@ si: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ si: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ si: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/sk.yml b/modules/wikis/config/locales/crowdin/sk.yml index 82c6464c1ce..1c80e27deb4 100644 --- a/modules/wikis/config/locales/crowdin/sk.yml +++ b/modules/wikis/config/locales/crowdin/sk.yml @@ -39,68 +39,19 @@ sk: few: XWiki providers many: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ sk: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ sk: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/sl.yml b/modules/wikis/config/locales/crowdin/sl.yml index 4512f116172..7fe7d06e408 100644 --- a/modules/wikis/config/locales/crowdin/sl.yml +++ b/modules/wikis/config/locales/crowdin/sl.yml @@ -39,68 +39,19 @@ sl: two: XWiki providers few: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -122,6 +73,12 @@ sl: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -166,3 +123,61 @@ sl: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/sr.yml b/modules/wikis/config/locales/crowdin/sr.yml index 406b29ad0b6..bc515265805 100644 --- a/modules/wikis/config/locales/crowdin/sr.yml +++ b/modules/wikis/config/locales/crowdin/sr.yml @@ -35,68 +35,19 @@ sr: one: XWiki provider few: XWiki providers other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -118,6 +69,12 @@ sr: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -162,3 +119,61 @@ sr: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/sv.yml b/modules/wikis/config/locales/crowdin/sv.yml index 38a7831771a..3a7a57526fd 100644 --- a/modules/wikis/config/locales/crowdin/sv.yml +++ b/modules/wikis/config/locales/crowdin/sv.yml @@ -31,68 +31,19 @@ sv: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ sv: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ sv: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/th.yml b/modules/wikis/config/locales/crowdin/th.yml index 620622e4b6f..988f9ca749e 100644 --- a/modules/wikis/config/locales/crowdin/th.yml +++ b/modules/wikis/config/locales/crowdin/th.yml @@ -27,68 +27,19 @@ th: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ th: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ th: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/tr.yml b/modules/wikis/config/locales/crowdin/tr.yml index a2caa13abd3..13e9f375f00 100644 --- a/modules/wikis/config/locales/crowdin/tr.yml +++ b/modules/wikis/config/locales/crowdin/tr.yml @@ -31,68 +31,19 @@ tr: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ tr: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ tr: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/uk.yml b/modules/wikis/config/locales/crowdin/uk.yml index 4aba6bdb7b8..b5ff79efbb6 100644 --- a/modules/wikis/config/locales/crowdin/uk.yml +++ b/modules/wikis/config/locales/crowdin/uk.yml @@ -39,68 +39,19 @@ uk: few: Постачальники XWiki many: Постачальники XWiki other: Постачальники XWiki + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Керувати посиланнями на сторінки Wiki project_module_wiki_platforms: Постачальники Wiki wikis: - buttons: - connect_account: Підключити обліковий запис %{provider} - done_continue: Виконано, продовжити - open_wiki: Відкрити Wiki - save_and_continue: Зберегти та продовжити - wiki_page: Сторінка Wiki - instructions: - xwiki: - integration: Адміністрування XWiki - oauth_application_details_html: Секретний ключ клієнта знову стане недоступним, коли ви закриєте це вікно. Скопіюйте ці значення в [налаштування інтеграції XWiki з OpenProject](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Видалити посилання на пов’язану сторінку Wiki - heading: Видалити посилання на пов’язану сторінку Wiki? - health_checks: - authentication: - existing_token: Маркер користувача - header: Автентифікація - user_bound_request: Автентифікація запиту за користувачем - base_configuration: - header: Конфігурація - provider_configured: Конфігурацію налаштовано - errors: - not_configured: Не вдалося перевірити підключення. Спочатку налаштуйте конфігурацію. - xwiki_oauth_connection_error: OpenProject не вдалося під’єднатися до налаштованого екземпляра XWiki. - xwiki_oauth_request_error: Під час спроби зв’язатися з екземпляром XWiki сталася несподівана помилка. - xwiki_oauth_token_missing: OpenProject не може перевірити з’єднання на рівні користувача з XWiki, оскільки користувач досі не підключив свій обліковий запис XWiki. - xwiki_oauth_unauthorized: Платформа XWiki не розпізнала маркер користувача. - link_existing_wiki_page_dialog: - title: Додати наявну сторінку Wiki - link_existing_wiki_page_form: - no_results: Не знайдено сторінок Wiki - placeholder: Шукати сторінку Wiki - work_package_wikis_tab_component: - inline_page_links: Вставлені посилання на сторінку - referencing_pages: Додано посилання в - page_links: - errors: - page_not_found: Зв’язана сторінка Wiki більше не доступна - page_access_forbidden: У вас немає дозволу на доступ до цієї сторінки Wiki - unexpected: Сталася неочікувана помилка - page_link_component: - remove: Видалити посилання на сторінку - relation_page_links_component: - link_existing: Наявна сторінка Wiki - link_new: Нова сторінка Wiki - empty_heading: Немає пов’язаних сторінок - empty_text: Додайте посилання на інші пов’язані сторінки Wiki вручну. - oauth_login_component: - heading: Немає підключення до сервісу %{provider} - description: Увійдіть у сервіс %{provider}, щоб переглядати пов’язані сторінки Wiki й керувати ними із цього екземпляра OpenProject. - connect_button: Підключити обліковий запис %{provider} admin: destroy_confirmation_dialog_component: - title: Видалити постачальника Wiki - heading: Видалити цього постачальника Wiki остаточно? description_html: Постачальника Wiki %{wiki_provider} і всі посилання на пов’язані сторінки Wiki буде видалено. Крім того, кожне вставлене посилання на сторінку Wiki більше не працюватиме. Ця дія є незворотною. + heading: Видалити цього постачальника Wiki остаточно? + title: Видалити постачальника Wiki forms: general_info_form_component: provider_description: Переконайтеся, що ви маєте права адміністратора у своєму екземплярі XWiki, перш ніж виконувати налаштування. @@ -122,6 +73,12 @@ uk: no_health_report: Немає доступних звітів no_health_report_description: Запустіть перевірки, щоб отримати комплексний звіт про стан справності цього постачальника Wiki. title: Звіт про справність + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: Ця дія призведе до скидання поточних облікових даних OAuth. Коли ви підтвердите дію, вам потрібно буде повторно ввести облікові дані у своєму екземплярі XWiki. У такому разі всім користувачам знадобиться знову пройти авторизацію. Продовжити? label_oauth_client_id: Ідентифікатор клієнта OAuth @@ -166,3 +123,61 @@ uk: openproject_oauth_description: Надайте XWiki доступ до даних OpenProject за допомогою OAuth. xwiki_oauth: OAuth для XWiki xwiki_oauth_description: Надайте OpenProject доступ до даних XWiki за допомогою OAuth. + buttons: + connect_account: Підключити обліковий запис %{provider} + done_continue: Виконано, продовжити + open_wiki: Відкрити Wiki + save_and_continue: Зберегти та продовжити + wiki_page: Сторінка Wiki + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Видалити посилання на пов’язану сторінку Wiki? + title: Видалити посилання на пов’язану сторінку Wiki + health_checks: + authentication: + existing_token: Маркер користувача + header: Автентифікація + user_bound_request: Автентифікація запиту за користувачем + base_configuration: + header: Конфігурація + provider_configured: Конфігурацію налаштовано + errors: + not_configured: Не вдалося перевірити підключення. Спочатку налаштуйте конфігурацію. + xwiki_oauth_connection_error: OpenProject не вдалося під’єднатися до налаштованого екземпляра XWiki. + xwiki_oauth_request_error: Під час спроби зв’язатися з екземпляром XWiki сталася несподівана помилка. + xwiki_oauth_token_missing: OpenProject не може перевірити з’єднання на рівні користувача з XWiki, оскільки користувач досі не підключив свій обліковий запис XWiki. + xwiki_oauth_unauthorized: Платформа XWiki не розпізнала маркер користувача. + instructions: + xwiki: + integration: Адміністрування XWiki + oauth_application_details_html: Секретний ключ клієнта знову стане недоступним, коли ви закриєте це вікно. Скопіюйте ці значення в [налаштування інтеграції XWiki з OpenProject](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Додати наявну сторінку Wiki + link_existing_wiki_page_form: + no_results: Не знайдено сторінок Wiki + placeholder: Шукати сторінку Wiki + oauth_login_component: + connect_button: Підключити обліковий запис %{provider} + description: Увійдіть у сервіс %{provider}, щоб переглядати пов’язані сторінки Wiki й керувати ними із цього екземпляра OpenProject. + heading: Немає підключення до сервісу %{provider} + page_link_component: + remove: Видалити посилання на сторінку + page_links: + errors: + page_access_forbidden: У вас немає дозволу на доступ до цієї сторінки Wiki + page_not_found: Зв’язана сторінка Wiki більше не доступна + unexpected: Сталася неочікувана помилка + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: Немає пов’язаних сторінок + empty_text: Додайте посилання на інші пов’язані сторінки Wiki вручну. + link_existing: Наявна сторінка Wiki + link_new: Нова сторінка Wiki + work_package_wikis_tab_component: + inline_page_links: Вставлені посилання на сторінку + referencing_pages: Додано посилання в diff --git a/modules/wikis/config/locales/crowdin/uz.yml b/modules/wikis/config/locales/crowdin/uz.yml index ede1fdbf7c4..388ced0b3a1 100644 --- a/modules/wikis/config/locales/crowdin/uz.yml +++ b/modules/wikis/config/locales/crowdin/uz.yml @@ -31,68 +31,19 @@ uz: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -114,6 +65,12 @@ uz: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -158,3 +115,61 @@ uz: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/vi.yml b/modules/wikis/config/locales/crowdin/vi.yml index 64873070a58..a9d144c410a 100644 --- a/modules/wikis/config/locales/crowdin/vi.yml +++ b/modules/wikis/config/locales/crowdin/vi.yml @@ -27,68 +27,19 @@ vi: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Cấu hình - provider_configured: Cấu hình complete - errors: - not_configured: The connection could not be validated. Please finish cấu hình first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ vi: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ vi: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Cấu hình + provider_configured: Cấu hình complete + errors: + not_configured: The connection could not be validated. Please finish cấu hình first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/crowdin/zh-CN.yml b/modules/wikis/config/locales/crowdin/zh-CN.yml index ba20a0f06bb..96f5b3537e8 100644 --- a/modules/wikis/config/locales/crowdin/zh-CN.yml +++ b/modules/wikis/config/locales/crowdin/zh-CN.yml @@ -35,68 +35,19 @@ zh-CN: XWiki 提供商 Other XWiki 提供商 + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: 管理 Wiki 页面链接 project_module_wiki_platforms: Wiki 提供商 wikis: - buttons: - connect_account: 连接 %{provider} 帐户 - done_continue: 完成, 继续 - open_wiki: 打开 wiki - save_and_continue: 保存并继续 - wiki_page: Wiki 页面 - instructions: - xwiki: - integration: XWiki 管理 - oauth_application_details_html: 关闭此窗口后,将无法再次访问客户端密钥值。请将这些值复制到 [XWiki OpenProject 集成设置](xwiki_admin_link)中。 - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: 删除相关 wiki 页面链接 - heading: 是否删除相关 wiki 页面链接? - health_checks: - authentication: - existing_token: 用户令牌 - header: 身份验证 - user_bound_request: 基于用户的请求身份验证 - base_configuration: - header: 配置 - provider_configured: 配置完成 - errors: - not_configured: 无法验证关联。请先完成配置。 - xwiki_oauth_connection_error: OpenProject 无法关联到已配置的 XWiki 实例。 - xwiki_oauth_request_error: 尝试与 XWiki 实例通信时发生意外错误。 - xwiki_oauth_token_missing: OpenProject 无法测试用户与 XWiki 的用户级通信,因为用户尚未关联他们的 XWiki 帐户。 - xwiki_oauth_unauthorized: XWiki 未识别用户令牌。 - link_existing_wiki_page_dialog: - title: 添加现有 wiki 页面 - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: 内联页面链接 - referencing_pages: 引用于 - page_links: - errors: - page_not_found: 关联的 wiki 页面不再可用 - page_access_forbidden: 您无权访问此 wiki 页面 - unexpected: 发生意外错误 - page_link_component: - remove: 删除页面链接 - relation_page_links_component: - link_existing: 现有 wiki 页面 - link_new: 新 wiki 页面 - empty_heading: 无相关页面 - empty_text: 手动添加链接到其他相关Wiki页面。 - oauth_login_component: - heading: 未连接至 %{provider} - description: 登录 %{provider} ,查看和管理此 OpenProject 实例的相关Wiki页面。 - connect_button: 连接 %{provider} 账户 admin: destroy_confirmation_dialog_component: - title: 删除 wiki 提供商 - heading: 是否永久删除此 wiki 提供商? description_html: Wiki 提供商 %{wiki_provider} 和所有相关的 wiki 页面链接将被删除。此外,每个内联 wiki 页面链接也将无法再访问。此操作无法撤消。 + heading: 是否永久删除此 wiki 提供商? + title: 删除 wiki 提供商 forms: general_info_form_component: provider_description: 在进行设置之前,请确保您在 XWiki 实例中具有管理权限。 @@ -118,6 +69,12 @@ zh-CN: no_health_report: 无可用报告 no_health_report_description: 立即运行检查,以获取此 wiki 提供商的完整健康状态报告。 title: 健康报告 + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: 此操作将重置当前的 OAuth 凭据。确认后,您必须在 XWiki 实例中重新输入凭据,所有用户都必须重新授权。确定要继续吗? label_oauth_client_id: OAuth 客户端 ID @@ -162,3 +119,61 @@ zh-CN: openproject_oauth_description: 允许 XWiki 使用 OAuth 访问 OpenProject 数据。 xwiki_oauth: XWiki OAuth xwiki_oauth_description: 允许 OpenProject 使用 OAuth 访问 XWiki 数据。 + buttons: + connect_account: 连接 %{provider} 帐户 + done_continue: 完成, 继续 + open_wiki: 打开 wiki + save_and_continue: 保存并继续 + wiki_page: Wiki 页面 + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: 是否删除相关 wiki 页面链接? + title: 删除相关 wiki 页面链接 + health_checks: + authentication: + existing_token: 用户令牌 + header: 身份验证 + user_bound_request: 基于用户的请求身份验证 + base_configuration: + header: 配置 + provider_configured: 配置完成 + errors: + not_configured: 无法验证关联。请先完成配置。 + xwiki_oauth_connection_error: OpenProject 无法关联到已配置的 XWiki 实例。 + xwiki_oauth_request_error: 尝试与 XWiki 实例通信时发生意外错误。 + xwiki_oauth_token_missing: OpenProject 无法测试用户与 XWiki 的用户级通信,因为用户尚未关联他们的 XWiki 帐户。 + xwiki_oauth_unauthorized: XWiki 未识别用户令牌。 + instructions: + xwiki: + integration: XWiki 管理 + oauth_application_details_html: 关闭此窗口后,将无法再次访问客户端密钥值。请将这些值复制到 [XWiki OpenProject 集成设置](xwiki_admin_link)中。 + link_existing_wiki_page_dialog: + title: 添加现有 wiki 页面 + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: 连接 %{provider} 账户 + description: 登录 %{provider} ,查看和管理此 OpenProject 实例的相关Wiki页面。 + heading: 未连接至 %{provider} + page_link_component: + remove: 删除页面链接 + page_links: + errors: + page_access_forbidden: 您无权访问此 wiki 页面 + page_not_found: 关联的 wiki 页面不再可用 + unexpected: 发生意外错误 + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: 无相关页面 + empty_text: 手动添加链接到其他相关Wiki页面。 + link_existing: 现有 wiki 页面 + link_new: 新 wiki 页面 + work_package_wikis_tab_component: + inline_page_links: 内联页面链接 + referencing_pages: 引用于 diff --git a/modules/wikis/config/locales/crowdin/zh-TW.yml b/modules/wikis/config/locales/crowdin/zh-TW.yml index 5d1f038703c..683f27ccd08 100644 --- a/modules/wikis/config/locales/crowdin/zh-TW.yml +++ b/modules/wikis/config/locales/crowdin/zh-TW.yml @@ -27,68 +27,19 @@ zh-TW: other: Relation page links wikis/xwiki_provider: other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: Wikis permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -110,6 +61,12 @@ zh-TW: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -154,3 +111,61 @@ zh-TW: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/locales/en.yml b/modules/wikis/config/locales/en.yml index be289ec942f..b67984ec956 100644 --- a/modules/wikis/config/locales/en.yml +++ b/modules/wikis/config/locales/en.yml @@ -31,70 +31,21 @@ en: wikis/xwiki_provider: one: XWiki provider other: XWiki providers + menus: + admin: + external_wiki_providers: Wiki providers + internal_wiki_provider: Internal wiki + wikis: "Wikis" permission_manage_wiki_page_links: Manage Wiki Page Links project_module_wiki_platforms: Wiki providers wikis: - buttons: - connect_account: Connect %{provider} account - done_continue: Done, continue - open_wiki: Open wiki - save_and_continue: Save and continue - wiki_page: Wiki page - instructions: - xwiki: - integration: XWiki Administration - oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). - provider_types: - xwiki: - name: XWiki - delete_relation_page_link_confirmation_dialog: - title: Delete related wiki page link - heading: Delete related wiki page link? - health_checks: - authentication: - existing_token: User token - header: Authentication - user_bound_request: User-based request authentication - base_configuration: - header: Configuration - provider_configured: Configuration complete - errors: - not_configured: The connection could not be validated. Please finish configuration first. - xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. - xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. - xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. - xwiki_oauth_unauthorized: The user token was not recognized by XWiki. - link_existing_wiki_page_dialog: - title: Add existing wiki page - link_existing_wiki_page_form: - no_results: No wiki pages found - placeholder: Search for a wiki page - work_package_wikis_tab_component: - inline_page_links: Inline page links - referencing_pages: Referenced in - page_links: - errors: - page_not_found: Linked wiki page no longer available - page_access_forbidden: You do not have permission to access this wiki page - unexpected: An unexpected error occurred - page_link_component: - remove: Remove page link - relation_page_links_component: - link_existing: Existing wiki page - link_new: New wiki page - empty_heading: No related pages - empty_text: Manually add links to other related wiki pages. - oauth_login_component: - heading: Not connected to %{provider} - description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. - connect_button: Connect %{provider} account admin: destroy_confirmation_dialog_component: - title: Delete wiki provider - heading: Permanently delete this wiki provider? description_html: >- The wiki provider %{wiki_provider} and all the related wiki page links will be deleted. In addition, every inline wiki page link will no longer be accessible. This action is irreversible. + heading: Permanently delete this wiki provider? + title: Delete wiki provider forms: general_info_form_component: provider_description: Please make sure you have administration privileges in your XWiki instance before doing the setup. @@ -116,6 +67,12 @@ en: no_health_report: No report available no_health_report_description: Run the checks now for a full health status report for this wiki provider. title: Health Report + internal_provider_form: + checkbox_caption: Allow projects to use the internal OpenProject wiki along with external Wiki providers + checkbox_label: Enable the internal OpenProject wiki + internal_wiki_provider: + show: + description: Choose to enable or disable the internal OpenProject wiki oauth_application_info_component: confirm_replace_oauth_application: This action will reset the current OAuth credentials. After confirming you will have to reenter the credentials in your XWiki instance and all users will have to reauthorize. Are you sure you want to proceed? label_oauth_client_id: OAuth Client ID @@ -160,3 +117,61 @@ en: openproject_oauth_description: Allow XWiki to access OpenProject data using an OAuth. xwiki_oauth: XWiki OAuth xwiki_oauth_description: Allow OpenProject to access XWiki data using an OAuth. + buttons: + connect_account: Connect %{provider} account + done_continue: Done, continue + open_wiki: Open wiki + save_and_continue: Save and continue + wiki_page: Wiki page + create_new_wiki_page_dialog: + page_title: Title + parent_help_text: Select a parent for this new wiki page. + title: Create new wiki page + delete_relation_page_link_confirmation_dialog: + heading: Delete related wiki page link? + title: Delete related wiki page link + health_checks: + authentication: + existing_token: User token + header: Authentication + user_bound_request: User-based request authentication + base_configuration: + header: Configuration + provider_configured: Configuration complete + errors: + not_configured: The connection could not be validated. Please finish configuration first. + xwiki_oauth_connection_error: OpenProject could not connect to the configured XWiki instance. + xwiki_oauth_request_error: An unexpected error occured when trying to communicate with the XWiki instance. + xwiki_oauth_token_missing: OpenProject cannot test the user-level communication with XWiki as the user did not yet connect their XWiki account. + xwiki_oauth_unauthorized: The user token was not recognized by XWiki. + instructions: + xwiki: + integration: XWiki Administration + oauth_application_details_html: The client secret value will not be accessible again after you close this window. Please copy these values into the [XWiki OpenProject Integration settings](xwiki_admin_link). + link_existing_wiki_page_dialog: + title: Add existing wiki page + link_existing_wiki_page_form: + no_results: No wiki pages found + placeholder: Search for a wiki page + oauth_login_component: + connect_button: Connect %{provider} account + description: Log in to %{provider} to view and manage related wiki pages from this OpenProject instance. + heading: Not connected to %{provider} + page_link_component: + remove: Remove page link + page_links: + errors: + page_access_forbidden: You do not have permission to access this wiki page + page_not_found: Linked wiki page no longer available + unexpected: An unexpected error occurred + provider_types: + xwiki: + name: XWiki + relation_page_links_component: + empty_heading: No related pages + empty_text: Manually add links to other related wiki pages. + link_existing: Existing wiki page + link_new: New wiki page + work_package_wikis_tab_component: + inline_page_links: Inline page links + referencing_pages: Referenced in diff --git a/modules/wikis/config/routes.rb b/modules/wikis/config/routes.rb index 242e3c63458..63a692360c5 100644 --- a/modules/wikis/config/routes.rb +++ b/modules/wikis/config/routes.rb @@ -31,6 +31,7 @@ Rails.application.routes.draw do namespace :admin do namespace :settings do + resource :internal_wiki_provider, controller: "/wikis/admin/internal_wiki_provider", only: %i[show update] resources :wiki_providers, controller: "/wikis/admin/wiki_providers", except: [:show] do member do get :confirm_destroy @@ -73,5 +74,9 @@ Rails.application.routes.draw do get :load end - resource :search_wiki_pages, controller: "wikis/search_pages", only: %i[show] + resource :wiki_pages, controller: "wikis/pages", only: [] do + get :search + get :create_new_page_dialog + post :create_and_link + end end diff --git a/modules/wikis/lib/api/v3/page_links/page_links_api.rb b/modules/wikis/lib/api/v3/page_links/page_links_api.rb index b6a44e086d4..bacde89be2e 100644 --- a/modules/wikis/lib/api/v3/page_links/page_links_api.rb +++ b/modules/wikis/lib/api/v3/page_links/page_links_api.rb @@ -32,6 +32,12 @@ module API module V3 module PageLinks class PageLinksAPI < OpenProjectAPI + helpers do + def enrich_models_with_wiki_metadata(relation) + Wikis::PageLinkMetadataService.new(relation).call + end + end + resources :wiki_page_links do post &::API::V3::PageLinks::CreateEndpoint.new( model: ::Wikis::RelationPageLink, @@ -42,6 +48,28 @@ module API process_contract: ::Wikis::RelationPageLinks::CreateContract, render_representer: PageLinkCollectionRepresenter ).mount + + get do + query = ParamsToQueryService.new( + ::Wikis::PageLink, + current_user, + query_class: ::Queries::Wikis::PageLinks::PageLinkQuery + ).call(params) + + unless query.valid? + message = I18n.t("api_v3.errors.missing_or_malformed_parameter", parameter: "filters") + raise ::API::Errors::InvalidQuery.new(message) + end + + relation = query.results.where(linkable: Authorization.work_packages(:view_work_packages, current_user)) + + PageLinkCollectionRepresenter.new( + enrich_models_with_wiki_metadata(relation).result, + per_page: params[:pageSize], + self_link: api_v3_paths.wiki_page_links, + current_user: + ) + end end end end diff --git a/modules/wikis/lib/open_project/wikis/engine.rb b/modules/wikis/lib/open_project/wikis/engine.rb index 9150153b2a2..a8fc465f60d 100644 --- a/modules/wikis/lib/open_project/wikis/engine.rb +++ b/modules/wikis/lib/open_project/wikis/engine.rb @@ -64,6 +64,7 @@ module OpenProject::Wikis # Registering queries and filters ::Queries::Register.register(::Queries::Wikis::PageLinks::PageLinkQuery) do filter ::Queries::Wikis::PageLinks::Filter::ProviderFilter + filter ::Queries::Wikis::PageLinks::Filter::WikiPageLinkTypeFilter end end @@ -73,7 +74,11 @@ module OpenProject::Wikis project_module :work_package_tracking do permission :manage_wiki_page_links, { - "wikis/relation_page_links": %i[create destroy confirm_delete_dialog link_existing_dialog] + "wikis/pages": %i[create_and_link create_new_page_dialog], + "wikis/relation_page_links": %i[create + destroy + confirm_delete_dialog + link_existing_dialog] }, permissible_on: :project, dependencies: %i[edit_work_packages], @@ -94,9 +99,23 @@ module OpenProject::Wikis menu :admin_menu, :wiki_providers, { controller: "/wikis/admin/wiki_providers", action: :index }, - if: ->(_) { OpenProject::FeatureDecisions.wiki_enhancements_active? }, - caption: :project_module_wiki_platforms, + if: ->(_) { User.current.admin? && OpenProject::FeatureDecisions.wiki_enhancements_active? }, + caption: :"menus.admin.wikis", icon: :book + + menu :admin_menu, + :internal_wiki_provider, + { controller: "/wikis/admin/internal_wiki_provider", action: :show }, + parent: :wiki_providers, + if: ->(_) { User.current.admin? && OpenProject::FeatureDecisions.wiki_enhancements_active? }, + caption: :"menus.admin.internal_wiki_provider" + + menu :admin_menu, + :external_wiki_providers, + { controller: "/wikis/admin/wiki_providers", action: :index }, + parent: :wiki_providers, + if: ->(_) { User.current.admin? && OpenProject::FeatureDecisions.wiki_enhancements_active? }, + caption: :"menus.admin.external_wiki_providers" end patch_with_namespace :WikiPages, :CreateService diff --git a/modules/wikis/spec/features/admin/internal_provider_spec.rb b/modules/wikis/spec/features/admin/internal_provider_spec.rb new file mode 100644 index 00000000000..d3a7c68f6df --- /dev/null +++ b/modules/wikis/spec/features/admin/internal_provider_spec.rb @@ -0,0 +1,63 @@ +# 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 "spec_helper" + +RSpec.describe "Updating internal wiki provider", :js, :selenium, driver: :firefox_en do + shared_let(:admin) { create(:admin, preferences: { time_zone: "Etc/UTC" }) } + shared_let(:auth_provider) { create(:oidc_provider) } + + let!(:provider) { create(:internal_wiki_provider, enabled: true) } + + current_user { admin } + + it "can enable and disable the internal provider", :aggregate_failures, with_ee: [:scim_api] do + visit admin_settings_internal_wiki_provider_path + expect(page).to be_axe_clean.within("#content") + + expect(page).to have_checked_field("Enable the internal OpenProject wiki") + + uncheck "Enable the internal OpenProject wiki" + click_on "Save" + + SeleniumHubWaiter.wait + + expect(page).to have_unchecked_field("Enable the internal OpenProject wiki") + expect(provider.reload).not_to be_enabled + + check "Enable the internal OpenProject wiki" + click_on "Save" + + SeleniumHubWaiter.wait + + expect(page).to have_checked_field("Enable the internal OpenProject wiki") + expect(provider.reload).to be_enabled + end +end diff --git a/modules/wikis/spec/requests/api/v3/page_links/page_links_api_spec.rb b/modules/wikis/spec/requests/api/v3/page_links/page_links_api_spec.rb index 3ba6cb3f773..a1ae81b0057 100644 --- a/modules/wikis/spec/requests/api/v3/page_links/page_links_api_spec.rb +++ b/modules/wikis/spec/requests/api/v3/page_links/page_links_api_spec.rb @@ -34,18 +34,18 @@ require_module_spec_helper RSpec.describe "API v3 wiki page links resource", content_type: :json do include API::V3::Utilities::PathHelper - let(:work_package) { create(:work_package) } - let(:internal_wiki) { create(:internal_wiki_provider) } - let(:xwiki_provider) { create(:xwiki_provider) } + shared_let(:work_package) { create(:work_package) } + shared_let(:internal_wiki) { create(:internal_wiki_provider) } + shared_let(:xwiki_provider) { create(:xwiki_provider) } - let(:project) { work_package.project } + shared_let(:project) { work_package.project } - let(:user) { create(:user, member_with_permissions: { project => %i(view_work_packages manage_wiki_page_links) }) } + shared_let(:user) { create(:user, member_with_permissions: { project => %i(view_work_packages manage_wiki_page_links) }) } - let(:relation_page_links) { create_list(:relation_wiki_page_link, 3, provider: xwiki_provider, linkable: work_package) } - let(:inline_page_links) { create_list(:inline_wiki_page_link, 3, provider: internal_wiki, linkable: work_package) } + shared_let(:relation_page_links) { create_list(:relation_wiki_page_link, 3, provider: xwiki_provider, linkable: work_package) } + shared_let(:inline_page_links) { create_list(:inline_wiki_page_link, 3, provider: internal_wiki, linkable: work_package) } - let(:unrelated_page_links) do + shared_let(:unrelated_page_links) do create_list(:inline_wiki_page_link, 3, provider: internal_wiki, linkable: create(:work_package, project: project)) end @@ -79,6 +79,52 @@ RSpec.describe "API v3 wiki page links resource", content_type: :json do end end + describe "GET /api/v3/wiki_page_links" do + let(:unaccessible_links) { create_list(:relation_wiki_page_link, 2, provider: xwiki_provider) } + let(:path) { api_v3_paths.wiki_page_links } + + context "with all preconditions met (happy path)" do + before do + unaccessible_links + get path + end + + it_behaves_like "API V3 collection response", 9, 9, "WikiPageLink", "WikiPageLinkCollection" do + let(:elements) { Wikis::PageLink.where.not(id: unaccessible_links.pluck(:id)).order(id: :desc).all } + end + end + + context "when filtered by provider" do + let(:filter) { [{ provider: { operator: "=", values: [internal_wiki.universal_identifier] } }] } + + before { get "#{path}?filters=#{CGI.escape(filter.to_json)}" } + + it_behaves_like "API V3 collection response", 6, 6, "WikiPageLink", "WikiPageLinkCollection" do + let(:elements) { Wikis::PageLink.where(provider: internal_wiki).order(id: :desc).all } + end + end + + context "when filtered by link type" do + let(:filter) do + [{ wiki_page_link_type: + { operator: "=", values: [API::V3::PageLinks::URN_PAGE_LINK_TYPE["Wikis::RelationPageLink"]] } }] + end + + before { get "#{path}?filters=#{CGI.escape(filter.to_json)}" } + + it_behaves_like "API V3 collection response", 3, 3, "WikiPageLink", "WikiPageLinkCollection" do + let(:elements) { Wikis::RelationPageLink.where.not(id: unaccessible_links.pluck(:id)).order(id: :desc).all } + end + + it "only returns the filtered type" do + json = MultiJson.load(last_response.body, symbolize_keys: true) + + expect(json.dig(:_embedded, :elements)) + .to all(include(wikiPageLinkType: API::V3::PageLinks::URN_PAGE_LINK_TYPE["Wikis::RelationPageLink"])) + end + end + end + describe "POST /api/v3/wiki_page_links" do let(:user) { create(:user, member_with_permissions: { project => %i(view_work_packages manage_wiki_page_links) }) } @@ -168,10 +214,10 @@ RSpec.describe "API v3 wiki page links resource", content_type: :json do def stub_provider_queries internal_class = class_double(Wikis::Adapters::Providers::Internal::Queries::PageInfo) - xwiki_class = class_double(Wikis::Adapters::Providers::XWiki::Queries::PageInfo) + xwiki_class = class_double(Wikis::Adapters::Providers::XWiki::Queries::StablePageInfo) internal_query = instance_double(Wikis::Adapters::Providers::Internal::Queries::PageInfo) - xwiki_query = instance_double(Wikis::Adapters::Providers::XWiki::Queries::PageInfo) + xwiki_query = instance_double(Wikis::Adapters::Providers::XWiki::Queries::StablePageInfo) Wikis::Adapters::Registry.stub("internal.queries.page_info", internal_class) Wikis::Adapters::Registry.stub("xwiki.queries.page_info", xwiki_class) @@ -180,6 +226,7 @@ RSpec.describe "API v3 wiki page links resource", content_type: :json do allow(xwiki_class).to receive(:new).and_return(xwiki_query) stub_query_calls(inline_page_links, internal_query) stub_query_calls(relation_page_links, xwiki_query) + stub_query_calls(unrelated_page_links, internal_query) end def stub_query_calls(links, query) diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/page_reference_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/canonical_page_reference_spec.rb similarity index 84% rename from modules/wikis/spec/services/wikis/adapters/providers/xwiki/page_reference_spec.rb rename to modules/wikis/spec/services/wikis/adapters/providers/xwiki/canonical_page_reference_spec.rb index a9465e38cd8..8c7d29619a2 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/page_reference_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/canonical_page_reference_spec.rb @@ -31,7 +31,7 @@ require "spec_helper" require_module_spec_helper -RSpec.describe Wikis::Adapters::Providers::XWiki::PageReference do +RSpec.describe Wikis::Adapters::Providers::XWiki::CanonicalPageReference do describe ".parse" do subject { described_class.parse(identifier) } @@ -87,4 +87,24 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::PageReference do it { is_expected.to eq("/wikis/xwiki/spaces/My%20Space/pages/My%20Page") } end end + + describe "#to_s" do + subject { described_class.parse(identifier).to_s } + + context "with a standard identifier" do + let(:identifier) { "xwiki:Main.WebHome" } + + it "roundtrips" do + expect(subject).to eq(identifier) + end + end + + context "with a nested space identifier" do + let(:identifier) { "xwiki:MySpace.SubSpace.PageName" } + + it "roundtrips" do + expect(subject).to eq(identifier) + end + end + end end diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/page_info_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info_spec.rb similarity index 76% rename from modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/page_info_spec.rb rename to modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info_spec.rb index e9be445be71..bd32a8cb265 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/page_info_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/internal/canonical_page_info_spec.rb @@ -31,52 +31,46 @@ require "spec_helper" require_module_spec_helper -RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::PageInfo, :webmock do - it "is registered" do - expect(Wikis::Adapters::Registry.resolve("xwiki.queries.page_info")).to eq(described_class) +RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::Internal::CanonicalPageInfo, :disable_ssrf_filter, :webmock do + it "is not registered" do + expect(Wikis::Adapters::Registry.resolve("xwiki.queries.page_info")).not_to eq(described_class) end describe "#call" do let(:user) { create(:user) } - let(:wiki_provider) { create(:xwiki_provider, :with_connected_user, url: "https://xwiki.example.com/", connected_user: user) } + let(:wiki_provider) { create(:xwiki_provider, :for_local_connection, connected_user: user) } let(:identifier) { "xwiki:Main.WebHome" } - let(:page_url) { "https://xwiki.example.com/rest/wikis/xwiki/spaces/Main/pages/WebHome" } + let(:page_url) { "https://xwiki.local/rest/openproject/documents?docRef=xwiki:Main.WebHome" } let(:auth_strategy) { Wikis::Adapters::Input::AuthStrategy.build(key: :bearer_token, user:, provider: wiki_provider).value! } let(:input_data) { Wikis::Adapters::Input::PageInfo.build(identifier:).value! } let(:query) { described_class.new(model: wiki_provider) } subject(:result) { query.call(input_data:, auth_strategy:) } - context "when the page exists" do - let(:page_response) do - { "title" => "Home", "xwikiAbsoluteUrl" => "https://xwiki.example.com/bin/view/Main/" }.to_json - end - - before do - stub_request(:get, page_url) - .with(headers: { "Authorization" => "Bearer user-bearer-token" }) - .to_return(status: 200, body: page_response, headers: { "Content-Type" => "application/json" }) - end + context "when the page exists", vcr: "xwiki/canonical_page_info" do + # Set the expected identifier according to the stable identifier returned by XWiki (or update the VCR cassette accordingly) + let(:expected_identifier) { "484f4" } it "returns Success with title and href" do expect(result).to be_success expect(result.value!).to have_attributes( - identifier:, + identifier: expected_identifier, title: "Home", - href: "https://xwiki.example.com/bin/view/Main/" + href: "https://xwiki.local/bin/view/Main/" ) end end context "with a nested space identifier" do let(:identifier) { "xwiki:MySpace.SubSpace.PageName" } - let(:page_url) { "https://xwiki.example.com/rest/wikis/xwiki/spaces/MySpace/spaces/SubSpace/pages/PageName" } - let(:absolute_url) { "https://xwiki.example.com/bin/view/MySpace/SubSpace/PageName" } + let(:page_url) do + "https://xwiki.local/rest/openproject/documents?docRef=xwiki:MySpace.SubSpace.PageName" + end + let(:absolute_url) { "https://xwiki.local/bin/view/MySpace/SubSpace/PageName" } before do stub_request(:get, page_url) - .to_return(status: 200, body: { "title" => "Nested Page", - "xwikiAbsoluteUrl" => absolute_url }.to_json, + .to_return(status: 200, body: { id: "foo", title: "Nested Page", xwikiAbsoluteUrl: absolute_url }.to_json, headers: { "Content-Type" => "application/json" }) end @@ -93,7 +87,7 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::PageInfo, :webmock do end context "when no OAuth token exists for the user" do - let(:wiki_provider) { create(:xwiki_provider, :with_oauth_client, url: "https://xwiki.example.com/") } + let(:wiki_provider) { create(:xwiki_provider, :with_oauth_client, url: "https://xwiki.local/") } it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :missing_token)) } end @@ -136,5 +130,14 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::PageInfo, :webmock do it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :invalid_response)) } end + + context "when the response body is unexpected JSON" do + before do + stub_request(:get, page_url) + .to_return(status: 200, body: { error: "An error occured" }.to_json, headers: { "Content-Type" => "application/json" }) + end + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :invalid_response)) } + end end end diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/search_pages_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/search_pages_spec.rb index 9ae5ed65751..590fb2625f6 100644 --- a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/search_pages_spec.rb +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/search_pages_spec.rb @@ -53,6 +53,13 @@ RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::SearchPages, :disable expect(subject.value!.first.title).to eq("Test Page for RSpec") end + it "returns a complete PageInfo result" do + page_info = subject.value!.first + page_info.to_h.each do |attribute, value| + expect(value).not_to be_nil, "#{attribute} was expected to be non-nil, but was nil" + end + end + it "returns no other random results" do expect(subject.value!.count).to eq(1) end diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/stable_page_info_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/stable_page_info_spec.rb new file mode 100644 index 00000000000..eb726207d40 --- /dev/null +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/queries/stable_page_info_spec.rb @@ -0,0 +1,119 @@ +# 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 "spec_helper" +require_module_spec_helper + +RSpec.describe Wikis::Adapters::Providers::XWiki::Queries::StablePageInfo, :disable_ssrf_filter, :webmock do + it "is registered" do + expect(Wikis::Adapters::Registry.resolve("xwiki.queries.page_info")).to eq(described_class) + end + + describe "#call" do + let(:user) { create(:user) } + let(:wiki_provider) { create(:xwiki_provider, :for_local_connection, connected_user: user) } + let(:identifier) { "123abc" } + let(:page_url) { "https://xwiki.local/rest/openproject/documents/123abc" } + let(:auth_strategy) { Wikis::Adapters::Input::AuthStrategy.build(key: :bearer_token, user:, provider: wiki_provider).value! } + let(:input_data) { Wikis::Adapters::Input::PageInfo.build(identifier:).value! } + let(:query) { described_class.new(model: wiki_provider) } + + subject(:result) { query.call(input_data:, auth_strategy:) } + + context "when the page exists", vcr: "xwiki/stable_page_info" do + # Before recording cassette make sure a wiki page with title "Test Page for RSpec" exists + # Set the according identifier of that test page below + let(:identifier) { "d70f1" } + + it "returns Success with title and href" do + expect(result).to be_success + expect(result.value!).to have_attributes( + identifier: "d70f1", + title: "Test Page for RSpec", + href: "https://xwiki.local/bin/view/Test%20Page/" + ) + end + end + + context "when no OAuth token exists for the user" do + let(:wiki_provider) { create(:xwiki_provider, :with_oauth_client, url: "https://xwiki.local/") } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :missing_token)) } + end + + context "when the page is not found" do + before { stub_request(:get, page_url).to_return(status: 404, body: "") } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :not_found)) } + end + + context "when access is unauthorized" do + before { stub_request(:get, page_url).to_return(status: 401, body: "") } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :unauthorized)) } + end + + context "when access is forbidden" do + before { stub_request(:get, page_url).to_return(status: 403, body: "") } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :unauthorized)) } + end + + context "when XWiki returns a non-2xx status" do + before { stub_request(:get, page_url).to_return(status: 500, body: "Internal Server Error") } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :request_failed)) } + end + + context "when a network error occurs" do + before { stub_request(:get, page_url).to_timeout } + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :connection_error)) } + end + + context "when the response body is not valid JSON" do + before do + stub_request(:get, page_url) + .to_return(status: 200, body: "not json", headers: { "Content-Type" => "application/json" }) + end + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :invalid_response)) } + end + + context "when the response body is unexpected JSON" do + before do + stub_request(:get, page_url) + .to_return(status: 200, body: { error: "An error occured" }.to_json, headers: { "Content-Type" => "application/json" }) + end + + it { is_expected.to be_failure.and have_attributes(failure: have_attributes(code: :invalid_response)) } + end + end +end diff --git a/modules/wikis/spec/services/wikis/adapters/providers/xwiki/stable_page_reference_spec.rb b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/stable_page_reference_spec.rb new file mode 100644 index 00000000000..ee223d4af85 --- /dev/null +++ b/modules/wikis/spec/services/wikis/adapters/providers/xwiki/stable_page_reference_spec.rb @@ -0,0 +1,66 @@ +# 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 "spec_helper" +require_module_spec_helper + +RSpec.describe Wikis::Adapters::Providers::XWiki::StablePageReference do + describe ".parse" do + subject { described_class.parse(identifier) } + + let(:identifier) { "123abc" } + + it { is_expected.to have_attributes(uid: "123abc") } + + context "when passing nil" do + let(:identifier) { nil } + + it { is_expected.to be_nil } + end + end + + describe "#rest_path" do + subject { described_class.parse(identifier).rest_path } + + let(:identifier) { "123abc" } + + it { is_expected.to eq("/openproject/documents/123abc") } + end + + describe "#to_s" do + subject { described_class.parse(identifier).to_s } + + let(:identifier) { "123abc" } + + it "roundtrips" do + expect(subject).to eq(identifier) + end + end +end diff --git a/publiccode.yml b/publiccode.yml index d76300c1325..a79f8fbfc91 100644 --- a/publiccode.yml +++ b/publiccode.yml @@ -7,8 +7,8 @@ name: OpenProject applicationSuite: openDesk url: 'https://github.com/opf/openproject' roadmap: 'https://www.openproject.org/roadmap' -releaseDate: '2026-05-13' -softwareVersion: '17.4.0' +releaseDate: '2026-06-08' +softwareVersion: '17.4.1' developmentStatus: stable softwareType: standalone/web logo: 'publiccode_logo.svg' diff --git a/spec/components/op_primer/quick_filter/segmented_component_spec.rb b/spec/components/op_primer/quick_filter/segmented_control_component_spec.rb similarity index 98% rename from spec/components/op_primer/quick_filter/segmented_component_spec.rb rename to spec/components/op_primer/quick_filter/segmented_control_component_spec.rb index e747088b72c..43274a9ec72 100644 --- a/spec/components/op_primer/quick_filter/segmented_component_spec.rb +++ b/spec/components/op_primer/quick_filter/segmented_control_component_spec.rb @@ -30,7 +30,7 @@ require "rails_helper" -RSpec.describe OpPrimer::QuickFilter::SegmentedComponent, type: :component do +RSpec.describe OpPrimer::QuickFilter::SegmentedControlComponent, type: :component do include QuickFilterHelpers let(:project) { build_stubbed(:project) } diff --git a/spec/components/op_primer/quick_filter/select_panel_component_spec.rb b/spec/components/op_primer/quick_filter/select_panel_component_spec.rb new file mode 100644 index 00000000000..c9549ece0b4 --- /dev/null +++ b/spec/components/op_primer/quick_filter/select_panel_component_spec.rb @@ -0,0 +1,208 @@ +# 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 "rails_helper" + +RSpec.describe OpPrimer::QuickFilter::SelectPanelComponent, type: :component do + include QuickFilterHelpers + + let(:project) { build_stubbed(:project) } + let(:query) { build_meeting_query } + + subject(:component) do + described_class.new( + name: "Project", + query:, + filter_key: :project_id, + path_args: [nil, :meetings] + ) + end + + def render_with_items + render_inline(component) do |c| + c.with_item(label: "Project 1", value: 1) + c.with_item(label: "Project 2", value: 2) + end + end + + context "when rendering with items" do + before { render_with_items } + + it "renders all items" do + expect(page).to have_text("Project 1") + expect(page).to have_text("Project 2") + end + + it "renders the select panel quick filter" do + expect(page).to have_css("[data-controller='quick-filter--select-panel']") + end + end + + context "when no items are given" do + before { render_inline(component) } + + it "does not render" do + expect(page).to have_no_css("[data-controller='quick-filter--select-panel']") + end + end + + context "when an item matches the active filter value" do + let(:query) { build_meeting_query.where("project_id", "=", ["1"]) } + + before { render_with_items } + + it "marks the matching item as selected" do + expect(page).to have_css("[aria-selected='true']", text: "Project 1", visible: :all) + end + + it "does not mark the other item as selected" do + expect(page).to have_no_css("[aria-selected='true']", text: "Project 2", visible: :all) + end + end + + context "when multiple items match the active filter" do + let(:query) { build_meeting_query.where("project_id", "=", ["1", "2"]) } + + before { render_with_items } + + it "marks all matching items as selected" do + expect(page).to have_css("[aria-selected='true']", text: "Project 1", visible: :all) + expect(page).to have_css("[aria-selected='true']", text: "Project 2", visible: :all) + end + end + + context "when no filter is active" do + before { render_with_items } + + it "marks no items as selected" do + expect(page).to have_no_css("[aria-selected='true']", visible: :all) + end + end + + context "with the show button" do + context "when no filter is active" do + before { render_with_items } + + it "shows the component name in muted text" do + expect(page).to have_button("Project") + expect(page).to have_css("button .color-fg-muted", text: "Project") + end + + it "does not show a counter" do + expect(page).to have_no_css("button .Counter") + end + + it "renders the trailing icon in muted color" do + expect(page).to have_css("button .octicon-triangle-down.color-fg-muted") + end + end + + context "when one item is active" do + let(:query) { build_meeting_query.where("project_id", "=", ["1"]) } + + before { render_with_items } + + it "shows the component name as the label" do + expect(page).to have_button("Project") + end + + it "does not render muted text" do + expect(page).to have_no_css("button .color-fg-muted", text: "Project") + end + + it "shows a counter with the selected count" do + expect(page).to have_css("button .Counter", text: "1") + end + + it "renders the trailing icon in default color" do + expect(page).to have_css("button .octicon-triangle-down.color-fg-default") + end + end + + context "when multiple items are active" do + let(:query) { build_meeting_query.where("project_id", "=", ["1", "2"]) } + + before { render_with_items } + + it "shows the component name as the label" do + expect(page).to have_button("Project") + end + + it "shows a counter with the selected count" do + expect(page).to have_css("button .Counter", text: "2") + end + end + end + + context "with the footer" do + context "when no filter is active" do + before { render_with_items } + + it "renders an apply button" do + expect(page).to have_test_selector("quick-filter-apply-button") + end + + it "does not render a clear button" do + expect(page).to have_no_test_selector("quick-filter-clear-button") + end + end + + context "when a filter is active" do + let(:query) { build_meeting_query.where("project_id", "=", ["1"]) } + + before { render_with_items } + + it "renders a clear button" do + expect(page).to have_test_selector("quick-filter-clear-button") + end + + it "renders an apply button" do + expect(page).to have_test_selector("quick-filter-apply-button") + end + end + end + + context "when other filters are active" do + let(:query) { build_meeting_query.where("time", "=", ["future"]) } + + before { render_with_items } + + it "preserves the operator and values of other filters unchanged" do + base_url = page.find("[data-controller='quick-filter--select-panel']")[ + "data-quick-filter--select-panel-base-url-value" + ] + time_filter = filters_from_base_url(base_url).find { |f| f.key?("time") } + original = query.find_active_filter(:time) + + expect(time_filter["time"]["operator"]).to eq(original.operator.to_s) + expect(time_filter["time"]["values"]).to eq(original.values) + end + end +end diff --git a/spec/features/notifications/semantic_id_navigation_spec.rb b/spec/features/notifications/semantic_id_navigation_spec.rb index a4bd84fc066..ff0ae8c796e 100644 --- a/spec/features/notifications/semantic_id_navigation_spec.rb +++ b/spec/features/notifications/semantic_id_navigation_spec.rb @@ -42,6 +42,7 @@ RSpec.describe "Notification center uses displayId when navigating to the work p expect(page).to have_current_path( "/notifications/details/#{semantic_id}/activity" ) + center.expect_item_selected(notification) end it "renders the notification's WP link with the semantic identifier in its href" do diff --git a/spec/services/work_packages/activities_tab/paginator_spec.rb b/spec/services/work_packages/activities_tab/paginator_spec.rb index af9428ce51a..771a5934906 100644 --- a/spec/services/work_packages/activities_tab/paginator_spec.rb +++ b/spec/services/work_packages/activities_tab/paginator_spec.rb @@ -529,6 +529,26 @@ RSpec.describe WorkPackages::ActivitiesTab::Paginator, with_settings: { journal_ expect(records.map(&:id)).to include(initial_journal.id) end + context "with changesets" do + let(:repository) { create(:repository_subversion, project:) } + let!(:changeset) do + create(:changeset, + repository:, + committed_on: 1.day.ago, + revision: "rev1") + end + + before do + work_package.changesets << changeset + end + + it "includes changesets (commits are activity, not attribute-diffable journals)" do + _pagy, records = paginator.call + + expect(records).to include(changeset) + end + end + context "with attribute changes" do let!(:journal_with_attribute_change) do work_package.subject = "Updated subject" diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/canonical_page_info.yml b/spec/support/fixtures/vcr_cassettes/xwiki/canonical_page_info.yml new file mode 100644 index 00000000000..71ec256a5b8 --- /dev/null +++ b/spec/support/fixtures/vcr_cassettes/xwiki/canonical_page_info.yml @@ -0,0 +1,71 @@ +--- +http_interactions: +- request: + method: get + uri: https://xwiki.local/rest/openproject/documents?docRef=xwiki:Main.WebHome + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OpenProject 17.6.0 HTTPX Client + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Content-Type: + - application/json + Authorization: + - Bearer + response: + status: + code: 200 + message: OK + headers: + Content-Language: + - en + Content-Script-Type: + - text/javascript + Content-Type: + - application/json;charset=UTF-8 + Date: + - Wed, 10 Jun 2026 06:33:47 GMT + Set-Cookie: + - JSESSIONID=CF23A6F34156F21FFE50CB86F0F6138C; Path=/; HttpOnly + Xwiki-Form-Token: + - L5DY6HB46AhTFvPuxIu0Cg + Xwiki-User: + - xwiki:XWiki.admin + Xwiki-Version: + - 18.3.0 + body: + encoding: UTF-8 + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/children","rel":"http://www.xwiki.org/rel/children","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Main.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"484f4","fullName":"Main.WebHome","wiki":"xwiki","space":"Main","name":"WebHome","title":"Home","rawTitle":"Home","parent":"","parentId":"","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Main/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Main/","translations":{"links":[],"translations":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"en"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/pt_BR","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/pt_BR/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"pt_BR"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ru","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ru/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"ru"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/fr","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/fr/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"fr"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/no","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/no/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"no"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/da","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/da/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"da"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/de","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/de/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"de"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/en_GB","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/en_GB/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"en_GB"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/es","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/es/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"es"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ca","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ca/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"ca"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ko","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ko/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"ko"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ja","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/ja/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"ja"},{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/uk","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Main/pages/WebHome/translations/uk/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null}],"language":"uk"}],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1773821175000,"creator":"XWiki.admin","creatorName":null,"modified":1773821175000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"== Welcome to your wiki ==\n\nXWiki is the best + tool to organize your knowledge. A //wiki// is organized in a hierarchy of + //pages//. You can create multiple wikis, each with its own set of pages.\n\nXWiki + can be used as a knowledge base (support, documentation, sales, etc.), for + collaborative workspaces or even as a complete intranet.\n\n== The basics + ==\n\nTo make the most out of your wiki, log-in and:\n\nUse the {{displayIcon + name=\"pencil\"/}} button above to //edit// this page and start customizing + your wiki to your needs.\n\nUse the {{displayIcon name=\"add\"/}} button above + to //add// more pages to your wiki and create the //hierarchy// that best + organizes your content.\n\nUse the {{displayIcon name=\"home\"/}} breadcrumbs + located above the title to //navigate// inside your pages. It''s easy to get + lost in a big wiki without them.\n\nYou can also use the [[Sandbox>>Sandbox.WebHome]] + for more demo content and generally a place to experiment with your wiki''s + features. \n\n {{box}}Learn more on how to use XWiki with the [[Getting Started + Guide>>https://www.xwiki.org/xwiki/bin/view/Documentation/UserGuide/GettingStarted/WebHome]].{{/box}}\n\n(% + class=\"row\" %)\n(((\n(% class=\"col-xs-12 col-sm-6\" %)\n(((\n== Extend + your wiki ==\n\nTo extend the power and functionalities of your wiki with + the features that //you// need, head over to the [[Extension Manager>>XWiki.XWikiPreferences||queryString=\"editor=globaladmin§ion=XWiki.Extensions\"]] + where you can search for and install extensions.\n\nTo browse through the + 900+ community contributed extensions available for XWiki, head over to the + [[Extensions Repository>>https://extensions.xwiki.org]].\n)))\n\n(% class=\"col-xs-12 + col-sm-6\" %)\n(((\n== Create your application ==\n\nGo beyond the available + extensions and define the //structure// of your data based on //your// needs, + creating //your// own applications with [[App Within Minutes>>AppWithinMinutes]] + (AWM). \n\nAWM will take care of making it easy for you and your users to + create and manage the data.\n)))\n)))","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Main","name":"Main","type":"space","url":"https://xwiki.local/bin/view/Main/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Main/"}]},"rights":[],"renderedContent":null}' + recorded_at: Wed, 10 Jun 2026 06:33:47 GMT +recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/query_exact_match.yml b/spec/support/fixtures/vcr_cassettes/xwiki/query_exact_match.yml index 18637472313..028e7a262d5 100644 --- a/spec/support/fixtures/vcr_cassettes/xwiki/query_exact_match.yml +++ b/spec/support/fixtures/vcr_cassettes/xwiki/query_exact_match.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://xwiki.local/rest/wikis/query?number=50&q=%22Test%20Page%20for%20RSpec%22 + uri: https://xwiki.local/rest/wikis/query?number=20&q=%22Test%20Page%20for%20RSpec%22 body: encoding: US-ASCII string: '' @@ -27,26 +27,26 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:07 GMT Set-Cookie: - - JSESSIONID=A90934AE8F68AA76D0E0970863A314F8; Path=/; HttpOnly + - JSESSIONID=3CFCEFF117A41EAA3750970A7F16701F; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '790' + - '789' body: encoding: UTF-8 string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:Test Page.WebHome","pageFullName":"Test Page.WebHome","title":"Test Page for RSpec","wiki":"xwiki","space":"Test - Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":30.283539,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":33.28312,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' + recorded_at: Wed, 10 Jun 2026 06:23:07 GMT - request: method: get - uri: https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome + uri: https://xwiki.local/rest/openproject/documents?docRef=xwiki:Test%20Page.WebHome body: encoding: US-ASCII string: '' @@ -57,6 +57,8 @@ http_interactions: - application/json Accept-Encoding: - gzip, deflate + Content-Type: + - application/json Authorization: - Bearer response: @@ -71,24 +73,24 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:07 GMT Set-Cookie: - - JSESSIONID=6D38F35499AE562F0EEE91795F9951CF; Path=/; HttpOnly + - JSESSIONID=09FC7BC444F1E3C1FD3FBCF984C38AC7; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '2224' + - '2372' body: encoding: UTF-8 - string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:Test - Page.WebHome","fullName":"Test Page.WebHome","wiki":"xwiki","space":"Test - Page","name":"WebHome","title":"Test Page for RSpec","rawTitle":"Test Page - for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"This - is a test page that I created with my own hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"d70f1","fullName":"Test + Page.WebHome","wiki":"xwiki","space":"Test Page","name":"WebHome","title":"Test + Page for RSpec","rawTitle":"Test Page for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"This is a test page that I created with my own + hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test Page","name":"Test Page","type":"space","url":"https://xwiki.local/bin/view/Test%20Page/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Test%20Page/"}]},"rights":[],"renderedContent":null}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + recorded_at: Wed, 10 Jun 2026 06:23:07 GMT recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/query_no_match.yml b/spec/support/fixtures/vcr_cassettes/xwiki/query_no_match.yml index 21d38b10029..cccf4cf18a8 100644 --- a/spec/support/fixtures/vcr_cassettes/xwiki/query_no_match.yml +++ b/spec/support/fixtures/vcr_cassettes/xwiki/query_no_match.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://xwiki.local/rest/wikis/query?number=50&q=%22A%20page%20that%20does%20not%20exist%22 + uri: https://xwiki.local/rest/wikis/query?number=20&q=%22A%20page%20that%20does%20not%20exist%22 body: encoding: US-ASCII string: '' @@ -27,11 +27,11 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:23 GMT + - Wed, 10 Jun 2026 06:23:07 GMT Set-Cookie: - - JSESSIONID=9D417B4F0A9D4C117C903A54394DAD6C; Path=/; HttpOnly + - JSESSIONID=6653CAF1A1F9B748F41B143F534D9C38; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: @@ -41,5 +41,5 @@ http_interactions: body: encoding: UTF-8 string: '{"links":[],"searchResults":[],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' - recorded_at: Tue, 02 Jun 2026 08:17:23 GMT + recorded_at: Wed, 10 Jun 2026 06:23:07 GMT recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/query_partial_match.yml b/spec/support/fixtures/vcr_cassettes/xwiki/query_partial_match.yml index 86708b6d8f9..669115f44c2 100644 --- a/spec/support/fixtures/vcr_cassettes/xwiki/query_partial_match.yml +++ b/spec/support/fixtures/vcr_cassettes/xwiki/query_partial_match.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://xwiki.local/rest/wikis/query?number=50&q=%22for%20RSpec%22 + uri: https://xwiki.local/rest/wikis/query?number=20&q=%22for%20RSpec%22 body: encoding: US-ASCII string: '' @@ -27,11 +27,11 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:07 GMT Set-Cookie: - - JSESSIONID=4570EBB986F92482503F494102024098; Path=/; HttpOnly + - JSESSIONID=948F6FD6FE46127D21A904F5B4B572C4; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: @@ -42,11 +42,11 @@ http_interactions: encoding: UTF-8 string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:Test Page.WebHome","pageFullName":"Test Page.WebHome","title":"Test Page for RSpec","wiki":"xwiki","space":"Test - Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":14.608791,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + Page","pageName":"WebHome","modified":1780386902000,"author":"xwiki:XWiki.admin","authorName":null,"version":"4.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":16.572105,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' + recorded_at: Wed, 10 Jun 2026 06:23:07 GMT - request: method: get - uri: https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome + uri: https://xwiki.local/rest/openproject/documents?docRef=xwiki:Test%20Page.WebHome body: encoding: US-ASCII string: '' @@ -57,6 +57,8 @@ http_interactions: - application/json Accept-Encoding: - gzip, deflate + Content-Type: + - application/json Authorization: - Bearer response: @@ -71,24 +73,24 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:07 GMT Set-Cookie: - - JSESSIONID=36828A84C85C858E144AA581B1A1F138; Path=/; HttpOnly + - JSESSIONID=53060762864FA5DFC002D5F089BD0319; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '2224' + - '2372' body: encoding: UTF-8 - string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:Test - Page.WebHome","fullName":"Test Page.WebHome","wiki":"xwiki","space":"Test - Page","name":"WebHome","title":"Test Page for RSpec","rawTitle":"Test Page - for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"This - is a test page that I created with my own hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"d70f1","fullName":"Test + Page.WebHome","wiki":"xwiki","space":"Test Page","name":"WebHome","title":"Test + Page for RSpec","rawTitle":"Test Page for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"This is a test page that I created with my own + hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test Page","name":"Test Page","type":"space","url":"https://xwiki.local/bin/view/Test%20Page/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Test%20Page/"}]},"rights":[],"renderedContent":null}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + recorded_at: Wed, 10 Jun 2026 06:23:07 GMT recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/query_quoted_match.yml b/spec/support/fixtures/vcr_cassettes/xwiki/query_quoted_match.yml index bc3063416a4..5bf2ed65a1d 100644 --- a/spec/support/fixtures/vcr_cassettes/xwiki/query_quoted_match.yml +++ b/spec/support/fixtures/vcr_cassettes/xwiki/query_quoted_match.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://xwiki.local/rest/wikis/query?number=50&q=%22%5C%22Quoted%5C%22%20pages%20can%20be%20tricky%22 + uri: https://xwiki.local/rest/wikis/query?number=20&q=%22%5C%22Quoted%5C%22%20pages%20can%20be%20tricky%22 body: encoding: US-ASCII string: '' @@ -27,26 +27,26 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:06 GMT Set-Cookie: - - JSESSIONID=C28E0999BF663CA702569EE1C5C696E2; Path=/; HttpOnly + - JSESSIONID=53DEB144D1160E37FDBE016C6783652A; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '893' + - '892' body: encoding: UTF-8 string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:\"Quoted\" pages can be tricky.WebHome","pageFullName":"\"Quoted\" pages can be tricky.WebHome","title":"\"Quoted\" - pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":42.605682,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":47.94951,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' + recorded_at: Wed, 10 Jun 2026 06:23:06 GMT - request: method: get - uri: https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome + uri: https://xwiki.local/rest/openproject/documents?docRef=xwiki:%22Quoted%22%20pages%20can%20be%20tricky.WebHome body: encoding: US-ASCII string: '' @@ -57,6 +57,8 @@ http_interactions: - application/json Accept-Encoding: - gzip, deflate + Content-Type: + - application/json Authorization: - Bearer response: @@ -71,24 +73,25 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:22 GMT + - Wed, 10 Jun 2026 06:23:06 GMT Set-Cookie: - - JSESSIONID=EC142E0079C91196143B051273FDA2FD; Path=/; HttpOnly + - JSESSIONID=F53BDBC8DBB650A2E09E519DDCFF22D9; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '2642' + - '2769' body: encoding: UTF-8 - string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:\"Quoted\" - pages can be tricky.WebHome","fullName":"\"Quoted\" pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\" - pages can be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\" - pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"When - the page title contains quotes, it''s harder to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\" + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"1a013","fullName":"\"Quoted\" + pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\" pages can + be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\" + pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"When the page title contains quotes, it''s harder + to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\" pages can be tricky","name":"\"Quoted\" pages can be tricky","type":"space","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"}]},"rights":[],"renderedContent":null}' - recorded_at: Tue, 02 Jun 2026 08:17:22 GMT + recorded_at: Wed, 10 Jun 2026 06:23:06 GMT recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/query_unquoted_match.yml b/spec/support/fixtures/vcr_cassettes/xwiki/query_unquoted_match.yml index db53a2fc824..732e4de2196 100644 --- a/spec/support/fixtures/vcr_cassettes/xwiki/query_unquoted_match.yml +++ b/spec/support/fixtures/vcr_cassettes/xwiki/query_unquoted_match.yml @@ -2,7 +2,7 @@ http_interactions: - request: method: get - uri: https://xwiki.local/rest/wikis/query?number=50&q=%22Quoted%20pages%20can%20be%20tricky%22 + uri: https://xwiki.local/rest/wikis/query?number=20&q=%22Quoted%20pages%20can%20be%20tricky%22 body: encoding: US-ASCII string: '' @@ -27,26 +27,26 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:23 GMT + - Wed, 10 Jun 2026 06:23:06 GMT Set-Cookie: - - JSESSIONID=10D557C0A4C7D3C599B80C2FA01F5FF5; Path=/; HttpOnly + - JSESSIONID=E76D665AE92EA9DECFE756E8101CE2BD; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '893' + - '892' body: encoding: UTF-8 string: '{"links":[],"searchResults":[{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/page","type":null,"hrefLang":null}],"type":"page","id":"xwiki:\"Quoted\" pages can be tricky.WebHome","pageFullName":"\"Quoted\" pages can be tricky.WebHome","title":"\"Quoted\" - pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":42.605682,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' - recorded_at: Tue, 02 Jun 2026 08:17:23 GMT + pages can be tricky","wiki":"xwiki","space":"\"Quoted\" pages can be tricky","pageName":"WebHome","modified":1780387197000,"author":"xwiki:XWiki.admin","authorName":null,"version":"1.1","language":null,"className":null,"objectNumber":null,"filename":null,"score":47.94951,"object":null,"hierarchy":null}],"template":"https://xwiki.local/rest/?q={solrquery}(&number={number})(&start={start})(&orderField={fieldname}(&order={asc|desc}))(&distinct=1)(&prettyNames={false|true})(&wikis={wikis})(&className={classname})"}' + recorded_at: Wed, 10 Jun 2026 06:23:06 GMT - request: method: get - uri: https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome + uri: https://xwiki.local/rest/openproject/documents?docRef=xwiki:%22Quoted%22%20pages%20can%20be%20tricky.WebHome body: encoding: US-ASCII string: '' @@ -57,6 +57,8 @@ http_interactions: - application/json Accept-Encoding: - gzip, deflate + Content-Type: + - application/json Authorization: - Bearer response: @@ -71,24 +73,25 @@ http_interactions: Content-Type: - application/json;charset=UTF-8 Date: - - Tue, 02 Jun 2026 08:17:23 GMT + - Wed, 10 Jun 2026 06:23:06 GMT Set-Cookie: - - JSESSIONID=85112D2673FA7F3B99AEC6BF0A182372; Path=/; HttpOnly + - JSESSIONID=ABB17E4169B041D4223B7F1C381AD0BE; Path=/; HttpOnly Xwiki-Form-Token: - - 2XZUUfWArYhRgLYx4nHjhQ + - L5DY6HB46AhTFvPuxIu0Cg Xwiki-User: - xwiki:XWiki.admin Xwiki-Version: - 18.3.0 Content-Length: - - '2642' + - '2769' body: encoding: UTF-8 - string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"xwiki:\"Quoted\" - pages can be tricky.WebHome","fullName":"\"Quoted\" pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\" - pages can be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\" - pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"","content":"When - the page title contains quotes, it''s harder to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\" + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/%22Quoted%22%20pages%20can%20be%20tricky/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/%22Quoted%22%20pages%20can%20be%20tricky.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"1a013","fullName":"\"Quoted\" + pages can be tricky.WebHome","wiki":"xwiki","space":"\"Quoted\" pages can + be tricky","name":"WebHome","title":"\"Quoted\" pages can be tricky","rawTitle":"\"Quoted\" + pages can be tricky","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"1.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":1,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780387197000,"creator":"XWiki.admin","creatorName":null,"modified":1780387197000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"When the page title contains quotes, it''s harder + to exactly match their page title.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"\"Quoted\" pages can be tricky","name":"\"Quoted\" pages can be tricky","type":"space","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/%22Quoted%22%20pages%20can%20be%20tricky/"}]},"rights":[],"renderedContent":null}' - recorded_at: Tue, 02 Jun 2026 08:17:23 GMT + recorded_at: Wed, 10 Jun 2026 06:23:06 GMT recorded_with: VCR 6.4.0 diff --git a/spec/support/fixtures/vcr_cassettes/xwiki/stable_page_info.yml b/spec/support/fixtures/vcr_cassettes/xwiki/stable_page_info.yml new file mode 100644 index 00000000000..891225a1652 --- /dev/null +++ b/spec/support/fixtures/vcr_cassettes/xwiki/stable_page_info.yml @@ -0,0 +1,50 @@ +--- +http_interactions: +- request: + method: get + uri: https://xwiki.local/rest/openproject/documents/d70f1 + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - OpenProject 17.6.0 HTTPX Client + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Authorization: + - Bearer + response: + status: + code: 200 + message: OK + headers: + Content-Language: + - en + Content-Script-Type: + - text/javascript + Content-Type: + - application/json;charset=UTF-8 + Date: + - Wed, 10 Jun 2026 06:31:21 GMT + Set-Cookie: + - JSESSIONID=39C7519D8EAC0C8BA141B8F2519873C0; Path=/; HttpOnly + Xwiki-Form-Token: + - L5DY6HB46AhTFvPuxIu0Cg + Xwiki-User: + - xwiki:XWiki.admin + Xwiki-Version: + - 18.3.0 + Content-Length: + - '2378' + body: + encoding: UTF-8 + string: '{"links":[{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page","rel":"http://www.xwiki.org/rel/space","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome","rel":"http://www.xwiki.org/rel/parent","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/history","rel":"http://www.xwiki.org/rel/history","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/spaces/Test%20Page/pages/WebHome/objects","rel":"http://www.xwiki.org/rel/objects","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/syntaxes","rel":"http://www.xwiki.org/rel/syntaxes","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/openproject/documents/d70f1","rel":"self","type":null,"hrefLang":null},{"href":"https://xwiki.local/rest/wikis/xwiki/classes/Test%20Page.WebHome","rel":"http://www.xwiki.org/rel/class","type":null,"hrefLang":null}],"id":"d70f1","fullName":"Test + Page.WebHome","wiki":"xwiki","space":"Test Page","name":"WebHome","title":"Test + Page for RSpec","rawTitle":"Test Page for RSpec","parent":"Main.WebHome","parentId":"xwiki:Main.WebHome","version":"4.1","author":"XWiki.admin","authorName":null,"xwikiRelativeUrl":"https://xwiki.local/bin/view/Test%20Page/","xwikiAbsoluteUrl":"https://xwiki.local/bin/view/Test%20Page/","translations":{"links":[],"translations":[],"default":"en"},"syntax":"xwiki/2.1","language":"","majorVersion":4,"minorVersion":1,"hidden":false,"enforceRequiredRights":false,"created":1780383689000,"creator":"XWiki.admin","creatorName":null,"modified":1780386902000,"modifier":"XWiki.admin","modifierName":null,"originalMetadataAuthor":"xwiki:XWiki.admin","originalMetadataAuthorName":null,"comment":"Created + URL Shortener.","content":"This is a test page that I created with my own + hands.","clazz":null,"objects":null,"attachments":null,"hierarchy":{"items":[{"label":"xwiki","name":"xwiki","type":"wiki","url":"https://xwiki.local/bin/view/Main/"},{"label":"Test + Page","name":"Test Page","type":"space","url":"https://xwiki.local/bin/view/Test%20Page/"},{"label":"WebHome","name":"WebHome","type":"document","url":"https://xwiki.local/bin/view/Test%20Page/"}]},"rights":[],"renderedContent":null}' + recorded_at: Wed, 10 Jun 2026 06:31:21 GMT +recorded_with: VCR 6.4.0 diff --git a/spec/support/form_fields/primerized/block_note_editor_input.rb b/spec/support/form_fields/primerized/block_note_editor_input.rb index 5fd18077a33..830f369a716 100644 --- a/spec/support/form_fields/primerized/block_note_editor_input.rb +++ b/spec/support/form_fields/primerized/block_note_editor_input.rb @@ -118,6 +118,27 @@ module FormFields end end + # Triggers undo in the editor by dispatching a synthetic Ctrl-Z keydown event + # directly to the shadow-DOM contenteditable element. Selenium's send_keys does + # not reliably deliver modifier-key chords to elements inside a shadow DOM, so + # we use execute_script instead. ProseMirror processes all keydown events on + # its editor div regardless of isTrusted. + def undo + page.execute_script(<<~JS) + var shadowRoot = #{shadow_root_query} + var element = shadowRoot.querySelector('div[role="textbox"]'); + element.focus(); + element.dispatchEvent(new KeyboardEvent('keydown', { + key: 'z', + code: 'KeyZ', + ctrlKey: true, + bubbles: true, + cancelable: true, + composed: true + })); + JS + end + private # Attention: This only works with selenium, not with cuprite, diff --git a/spec/support/matchers/pluck.rb b/spec/support/matchers/pluck.rb new file mode 100644 index 00000000000..6bc20650d0f --- /dev/null +++ b/spec/support/matchers/pluck.rb @@ -0,0 +1,85 @@ +# 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. +# ++ + +# When you need to check an attribute for multiple records: +# +# expect(WorkPackage.where(sprint:)).to pluck(:position).eq( +# sprint1_wp2 => 1, +# sprint1_wp3 => 2, +# sprint1_wp4 => 3, +# sprint1_wp1 => 4, +# sprint1_wp5 => 6 +# ) +# +# Fails with: +# +# 582 => 1, +# 583 => 2, +# 584 => 3, +# -585 => 6, +# +585 => 5, +# +# Specify `identified_by` attribute to be used instead of `id` to differentiate +# records in failurediff, it must be unique: +# +# expect(WorkPackage.where(sprint:)).to pluck(:position, identified_by: :subject).eq( +# sprint1_wp2 => 1, +# sprint1_wp3 => 2, +# sprint1_wp4 => 3, +# sprint1_wp1 => 4, +# sprint1_wp5 => 6 +# ) +# +# Fails with: +# +# "Sprint 1 WorkPackage 2" => 1, +# "Sprint 1 WorkPackage 3" => 2, +# "Sprint 1 WorkPackage 4" => 3, +# -"Sprint 1 WorkPackage 5" => 6, +# +"Sprint 1 WorkPackage 5" => 5, + +RSpec::Matchers.define :pluck do |attribute, identified_by: :id| + chain :eq do |expected| + @expected = expected.transform_keys { it.public_send(identified_by) } + end + + match do |actual| + @actual = actual.pluck(identified_by, attribute).to_h + @actual == @expected + end + + diffable + + define_method(:expected) { @expected } + + failure_message do |_| + "expected #{attribute.inspect} (identified by #{identified_by.inspect}) to match" + end +end diff --git a/spec/support/shared/components/quick_filter.rb b/spec/support/shared/components/quick_filter.rb index 672850b36cf..a1788f2acde 100644 --- a/spec/support/shared/components/quick_filter.rb +++ b/spec/support/shared/components/quick_filter.rb @@ -34,12 +34,21 @@ module QuickFilterHelpers end def filters_from_link(link) - json = CGI.unescape(link[:href].match(/filters=([^&]+)/)[1]) - JSON.parse(json) + parse_url_param(link[:href], "filters") end def sort_from_link(link) - json = CGI.unescape(link[:href].match(/sortBy=([^&]+)/)[1]) + parse_url_param(link[:href], "sortBy") + end + + def filters_from_base_url(url) + parse_url_param(url, "filters") + end + + private + + def parse_url_param(url, param) + json = CGI.unescape(url.match(/#{param}=([^&]+)/)[1]) JSON.parse(json) end end