diff --git a/.buildpacks b/.buildpacks
index c3c91f1aac5..f5cf87bf7ed 100644
--- a/.buildpacks
+++ b/.buildpacks
@@ -1,2 +1,2 @@
https://github.com/heroku/heroku-buildpack-nodejs.git#v315
-https://github.com/pkgr/heroku-buildpack-ruby.git#v327-1
+https://github.com/pkgr/heroku-buildpack-ruby.git#v356-1
diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml
index bfb56a7c6d3..761aeeb067b 100644
--- a/.github/workflows/cla.yml
+++ b/.github/workflows/cla.yml
@@ -21,7 +21,10 @@ jobs:
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
uses: contributor-assistant/github-action@v2.6.1
env:
+ # https://github.com/contributor-assistant/github-action?tab=readme-ov-file#environmental-variables
+ # Built-in GitHub token to make the API calls for interacting with GitHub. Does not need to be specified the secrets store.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ # Access token for repository where the signatures are stored (see below for remote-repository-name)
PERSONAL_ACCESS_TOKEN: ${{ secrets.OPENPROJECTCI_GH_LEGAL_TOKEN }}
with:
path-to-signatures: "contributor-license-agreement/signatures/version1.json"
diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml
index 861d79fd3dc..03f3c5ae822 100644
--- a/.github/workflows/crowdin.yml
+++ b/.github/workflows/crowdin.yml
@@ -76,12 +76,14 @@ jobs:
crowdin_branch_name: ${{ steps.vars.outputs.crowdin_branch }}
# Dont create a PR for the updated translations
push_translations: false
+ user: auto
env:
OPENPROJECT_CROWDIN_PROJECT: ${{ secrets.OPENPROJECT_CROWDINV2_PROJECT }}
OPENPROJECT_CROWDIN_API_KEY: ${{ secrets.OPENPROJECT_CROWDINV2_API_KEY }}
- name: "Fix root key in Portuguese crowdin translation files"
- run: |
- script/i18n/fix_crowdin_pt_language_root_key
+ run: script/i18n/fix_crowdin_pt_language_root_key
+ - name: "Rewrite crowdin translation files using ruby yaml library"
+ run: script/i18n/rewrite_crowdin_yml_files
- name: "Commit translations"
env:
BRANCH: ${{ matrix.branch }}
diff --git a/.rubocop.yml b/.rubocop.yml
index 1815a2c11d1..ae173ff1fe2 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -169,6 +169,10 @@ Rails/ContentTag:
# dynamic finders cop clashes with capybara ID cop
Rails/DynamicFindBy:
Enabled: true
+ AllowedMethods:
+ - find_by_id_or_identifier
+ - find_by_id_or_identifier!
+ - find_by_semantic_identifier
Exclude:
- "spec/features/**/*.rb"
- "spec/support/**/*.rb"
@@ -186,6 +190,9 @@ Rails/FindEach:
- limit
- select
- lock
+ Exclude:
+ - "spec/**/*"
+ - "modules/**/spec/**/*"
# The http verbs in Rack::Test do not accept named parameters (params: params)
Rails/HttpPositionalArguments:
@@ -197,11 +204,13 @@ Rails/I18nLocaleAssignment:
Enabled: true
Exclude:
- "spec/**/*.rb"
+ - "modules/*/spec/**/*.rb"
Rails/I18nLocaleTexts:
Enabled: true
Exclude:
- "spec/**/*.rb"
+ - "modules/*/spec/**/*.rb"
# We have config.active_record.belongs_to_required_by_default = false ,
# which means, we do have to declare presence validators on belongs_to relations.
@@ -215,6 +224,9 @@ Rails/RequireDependency:
# Require save! to prevent saving without validation when saving outside of a condition.
Rails/SaveBang:
Enabled: true
+ Exclude:
+ - "spec/**/*"
+ - "modules/**/spec/**/*"
# There are valid cases in which to use methods like:
# * update_all
@@ -321,6 +333,7 @@ RSpec/SpecFilePathFormat:
CustomTransform:
OpenIDConnect: openid_connect
OAuthClients: oauth_clients
+ XWikiProviders: xwiki_providers
EnforcedInflector: active_support
IgnoreMethods: true
@@ -471,6 +484,11 @@ Style/Proc:
Style/RaiseArgs:
Enabled: false
+Style/RescueModifier:
+ Exclude:
+ - "spec/**/*"
+ - "modules/**/spec/**/*"
+
Style/RegexpLiteral:
Enabled: false
diff --git a/.ruby-version b/.ruby-version
index 1454f6ed4b7..4d54daddb61 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-4.0.1
+4.0.2
diff --git a/Gemfile b/Gemfile
index 548a87c64e5..fedf29eb877 100644
--- a/Gemfile
+++ b/Gemfile
@@ -41,10 +41,10 @@ gem "activemodel-serializers-xml", "~> 1.0.1"
gem "activerecord-import", "~> 2.2.0"
gem "activerecord-session_store", "~> 2.2.0"
gem "ox"
-gem "rails", "~> 8.1.2"
+gem "rails", "~> 8.1.3"
gem "responders", "~> 3.2"
-gem "ffi", "~> 1.15"
+gem "ffi", "~> 1.17"
gem "connection_pool", "~> 3.0.2"
@@ -72,7 +72,7 @@ gem "awesome_nested_set", "~> 3.9.0"
gem "closure_tree", "~> 9.6.1"
gem "rubytree", "~> 2.2.0"
-gem "addressable", "~> 2.8.9"
+gem "addressable", "~> 2.9.0"
# Remove whitespace from model input
gem "auto_strip_attributes", "~> 2.5"
@@ -87,7 +87,7 @@ gem "htmldiff"
gem "stringex", "~> 2.8.5"
# CommonMark markdown parser with GFM extension
-gem "commonmarker", "~> 2.7.0"
+gem "commonmarker", "~> 2.8.0"
# HTML pipeline for transformations on text formatter output
# such as sanitization or additional features
@@ -123,11 +123,11 @@ gem "sys-filesystem", "~> 1.5.0", require: false
gem "bcrypt", "~> 3.1.22"
-gem "multi_json", "~> 1.19.0"
+gem "multi_json", "~> 1.20.0"
gem "oj", "~> 3.16.16"
gem "daemons"
-gem "good_job", "~> 4.13.3" # update should be done manually in sync with saas-openproject version.
+gem "good_job", "~> 4.14.2" # update should be done manually in sync with saas-openproject version.
gem "rack-protection", "~> 3.2.0"
@@ -161,7 +161,7 @@ gem "ttfunk", "~> 1.7.0" # remove after https://github.com/prawnpdf/prawn/issues
# prawn implicitly depends on matrix gem no longer in ruby core with 3.1
gem "matrix", "~> 0.4.3"
-gem "mcp", "~> 0.8.0"
+gem "mcp", "~> 0.10.0"
gem "meta-tags", "~> 2.23.0"
@@ -204,9 +204,9 @@ gem "carrierwave_direct", "~> 3.0.0"
gem "ssrf_filter", "~> 1.3"
gem "fog-aws"
-gem "aws-sdk-core", "~> 3.241"
+gem "aws-sdk-core", "~> 3.244"
# File upload via fog + screenshots on travis
-gem "aws-sdk-s3", "~> 1.213"
+gem "aws-sdk-s3", "~> 1.217"
gem "openproject-token", "~> 8.8.2"
@@ -227,7 +227,7 @@ gem "dry-validation"
gem "store_attribute", "~> 2.0"
# Appsignal integration
-gem "appsignal", "~> 4.7", require: false
+gem "appsignal", "~> 4.8", require: false
# Yabeda integration
gem "yabeda-activerecord"
@@ -236,11 +236,11 @@ gem "yabeda-puma-plugin"
gem "yabeda-rails"
# opentelemetry
-gem "opentelemetry-exporter-otlp", "~> 0.32.0", require: false
+gem "opentelemetry-exporter-otlp", "~> 0.33.0", require: false
gem "opentelemetry-instrumentation-all", "~> 0.91.0", require: false
gem "opentelemetry-sdk", "~> 1.10", require: false
-gem "view_component", "~> 4.5.0"
+gem "view_component", "~> 4.6.0"
# Lookbook
gem "lookbook", "2.3.14"
@@ -254,7 +254,7 @@ gem "factory_bot_rails", "~> 6.5.0", require: false
gem "turbo_power", "~> 0.7.0"
gem "turbo-rails", "~> 2.0.20"
-gem "httpx", "~> 1.7.4"
+gem "httpx", "~> 1.7.5"
# Brings actual deep-freezing to most ruby objects
gem "ice_nine"
@@ -266,7 +266,7 @@ group :test do
# Test prof provides factories from code
# and other niceties
- gem "test-prof", "~> 1.5.0"
+ gem "test-prof", "~> 1.6.0"
gem "turbo_tests", github: "opf/turbo_tests", ref: "with-patches"
gem "rack_session_access"
@@ -334,9 +334,6 @@ group :development do
gem "spring-commands-rubocop"
gem "colored2"
-
- # git hooks manager
- gem "lefthook", require: false
end
group :development, :test do
@@ -356,6 +353,9 @@ group :development, :test do
# https://github.com/puma/puma/issues/2835#issuecomment-2302133927
gem "byebug"
+ # Unreleased fix of readline dependency of pry: https://github.com/pry/pry/pull/2366
+ # Once this gets released, the specific dev dependency on pry can be removed
+ gem "pry", github: "pry/pry", ref: "135640262879544c6bfecbf3e78511289bfe956c"
gem "pry-byebug", "~> 3.12.0", platforms: [:mri]
gem "pry-rails", "~> 0.3.6"
gem "pry-rescue", "~> 1.6.0"
@@ -387,7 +387,7 @@ end
gem "bootsnap", "~> 1.23.0", require: false
# API gems
-gem "grape", "~> 3.1.1"
+gem "grape", "~> 3.2.0"
gem "grape_logging", "~> 3.0.0"
gem "roar", "~> 1.2.0"
diff --git a/Gemfile.lock b/Gemfile.lock
index 970a9402eca..cb7087239a1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -61,6 +61,16 @@ GIT
parallel_tests (>= 3.3.0, < 5)
rspec (>= 3.10)
+GIT
+ remote: https://github.com/pry/pry.git
+ revision: 135640262879544c6bfecbf3e78511289bfe956c
+ ref: 135640262879544c6bfecbf3e78511289bfe956c
+ specs:
+ pry (0.16.0)
+ coderay (~> 1.1)
+ method_source (~> 1.0)
+ reline (>= 0.6.0)
+
PATH
remote: modules/auth_plugins
specs:
@@ -77,7 +87,6 @@ PATH
remote: modules/avatars
specs:
openproject-avatars (1.0.0)
- fastimage (>= 2.3, < 2.5)
gravatar_image_tag (~> 1.2.0)
PATH
@@ -203,7 +212,7 @@ PATH
remote: modules/two_factor_authentication
specs:
openproject-two_factor_authentication (1.0.0)
- aws-sdk-sns (>= 1.101, < 1.113)
+ aws-sdk-sns (>= 1.101, < 1.114)
messagebird-rest (>= 1.4.2, < 5.1.0)
rotp (~> 6.1)
webauthn (~> 3.0)
@@ -228,31 +237,31 @@ GEM
remote: https://rubygems.org/
specs:
Ascii85 (2.0.1)
- action_text-trix (2.1.17)
+ action_text-trix (2.1.18)
railties
- actioncable (8.1.2.1)
- actionpack (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ actioncable (8.1.3)
+ actionpack (= 8.1.3)
+ activesupport (= 8.1.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
- actionmailbox (8.1.2.1)
- actionpack (= 8.1.2.1)
- activejob (= 8.1.2.1)
- activerecord (= 8.1.2.1)
- activestorage (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ actionmailbox (8.1.3)
+ actionpack (= 8.1.3)
+ activejob (= 8.1.3)
+ activerecord (= 8.1.3)
+ activestorage (= 8.1.3)
+ activesupport (= 8.1.3)
mail (>= 2.8.0)
- actionmailer (8.1.2.1)
- actionpack (= 8.1.2.1)
- actionview (= 8.1.2.1)
- activejob (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ actionmailer (8.1.3)
+ actionpack (= 8.1.3)
+ actionview (= 8.1.3)
+ activejob (= 8.1.3)
+ activesupport (= 8.1.3)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
- actionpack (8.1.2.1)
- actionview (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ actionpack (8.1.3)
+ actionview (= 8.1.3)
+ activesupport (= 8.1.3)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
@@ -263,34 +272,34 @@ GEM
actionpack-xml_parser (2.0.1)
actionpack (>= 5.0)
railties (>= 5.0)
- actiontext (8.1.2.1)
+ actiontext (8.1.3)
action_text-trix (~> 2.1.15)
- actionpack (= 8.1.2.1)
- activerecord (= 8.1.2.1)
- activestorage (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ actionpack (= 8.1.3)
+ activerecord (= 8.1.3)
+ activestorage (= 8.1.3)
+ activesupport (= 8.1.3)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
- actionview (8.1.2.1)
- activesupport (= 8.1.2.1)
+ actionview (8.1.3)
+ activesupport (= 8.1.3)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
active_record_doctor (2.0.1)
activerecord (>= 7.0.0)
- activejob (8.1.2.1)
- activesupport (= 8.1.2.1)
+ activejob (8.1.3)
+ activesupport (= 8.1.3)
globalid (>= 0.3.6)
- activemodel (8.1.2.1)
- activesupport (= 8.1.2.1)
+ activemodel (8.1.3)
+ activesupport (= 8.1.3)
activemodel-serializers-xml (1.0.3)
activemodel (>= 5.0.0.a)
activesupport (>= 5.0.0.a)
builder (~> 3.1)
- activerecord (8.1.2.1)
- activemodel (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ activerecord (8.1.3)
+ activemodel (= 8.1.3)
+ activesupport (= 8.1.3)
timeout (>= 0.4.0)
activerecord-import (2.2.0)
activerecord (>= 4.2)
@@ -302,13 +311,13 @@ GEM
cgi (>= 0.3.6)
rack (>= 2.0.8, < 4)
railties (>= 7.0)
- activestorage (8.1.2.1)
- actionpack (= 8.1.2.1)
- activejob (= 8.1.2.1)
- activerecord (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ activestorage (8.1.3)
+ actionpack (= 8.1.3)
+ activejob (= 8.1.3)
+ activerecord (= 8.1.3)
+ activesupport (= 8.1.3)
marcel (~> 1.0)
- activesupport (8.1.2.1)
+ activesupport (8.1.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
@@ -326,7 +335,7 @@ GEM
activesupport (>= 6.1)
acts_as_tree (2.9.1)
activerecord (>= 3.0.0)
- addressable (2.8.9)
+ addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
aes_key_wrap (1.1.0)
afm (1.0.0)
@@ -337,7 +346,7 @@ GEM
android_key_attestation (0.3.0)
anyway_config (2.8.0)
ruby-next-core (~> 1.0)
- appsignal (4.8.3)
+ appsignal (4.8.4)
logger
rack (>= 2.0.0)
ast (2.4.3)
@@ -347,8 +356,8 @@ GEM
awesome_nested_set (3.9.0)
activerecord (>= 4.0.0, < 8.2)
aws-eventstream (1.4.0)
- aws-partitions (1.1227.0)
- aws-sdk-core (3.243.0)
+ aws-partitions (1.1238.0)
+ aws-sdk-core (3.244.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
@@ -356,15 +365,15 @@ GEM
bigdecimal
jmespath (~> 1, >= 1.6.1)
logger
- aws-sdk-kms (1.122.0)
- aws-sdk-core (~> 3, >= 3.241.4)
+ aws-sdk-kms (1.123.0)
+ aws-sdk-core (~> 3, >= 3.244.0)
aws-sigv4 (~> 1.5)
- aws-sdk-s3 (1.216.0)
- aws-sdk-core (~> 3, >= 3.243.0)
+ aws-sdk-s3 (1.219.0)
+ aws-sdk-core (~> 3, >= 3.244.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
- aws-sdk-sns (1.112.0)
- aws-sdk-core (~> 3, >= 3.241.4)
+ aws-sdk-sns (1.113.0)
+ aws-sdk-core (~> 3, >= 3.244.0)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
@@ -391,7 +400,7 @@ GEM
erubi (~> 1.4)
parser (>= 2.4)
smart_properties
- bigdecimal (4.0.1)
+ bigdecimal (4.1.1)
bindata (2.5.1)
bootsnap (1.23.0)
msgpack (~> 1.2)
@@ -424,7 +433,7 @@ GEM
carrierwave_direct (3.0.0)
carrierwave (>= 2.2.0)
fog-aws
- cbor (0.5.10.1)
+ cbor (0.5.10.2)
cgi (0.5.1)
childprocess (5.1.0)
logger (~> 1.5)
@@ -438,13 +447,13 @@ GEM
descendants_tracker (~> 0.0.1)
color_conversion (0.1.2)
colored2 (4.0.3)
- commonmarker (2.7.0-aarch64-linux)
- commonmarker (2.7.0-aarch64-linux-musl)
- commonmarker (2.7.0-arm-linux)
- commonmarker (2.7.0-arm64-darwin)
- commonmarker (2.7.0-x86_64-darwin)
- commonmarker (2.7.0-x86_64-linux)
- commonmarker (2.7.0-x86_64-linux-musl)
+ commonmarker (2.8.1-aarch64-linux)
+ commonmarker (2.8.1-aarch64-linux-musl)
+ commonmarker (2.8.1-arm-linux)
+ commonmarker (2.8.1-arm64-darwin)
+ commonmarker (2.8.1-x86_64-darwin)
+ commonmarker (2.8.1-x86_64-linux)
+ commonmarker (2.8.1-x86_64-linux-musl)
compare-xml (0.66)
nokogiri (~> 1.8)
concurrent-ruby (1.3.6)
@@ -453,7 +462,7 @@ GEM
cose (1.3.1)
cbor (~> 0.5.9)
openssl-signature_algorithm (~> 1.0)
- counter_culture (3.12.2)
+ counter_culture (3.13.0)
activerecord (>= 4.2)
activesupport (>= 4.2)
crack (1.0.1)
@@ -549,7 +558,7 @@ GEM
activemodel
equivalent-xml (0.6.0)
nokogiri (>= 1.4.3)
- erb (6.0.2)
+ erb (6.0.3)
erb_lint (0.9.0)
activesupport
better_html (>= 2.0.1)
@@ -564,7 +573,7 @@ GEM
tzinfo
eventmachine (1.2.7)
eventmachine_httpserver (0.2.1)
- excon (1.4.0)
+ excon (1.4.2)
logger
factory_bot (6.5.6)
activesupport (>= 6.1.0)
@@ -579,21 +588,20 @@ GEM
faraday (>= 1, < 3)
faraday-net_http (3.4.2)
net-http (~> 0.5)
- fastimage (2.4.1)
- ferrum (0.17.1)
+ ferrum (0.17.2)
addressable (~> 2.5)
base64 (~> 0.2)
concurrent-ruby (~> 1.1)
webrick (~> 1.7)
websocket-driver (~> 0.7)
- ffi (1.17.3-aarch64-linux-gnu)
- ffi (1.17.3-aarch64-linux-musl)
- ffi (1.17.3-arm-linux-gnu)
- ffi (1.17.3-arm-linux-musl)
- ffi (1.17.3-arm64-darwin)
- ffi (1.17.3-x86_64-darwin)
- ffi (1.17.3-x86_64-linux-gnu)
- ffi (1.17.3-x86_64-linux-musl)
+ ffi (1.17.4-aarch64-linux-gnu)
+ ffi (1.17.4-aarch64-linux-musl)
+ ffi (1.17.4-arm-linux-gnu)
+ ffi (1.17.4-arm-linux-musl)
+ ffi (1.17.4-arm64-darwin)
+ ffi (1.17.4-x86_64-darwin)
+ ffi (1.17.4-x86_64-linux-gnu)
+ ffi (1.17.4-x86_64-linux-musl)
flamegraph (0.9.5)
fog-aws (3.33.1)
base64 (>= 0.2, < 0.4)
@@ -625,7 +633,7 @@ GEM
glob (0.4.0)
globalid (1.3.0)
activesupport (>= 6.1)
- good_job (4.13.3)
+ good_job (4.14.2)
activejob (>= 6.1.0)
activerecord (>= 6.1.0)
concurrent-ruby (>= 1.3.1)
@@ -646,25 +654,25 @@ GEM
base64 (~> 0.2)
faraday (>= 1.0, < 3.a)
google-logging-utils (0.2.0)
- google-protobuf (4.34.0)
+ google-protobuf (4.34.1)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-aarch64-linux-gnu)
+ google-protobuf (4.34.1-aarch64-linux-gnu)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-aarch64-linux-musl)
+ google-protobuf (4.34.1-aarch64-linux-musl)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-arm64-darwin)
+ google-protobuf (4.34.1-arm64-darwin)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-x86_64-darwin)
+ google-protobuf (4.34.1-x86_64-darwin)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-x86_64-linux-gnu)
+ google-protobuf (4.34.1-x86_64-linux-gnu)
bigdecimal
rake (~> 13.3)
- google-protobuf (4.34.0-x86_64-linux-musl)
+ google-protobuf (4.34.1-x86_64-linux-musl)
bigdecimal
rake (~> 13.3)
googleapis-common-protos-types (1.22.0)
@@ -677,8 +685,8 @@ GEM
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
- grape (3.1.1)
- activesupport (>= 7.1)
+ grape (3.2.0)
+ activesupport (>= 7.2)
dry-configurable
dry-types (>= 1.1)
mustermann-grape (~> 1.1.0)
@@ -703,7 +711,7 @@ GEM
htmlentities (4.3.4)
http-2 (1.1.3)
http_parser.rb (0.8.1)
- httpx (1.7.4)
+ httpx (1.7.6)
http-2 (>= 1.1.3)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
@@ -744,9 +752,9 @@ GEM
reline (>= 0.4.2)
iso8601 (0.13.0)
jmespath (1.6.2)
- job-iteration (1.12.0)
- activejob (>= 6.1)
- json (2.19.2)
+ job-iteration (1.13.0)
+ activejob (>= 7.0)
+ json (2.19.3)
json-jwt (1.17.0)
activesupport (>= 4.2)
aes_key_wrap
@@ -774,7 +782,6 @@ GEM
addressable (~> 2.8)
childprocess (~> 5.0)
logger (~> 1.6)
- lefthook (2.1.4)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
letter_opener_web (3.0.0)
@@ -819,9 +826,9 @@ GEM
net-pop
net-smtp
marcel (1.0.4)
- markly (0.15.2)
+ markly (0.16.0)
matrix (0.4.3)
- mcp (0.8.0)
+ mcp (0.10.0)
json-schema (>= 4.1)
messagebird-rest (5.0.0)
jwt (< 4)
@@ -831,17 +838,16 @@ GEM
mime-types (3.7.0)
logger
mime-types-data (~> 3.2025, >= 3.2025.0507)
- mime-types-data (3.2026.0317)
+ mime-types-data (3.2026.0407)
mini_magick (5.3.1)
logger
mini_mime (1.1.5)
- minitest (6.0.2)
+ minitest (6.0.4)
drb (~> 2.0)
prism (~> 1.5)
msgpack (1.8.0)
- multi_json (1.19.1)
- mustermann (3.0.4)
- ruby2_keywords (~> 0.0.1)
+ multi_json (1.20.1)
+ mustermann (3.1.0)
mustermann-grape (1.1.0)
mustermann (>= 1.0.0)
net-http (0.9.1)
@@ -875,7 +881,7 @@ GEM
racc (~> 1.4)
nokogiri (1.19.2-x86_64-linux-musl)
racc (~> 1.4)
- oj (3.16.16)
+ oj (3.16.17)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
okcomputer (1.19.1)
@@ -912,11 +918,11 @@ GEM
openssl (4.0.1)
openssl-signature_algorithm (1.3.0)
openssl (> 2.0)
- opentelemetry-api (1.8.0)
+ opentelemetry-api (1.9.0)
logger
- opentelemetry-common (0.23.0)
+ opentelemetry-common (0.24.0)
opentelemetry-api (~> 1.0)
- opentelemetry-exporter-otlp (0.32.0)
+ opentelemetry-exporter-otlp (0.33.0)
google-protobuf (>= 3.18)
googleapis-common-protos-types (~> 1.3)
opentelemetry-api (~> 1.1)
@@ -1027,7 +1033,7 @@ GEM
opentelemetry-instrumentation-base (~> 0.25)
opentelemetry-instrumentation-lmdb (0.25.0)
opentelemetry-instrumentation-base (~> 0.25)
- opentelemetry-instrumentation-mongo (0.25.0)
+ opentelemetry-instrumentation-mongo (0.25.1)
opentelemetry-instrumentation-base (~> 0.25)
opentelemetry-instrumentation-mysql2 (0.33.0)
opentelemetry-helpers-mysql
@@ -1077,31 +1083,32 @@ GEM
opentelemetry-helpers-sql-processor
opentelemetry-instrumentation-base (~> 0.25)
opentelemetry-semantic_conventions (>= 1.8.0)
- opentelemetry-registry (0.4.0)
+ opentelemetry-registry (0.5.0)
opentelemetry-api (~> 1.1)
- opentelemetry-sdk (1.10.0)
+ opentelemetry-sdk (1.11.0)
+ logger
opentelemetry-api (~> 1.1)
opentelemetry-common (~> 0.20)
opentelemetry-registry (~> 0.2)
opentelemetry-semantic_conventions
- opentelemetry-semantic_conventions (1.36.0)
+ opentelemetry-semantic_conventions (1.37.0)
opentelemetry-api (~> 1.0)
optimist (3.2.1)
os (1.1.4)
ostruct (0.6.3)
ox (2.14.23)
bigdecimal (>= 3.0)
- pagy (43.4.1)
+ pagy (43.5.1)
json
uri
yaml
paper_trail (17.0.0)
activerecord (>= 7.1)
request_store (~> 1.4)
- parallel (1.27.0)
+ parallel (2.0.1)
parallel_tests (4.10.1)
parallel
- parser (3.3.10.2)
+ parser (3.3.11.1)
ast (~> 2.4.1)
racc
pdf-core (0.9.0)
@@ -1168,10 +1175,6 @@ GEM
bigdecimal
logger
rb_sys (~> 0.9.124)
- pry (0.16.0)
- coderay (~> 1.1)
- method_source (~> 1.0)
- reline (>= 0.6.0)
pry-byebug (3.12.0)
byebug (~> 13.0)
pry (>= 0.13, < 0.17)
@@ -1199,7 +1202,7 @@ GEM
puma (>= 5.0, < 8)
raabro (1.4.0)
racc (1.8.1)
- rack (2.2.22)
+ rack (2.2.23)
rack-attack (6.8.0)
rack (>= 1.0, < 4)
rack-cors (2.0.2)
@@ -1227,20 +1230,20 @@ GEM
rackup (1.0.1)
rack (< 3)
webrick
- rails (8.1.2.1)
- actioncable (= 8.1.2.1)
- actionmailbox (= 8.1.2.1)
- actionmailer (= 8.1.2.1)
- actionpack (= 8.1.2.1)
- actiontext (= 8.1.2.1)
- actionview (= 8.1.2.1)
- activejob (= 8.1.2.1)
- activemodel (= 8.1.2.1)
- activerecord (= 8.1.2.1)
- activestorage (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ rails (8.1.3)
+ actioncable (= 8.1.3)
+ actionmailbox (= 8.1.3)
+ actionmailer (= 8.1.3)
+ actionpack (= 8.1.3)
+ actiontext (= 8.1.3)
+ actionview (= 8.1.3)
+ activejob (= 8.1.3)
+ activemodel (= 8.1.3)
+ activerecord (= 8.1.3)
+ activestorage (= 8.1.3)
+ activesupport (= 8.1.3)
bundler (>= 1.15.0)
- railties (= 8.1.2.1)
+ railties (= 8.1.3)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
@@ -1255,9 +1258,9 @@ GEM
rails-i18n (8.1.0)
i18n (>= 0.7, < 2)
railties (>= 8.0.0, < 9)
- railties (8.1.2.1)
- actionpack (= 8.1.2.1)
- activesupport (= 8.1.2.1)
+ railties (8.1.3)
+ actionpack (= 8.1.3)
+ activesupport (= 8.1.3)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
@@ -1265,12 +1268,13 @@ GEM
tsort (>= 0.2)
zeitwerk (~> 2.6)
rainbow (3.1.1)
- rake (13.3.1)
+ rake (13.4.2)
rake-compiler-dock (1.11.0)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
- rb_sys (0.9.124)
+ rb_sys (0.9.126)
+ json (>= 2)
rake-compiler-dock (= 1.11.0)
rbtrace (0.5.3)
ffi (>= 1.0.6)
@@ -1281,13 +1285,13 @@ GEM
erb
psych (>= 4.0.0)
tsort
- recaptcha (5.21.1)
+ recaptcha (5.21.2)
redcarpet (3.6.1)
redis (5.4.1)
redis-client (>= 0.22.0)
redis-client (0.28.0)
connection_pool
- regexp_parser (2.11.3)
+ regexp_parser (2.12.0)
reline (0.6.3)
io-console (~> 0.5)
representable (3.2.0)
@@ -1331,12 +1335,11 @@ GEM
rspec-support (3.13.7)
rspec-wait (1.0.2)
rspec (>= 3.4)
- rubocop (1.85.1)
+ rubocop (1.86.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
- mcp (~> 0.6)
- parallel (~> 1.10)
+ parallel (>= 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
@@ -1352,7 +1355,7 @@ GEM
rubocop-factory_bot (2.28.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
- rubocop-openproject (0.3.0)
+ rubocop-openproject (0.4.0)
rubocop
rubocop-performance (1.26.1)
lint_roller (~> 1.1)
@@ -1388,7 +1391,6 @@ GEM
ruby-vips (2.3.0)
ffi (~> 1.12)
logger
- ruby2_keywords (0.0.5)
rubytree (2.2.0)
json (~> 2.0, > 2.9)
rubyzip (2.4.1)
@@ -1400,9 +1402,9 @@ GEM
scimitar (2.15.0)
rails (>= 7.0)
securerandom (0.4.1)
- selenium-devtools (0.145.0)
+ selenium-devtools (0.147.0)
selenium-webdriver (~> 4.2)
- selenium-webdriver (4.41.0)
+ selenium-webdriver (4.43.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
@@ -1436,7 +1438,7 @@ GEM
actionpack (>= 6.1)
activesupport (>= 6.1)
sprockets (>= 3.0.0)
- ssrf_filter (1.3.0)
+ ssrf_filter (1.5.0)
stackprof (0.2.28)
statesman (13.1.0)
store_attribute (2.1.1)
@@ -1455,11 +1457,11 @@ GEM
table_print (1.5.7)
terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4)
- test-prof (1.5.2)
+ test-prof (1.6.1)
text-hyphen (1.5.0)
thor (1.5.0)
thread_safe (0.3.6)
- timecop (0.9.10)
+ timecop (0.9.11)
timeout (0.6.1)
tpm-key_attestation (0.14.1)
bindata (~> 2.4)
@@ -1491,7 +1493,7 @@ GEM
public_suffix
vcr (6.4.0)
vernier (1.10.0)
- view_component (4.5.0)
+ view_component (4.6.0)
actionview (>= 7.1.0)
activesupport (>= 7.1.0)
concurrent-ruby (~> 1)
@@ -1552,7 +1554,7 @@ GEM
railties
yabeda (~> 0.8)
yaml (0.4.0)
- yard (0.9.38)
+ yard (0.9.42)
zeitwerk (2.7.5)
PLATFORMS
@@ -1576,13 +1578,13 @@ DEPENDENCIES
activerecord-session_store (~> 2.2.0)
acts_as_list (~> 1.2.6)
acts_as_tree (~> 2.9.0)
- addressable (~> 2.8.9)
+ addressable (~> 2.9.0)
airbrake (~> 13.0.0)
- appsignal (~> 4.7)
+ appsignal (~> 4.8)
auto_strip_attributes (~> 2.5)
awesome_nested_set (~> 3.9.0)
- aws-sdk-core (~> 3.241)
- aws-sdk-s3 (~> 1.213)
+ aws-sdk-core (~> 3.244)
+ aws-sdk-s3 (~> 1.217)
axe-core-rspec
bcrypt (~> 3.1.22)
bootsnap (~> 1.23.0)
@@ -1598,7 +1600,7 @@ DEPENDENCIES
climate_control
closure_tree (~> 9.6.1)
colored2
- commonmarker (~> 2.7.0)
+ commonmarker (~> 2.8.0)
compare-xml (~> 0.66)
connection_pool (~> 3.0.2)
costs!
@@ -1623,21 +1625,21 @@ DEPENDENCIES
escape_utils (~> 1.3)
factory_bot (~> 6.5.6)
factory_bot_rails (~> 6.5.0)
- ffi (~> 1.15)
+ ffi (~> 1.17)
flamegraph
fog-aws
friendly_id (~> 5.6.0)
fuubar (~> 2.5.0)
globalid (~> 1.3)
- good_job (~> 4.13.3)
+ good_job (~> 4.14.2)
google-apis-gmail_v1
googleauth
- grape (~> 3.1.1)
+ grape (~> 3.2.0)
grape_logging (~> 3.0.0)
grids!
html-pipeline (~> 2.14.0)
htmldiff
- httpx (~> 1.7.4)
+ httpx (~> 1.7.5)
i18n-js (~> 4.2.4)
i18n-tasks (~> 1.1.0)
ice_cube (~> 0.17.0)
@@ -1648,7 +1650,6 @@ DEPENDENCIES
json_spec (~> 1.1.4)
ladle
launchy (~> 3.1.0)
- lefthook
letter_opener_web
listen (~> 3.10.0)
lograge (~> 0.14.0)
@@ -1656,11 +1657,11 @@ DEPENDENCIES
mail (= 2.9.0)
markly (~> 0.15)
matrix (~> 0.4.3)
- mcp (~> 0.8.0)
+ mcp (~> 0.10.0)
md_to_pdf!
meta-tags (~> 2.23.0)
mini_magick (~> 5.3.0)
- multi_json (~> 1.19.0)
+ multi_json (~> 1.20.0)
my_page!
net-ldap (~> 0.20.0)
nokogiri (~> 1.19.2)
@@ -1697,7 +1698,7 @@ DEPENDENCIES
openproject-webhooks!
openproject-wikis!
openproject-xls_export!
- opentelemetry-exporter-otlp (~> 0.32.0)
+ opentelemetry-exporter-otlp (~> 0.33.0)
opentelemetry-instrumentation-all (~> 0.91.0)
opentelemetry-sdk (~> 1.10)
overviews!
@@ -1709,6 +1710,7 @@ DEPENDENCIES
pg (~> 1.6.2)
plaintext (~> 0.3.7)
prawn (~> 2.4)
+ pry!
pry-byebug (~> 3.12.0)
pry-rails (~> 0.3.6)
pry-rescue (~> 1.6.0)
@@ -1722,7 +1724,7 @@ DEPENDENCIES
rack-test (~> 2.2.0)
rack-timeout (~> 0.7.0)
rack_session_access
- rails (~> 8.1.2)
+ rails (~> 8.1.3)
rails-controller-testing (~> 1.0.2)
rails-i18n (~> 8.1.0)
rbtrace
@@ -1771,7 +1773,7 @@ DEPENDENCIES
svg-graph (~> 2.2.0)
sys-filesystem (~> 1.5.0)
table_print (~> 1.5.6)
- test-prof (~> 1.5.0)
+ test-prof (~> 1.6.0)
timecop (~> 0.9.0)
ttfunk (~> 1.7.0)
turbo-rails (~> 2.0.20)
@@ -1781,7 +1783,7 @@ DEPENDENCIES
validate_url
vcr
vernier
- view_component (~> 4.5.0)
+ view_component (~> 4.6.0)
warden (~> 1.2)
warden-basic_auth (~> 0.2.1)
webmock (~> 3.26)
@@ -1794,44 +1796,44 @@ DEPENDENCIES
CHECKSUMS
Ascii85 (2.0.1) sha256=15cb5d941808543cbb9e7e6aea3c8ec3877f154c3461e8b3673e97f7ecedbe5a
- action_text-trix (2.1.17) sha256=b44691639d77e67169dc054ceacd1edc04d44dc3e4c6a427aa155a2beb4cc951
- actioncable (8.1.2.1) sha256=a2f88cecce148b3fcb63d2e517d7694e119830a85baa7d6cf59e5453dcf32e8d
- actionmailbox (8.1.2.1) sha256=c2e45c0c1e5687e35e050838c94a8aed0d954c56a32ea411d54cd848c338c54e
- actionmailer (8.1.2.1) sha256=d7d62fbc2197f1a7006bb5af4c665edf999adf79ab6c10337c088d27e6622071
- actionpack (8.1.2.1) sha256=a6b69cd10ec4c8d978c8eee51206e34152b1c1be017e534236dbc89a3d00ffb8
+ action_text-trix (2.1.18) sha256=3fdb83f8bff4145d098be283cdd47ac41caf5110bfa6df4695ed7127d7fb3642
+ actioncable (8.1.3) sha256=e5bc7f75e44e6a22de29c4f43176927c3a9ce4824464b74ed18d8226e75a80f0
+ actionmailbox (8.1.3) sha256=df7da474eaa0e70df4ed5a6fef66eb3b3b0f2dbf7f14518deee8d77f1b4aae59
+ actionmailer (8.1.3) sha256=831f724891bb70d0aaa4d76581a6321124b6a752cb655c9346aae5479318448d
+ actionpack (8.1.3) sha256=af998cae4d47c5d581a2cc363b5c77eb718b7c4b45748d81b1887b25621c29a3
actionpack-xml_parser (2.0.1) sha256=40cb461ee99445314ab580a783fb7413580deb8b28113c9e70ecd7c1b334d5e6
- actiontext (8.1.2.1) sha256=1e503ce600a6ab2e12a46f999959a7d8e2fdaff910ca01dcf3b968934b55d957
- actionview (8.1.2.1) sha256=38daa7b87bca427e2967f139e5b7f0d1081271bdafd0e015d8ef97a006f570a6
+ actiontext (8.1.3) sha256=d291019c00e1ea9e6463011fa214f6081a56d7b9a1d224e7d3f6384c1dafc7d2
+ actionview (8.1.3) sha256=1347c88c7f3edb38100c5ce0e9fb5e62d7755f3edc1b61cce2eb0b2c6ea2fd5d
active_record_doctor (2.0.1) sha256=7af0ac02195385c8f2f67d0e4ebe72b1fc79d65eaaf329e0db07f4d12a84069a
- activejob (8.1.2.1) sha256=c89c311d07fd358b76c581ed8fee87c5b4351fb44994f3389385c014d22182fe
- activemodel (8.1.2.1) sha256=8f31a6f9c12fecb8e5a0fce8a8950cfd94f0d75829322935f99e8217a3e5f3c6
+ activejob (8.1.3) sha256=a149b1766aa8204c3c3da7309e4becd40fcd5529c348cffbf6c9b16b565fe8d3
+ activemodel (8.1.3) sha256=90c05cbe4cef3649b8f79f13016191ea94c4525ce4a5c0fb7ef909c4b91c8219
activemodel-serializers-xml (1.0.3) sha256=fa1b16305e7254cc58a59c68833e3c0a593a59c8ab95d3be5aaea7cd9416c397
- activerecord (8.1.2.1) sha256=3f79140318ff6d23376f5d9b1b5b5e2c7d3cc8979dd71367e9a8394378ca630a
+ activerecord (8.1.3) sha256=8003be7b2466ba0a2a670e603eeb0a61dd66058fccecfc49901e775260ac70ab
activerecord-import (2.2.0) sha256=f8ca99b196e50775723d1f1d192c379f656378dc9f5628240992a0d78807fa4b
activerecord-nulldb-adapter (1.2.2) sha256=01e0b2e49af11ad56a92e274a3d8c9fb3c50a12a5460218c4c4b45355d9ef968
activerecord-session_store (2.2.0) sha256=65918054573683bf4f87af89e765e1fece14c9d71cfac1f11abe4687c96e2743
- activestorage (8.1.2.1) sha256=36794c9b8853ac9276b0386cb1f8973374d8e71e8a9666bb02e70f5b7c9c5391
- activesupport (8.1.2.1) sha256=beec20ced12ad569194554399449a6372fdab03061b8f48a9ed6ef9b7dc251b2
+ activestorage (8.1.3) sha256=0564ce9309143951a67615e1bb4e090ee54b8befed417133cae614479b46384d
+ activesupport (8.1.3) sha256=21a5e0dfbd4c3ddd9e1317ec6a4d782fa226e7867dc70b0743acda81a1dca20e
acts_as_list (1.2.6) sha256=8345380900b7bee620c07ad00991ccee59af3d8c9e8574f426e321da2865fdc8
acts_as_tree (2.9.1) sha256=b869eb10a8de38616b64ffcf9e882d3d99c8e06909c4057078a76c3b89a9a2f3
- addressable (2.8.9) sha256=cc154fcbe689711808a43601dee7b980238ce54368d23e127421753e46895485
+ addressable (2.9.0) sha256=7fdf6ac3660f7f4e867a0838be3f6cf722ace541dd97767fa42bc6cfa980c7af
aes_key_wrap (1.1.0) sha256=b935f4756b37375895db45669e79dfcdc0f7901e12d4e08974d5540c8e0776a5
afm (1.0.0) sha256=5bd4d6f6241e7014ef090985ec6f4c3e9745f6de0828ddd58bc1efdd138f4545
airbrake (13.0.5) sha256=901f5074c25d5ef77ed87f5bde7a28400a7324f5d7013a8a12d07e0099cc31b6
airbrake-ruby (6.2.2) sha256=293e34fb36e763e1b6d67ab584cce7c5b6fe9eea1a70c26d8c13c0f5d7de2fbc
android_key_attestation (0.3.0) sha256=467eb01a99d2bb48ef9cf24cc13712669d7056cba5a52d009554ff037560570b
anyway_config (2.8.0) sha256=f6797a7231f81202dcd3d0c07284e836e45713e761d320180348b13a5c7c9306
- appsignal (4.8.3) sha256=aa0ea5ffd39fe7530c56a6eb6efda60825ab061ef31376126cae93b009844dd7
+ appsignal (4.8.4) sha256=5c708a41c2913383d19ae581140da1904dbf642b974220d6c1bc4c7fdb1cf667
ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383
attr_required (1.0.2) sha256=f0ebfc56b35e874f4d0ae799066dbc1f81efefe2364ca3803dc9ea6a4de6cb99
auto_strip_attributes (2.6.0) sha256=a7e2e0cf744de2bcd947fd68014220702bcc88c81274c1cd9ce6f7316aae39b0
awesome_nested_set (3.9.0) sha256=3ce99e816550f97f4de118e621630070aacf24928b920fe4a68846578a8daaed
aws-eventstream (1.4.0) sha256=116bf85c436200d1060811e6f5d2d40c88f65448f2125bc77ffce5121e6e183b
- aws-partitions (1.1227.0) sha256=122dd20fe108cb38d38cccbc1f2592408bc1b30ca6e0d05797a7af2501567e29
- aws-sdk-core (3.243.0) sha256=a014eef785124b71d28325783fa422a1512f8421ec9b6e3931c8b0ca3fbb0f1c
- aws-sdk-kms (1.122.0) sha256=47ce3f51b26bd7d76f1270cfdfca17b40073ecd3219c8c9400788712abfb4eb8
- aws-sdk-s3 (1.216.0) sha256=a3bf6191e6f7a3dfb04b7cc73409f059394be559e4aff92d2a764341e4d90af4
- aws-sdk-sns (1.112.0) sha256=aff1b1b5bbcb4229599221c558a41790c1cd1a1fed47ac3d27d27512ad24b254
+ aws-partitions (1.1238.0) sha256=fa3d1bdea6d7e7619e8cee22ebce8a569d2119296d3ec8c5f9b9b7c81fb0602c
+ aws-sdk-core (3.244.0) sha256=3e458c078b0c5bdee95bc370c3a483374b3224cf730c1f9f0faf849a5d9a18ea
+ aws-sdk-kms (1.123.0) sha256=d405f37e82f8fa32045ca8980be266c0b45b37aaf2012afe0254321a1e811f20
+ aws-sdk-s3 (1.219.0) sha256=6a755d7377978525758b3c29185ca6a10128ce2b07555ca37c4549de10c2f1c7
+ aws-sdk-sns (1.113.0) sha256=15fe37d010e86f4c28b4c2f2133c463ce5c14189ec3673a1f43c30dfee511b0f
aws-sigv4 (1.12.1) sha256=6973ff95cb0fd0dc58ba26e90e9510a2219525d07620c8babeb70ef831826c00
axe-core-api (4.11.1) sha256=a6460506449a692030620a0574fee7afa6cd38cfbbf6620d20bf4d53d33a80cc
axe-core-rspec (4.11.1) sha256=dc6c0e166405cd3a28c4a0937f6521ee5b511c12c0ca1627144a1ee7d5014aec
@@ -1840,7 +1842,7 @@ CHECKSUMS
bcrypt (3.1.22) sha256=1f0072e88c2d705d94aff7f2c5cb02eb3f1ec4b8368671e19112527489f29032
benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c
better_html (2.2.0) sha256=e68ab66ab09696b708333bbf35e8aa3c107500ba7892f528e2111624bdd8cf76
- bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7
+ bigdecimal (4.1.1) sha256=1c09efab961da45203c8316b0cdaec0ff391dfadb952dd459584b63ebf8054ca
bindata (2.5.1) sha256=53186a1ec2da943d4cb413583d680644eb810aacbf8902497aac8f191fad9e58
bootsnap (1.23.0) sha256=c1254f458d58558b58be0f8eb8f6eec2821456785b7cdd1e16248e2020d3f214
brakeman (8.0.4) sha256=7bf921fa9638544835df9aa7b3e720a9a72c0267f34f92135955edd80d4dcf6f
@@ -1853,7 +1855,7 @@ CHECKSUMS
capybara_accessible_selectors (0.15.0)
carrierwave (2.2.6) sha256=cd9b6108fc7544e97e7fbcc561bd319a09f23c96816fdd0df8f2f45ffdc0dac3
carrierwave_direct (3.0.0) sha256=da4105ec7beea2687817b95ad95181be3d657248ec1cb5a0e5c35a45b176fc2f
- cbor (0.5.10.1) sha256=79cdf79f18dcd9ee97e0b849c6d573e5a2e3ddc1954d180f384d6ed2612b6df0
+ cbor (0.5.10.2) sha256=df5104f7a62c881123e6505441b1e276208be1771540c2cc3b1de8a210a7c52c
cgi (0.5.1) sha256=e93fcafc69b8a934fe1e6146121fa35430efa8b4a4047c4893764067036f18e9
childprocess (5.1.0) sha256=9a8d484be2fd4096a0e90a0cd3e449a05bc3aa33f8ac9e4d6dcef6ac1455b6ec
climate_control (1.2.0) sha256=36b21896193fa8c8536fa1cd843a07cf8ddbd03aaba43665e26c53ec1bd70aa5
@@ -1862,20 +1864,20 @@ CHECKSUMS
coercible (1.0.0) sha256=5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc
color_conversion (0.1.2) sha256=99bea5fa412e1527a11389975aa6ad445ff8528ebae202c11d08c45ea2b94c96
colored2 (4.0.3) sha256=63e1038183976287efc43034f5cca17fb180b4deef207da8ba78d051cbce2b37
- commonmarker (2.7.0-aarch64-linux) sha256=a15a47bb901f4cfcb3b4fe54d0daf91ec46e70b6e9704c67abec0ba30064b2dc
- commonmarker (2.7.0-aarch64-linux-musl) sha256=fa08eb19ffc3cf2f7132d86d74622338a0c35b480b23814a7ae63deaeafb56d3
- commonmarker (2.7.0-arm-linux) sha256=85274d47feca40bd574ac49c2959a015464936f7f830c1e2918ee147d5be1a13
- commonmarker (2.7.0-arm64-darwin) sha256=ef00f7efef4822e8e7f88be88920a319f71a251e894e02fbc82f6db5d4291db3
- commonmarker (2.7.0-x86_64-darwin) sha256=a8f5928f36138347b5e672d080b8f76dc430c6207566128b117cdd02f3e48c34
- commonmarker (2.7.0-x86_64-linux) sha256=53243eeb30e4ddb6a474672597ff7e59334e55a7653126bb87e65e6ab2629a4c
- commonmarker (2.7.0-x86_64-linux-musl) sha256=e4f5c06975f37a405bd157d276609e1c02502d2fbaf576f6e3616fba2e7b5662
+ commonmarker (2.8.1-aarch64-linux) sha256=f855599cc6855f4137d72dcacae9571451075afe6e6c8522eba353df9b81d0bf
+ commonmarker (2.8.1-aarch64-linux-musl) sha256=bbc2b3d361403431a5aac737dc86997d3b2843276ef395e7499cf17ad48e1b2c
+ commonmarker (2.8.1-arm-linux) sha256=ede48564a9c2e29e003361fd7b0b158b3b85bcbd5a15b963fa2b3c78eef3993f
+ commonmarker (2.8.1-arm64-darwin) sha256=cf75760122d6e1c3f8626b5a6911636d2e0aaa26fa8dd377fea440a49c854b3e
+ commonmarker (2.8.1-x86_64-darwin) sha256=75afa559c1f1cc201afbb81291a2f2fc77b2941347deaa8d564d008ba04ecb18
+ commonmarker (2.8.1-x86_64-linux) sha256=c8f2e903c6ee4e2c7e280aa8b49ef37c53202d388e3a2ee06dfdccc8c6fb634f
+ commonmarker (2.8.1-x86_64-linux-musl) sha256=9b6305ce47e0d444b77dabf1762bf76085c2f7963b63c25c02ec36edcf06c785
compare-xml (0.66) sha256=e21aa5c0f69ef1177eced997c688fd4df989084e74a1b612257af32e1dd05319
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
cookiejar (0.3.4) sha256=11b16acfc4baf7a0f463c21a6212005e04e25f5554d4d9f24d97f3492dfda0df
cose (1.3.1) sha256=d5d4dbcd6b035d513edc4e1ab9bc10e9ce13b4011c96e3d1b8fe5e6413fd6de5
costs (1.0.0)
- counter_culture (3.12.2) sha256=26358dbb15e2f1f7e60f2c11976e37517a74ffd34eb5ef8d7269862b9ff8aadd
+ counter_culture (3.13.0) sha256=a2cde20642ddd27aec9ff0c09b73fa5b4fd729da368079e67c177bface3148bf
crack (1.0.1) sha256=ff4a10390cd31d66440b7524eb1841874db86201d5b70032028553130b6d4c7e
crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d
css_parser (2.0.0) sha256=af5c759a127b125b635006a6c6c2e05b96a1ebdeec21b3c415fd5f09ec714a0a
@@ -1911,7 +1913,7 @@ CHECKSUMS
em-synchrony (1.0.6) sha256=6e7470a684d9bbc00d61d552911b65711540bd89e95c157156f5aacdd6f306ca
email_validator (2.2.4) sha256=5ab238095bec7aef9389f230e9e0c64c5081cdf91f19d6c5cecee0a93af20604
equivalent-xml (0.6.0) sha256=8919761efa848ad0846369ff8be1f646b17e5061698c4867b09829000cc3f487
- erb (6.0.2) sha256=9fe6264d44f79422c87490a1558479bd0e7dad4dd0e317656e67ea3077b5242b
+ erb (6.0.3) sha256=e43685a8a0a0ea6a924871b2162e8953ef73147ce46b75b36d1f6774fd286e91
erb_lint (0.9.0) sha256=dfb5e40ad839e8d1f0d56ca85ec9a7ac4c9cd966ec281138282f35b323ca7c31
erblint-github (1.0.1) sha256=9f28f7dc381a0dc68a0093ef7af3424ed9d2bb2b3e39bdc8e8cba86a0d31f2d0
erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9
@@ -1919,22 +1921,21 @@ CHECKSUMS
et-orbi (1.4.0) sha256=6c7e3c90779821f9e3b324c5e96fda9767f72995d6ae435b96678a4f3e2de8bc
eventmachine (1.2.7) sha256=994016e42aa041477ba9cff45cbe50de2047f25dd418eba003e84f0d16560972
eventmachine_httpserver (0.2.1) sha256=5db5e8a23754204d43592e5fcc2160457c57c870babe6307c4e61fc95019b809
- excon (1.4.0) sha256=5d2bc9d2c79511a562e7fcac77cc7a40acd9cebcc55b80e537975ad8187f2924
+ excon (1.4.2) sha256=32d8d8eda619717d9b8043b4675e096fb5c2139b080e2ad3b267f88c545aaa35
factory_bot (6.5.6) sha256=12beb373214dccc086a7a63763d6718c49769d5606f0501e0a4442676917e077
factory_bot_rails (6.5.1) sha256=d3cc4851eae4dea8a665ec4a4516895045e710554d2b5ac9e68b94d351bc6d68
faraday (2.14.1) sha256=a43cceedc1e39d188f4d2cdd360a8aaa6a11da0c407052e426ba8d3fb42ef61c
faraday-follow_redirects (0.5.0) sha256=5cde93c894b30943a5d2b93c2fe9284216a6b756f7af406a1e55f211d97d10ad
faraday-net_http (3.4.2) sha256=f147758260d3526939bf57ecf911682f94926a3666502e24c69992765875906c
- fastimage (2.4.1) sha256=c64bebd46b6fd8943ab70c1e6e85ff728f970f2e48f92ecd249b6bc3a540ad20
- ferrum (0.17.1) sha256=51d591120fc593e5a13b5d9d6474389f5145bb92a91e36eab147b5d096c8cbe7
- ffi (1.17.3-aarch64-linux-gnu) sha256=28ad573df26560f0aedd8a90c3371279a0b2bd0b4e834b16a2baa10bd7a97068
- ffi (1.17.3-aarch64-linux-musl) sha256=020b33b76775b1abacc3b7d86b287cef3251f66d747092deec592c7f5df764b2
- ffi (1.17.3-arm-linux-gnu) sha256=5bd4cea83b68b5ec0037f99c57d5ce2dd5aa438f35decc5ef68a7d085c785668
- ffi (1.17.3-arm-linux-musl) sha256=0d7626bb96265f9af78afa33e267d71cfef9d9a8eb8f5525344f8da6c7d76053
- ffi (1.17.3-arm64-darwin) sha256=0c690555d4cee17a7f07c04d59df39b2fba74ec440b19da1f685c6579bb0717f
- ffi (1.17.3-x86_64-darwin) sha256=1f211811eb5cfaa25998322cdd92ab104bfbd26d1c4c08471599c511f2c00bb5
- ffi (1.17.3-x86_64-linux-gnu) sha256=3746b01f677aae7b16dc1acb7cb3cc17b3e35bdae7676a3f568153fb0e2c887f
- ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56
+ ferrum (0.17.2) sha256=2c2540a850b211a46f4d81de21bfd62048f507e4c327d1807225c3823c17e6ee
+ ffi (1.17.4-aarch64-linux-gnu) sha256=b208f06f91ffd8f5e1193da3cae3d2ccfc27fc36fba577baf698d26d91c080df
+ ffi (1.17.4-aarch64-linux-musl) sha256=9286b7a615f2676245283aef0a0a3b475ae3aae2bb5448baace630bb77b91f39
+ ffi (1.17.4-arm-linux-gnu) sha256=d6dbddf7cb77bf955411af5f187a65b8cd378cb003c15c05697f5feee1cb1564
+ ffi (1.17.4-arm-linux-musl) sha256=9d4838ded0465bef6e2426935f6bcc93134b6616785a84ffd2a3d82bc3cf6f95
+ ffi (1.17.4-arm64-darwin) sha256=19071aaf1419251b0a46852abf960e77330a3b334d13a4ab51d58b31a937001b
+ ffi (1.17.4-x86_64-darwin) sha256=aa70390523cf3235096cf64962b709b4cfbd5c082a2cb2ae714eb0fe2ccda496
+ ffi (1.17.4-x86_64-linux-gnu) sha256=9d3db14c2eae074b382fa9c083fe95aec6e0a1451da249eab096c34002bc752d
+ ffi (1.17.4-x86_64-linux-musl) sha256=3fdf9888483de005f8ef8d1cf2d3b20d86626af206cbf780f6a6a12439a9c49e
flamegraph (0.9.5) sha256=a683020637ffa0e14a72640fa41babf14d926bfeaed87e31907cfd06ab2de8dc
fog-aws (3.33.1) sha256=20c7336ed978be6cbf2765844c53f30676288af98f1cb49945aa7b7b45a799a5
fog-core (2.6.0) sha256=3fe08aa83a23cddce42f4ba412040c08f890d7ff04c175c0ee59119371245be6
@@ -1947,21 +1948,21 @@ CHECKSUMS
fuubar (2.5.1) sha256=b272a7804b282661c7fab583a3764f92543cb482c365ae39c685cd218fdd4880
glob (0.4.0) sha256=893dc9e2d24abe13dda907ce0cda576f680ff382f2a6cf9e543f98ecbe29238c
globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11
- good_job (4.13.3) sha256=37478710dddd2630ed055f2159111ce6f7f14482d8ccb412142ee04674151e2e
+ good_job (4.14.2) sha256=f38f164346aee724bbfbdaed73e1a0bd382cc6354146029e0adcc619245ab6d1
google-apis-core (1.0.2) sha256=ba4579aaadc902d6cc7bc8db88f566ab00f5e31ea87ab41e9f9a032c470f2629
google-apis-gmail_v1 (0.47.0) sha256=3064434b6da55b85e2828ce4bb0f4d04e8cfd187a4ab262ceb1dcb01f98e49ef
google-cloud-env (2.3.1) sha256=0faac01eb27be78c2591d64433663b1a114f8f7af55a4f819755426cac9178e7
google-logging-utils (0.2.0) sha256=675462b4ea5affa825a3442694ca2d75d0069455a1d0956127207498fca3df7b
- google-protobuf (4.34.0) sha256=bffaea30fbe2807c80667a78953b15645b3bef62b25c10ca187e4418119be531
- google-protobuf (4.34.0-aarch64-linux-gnu) sha256=0ab8a8a97976a2265d647e69b3ff1980c89184abdaf06d36091856c5ab37cc55
- google-protobuf (4.34.0-aarch64-linux-musl) sha256=0632a86df6d320eac3b335bd779499d43ad8ee6d1f8c8494b773ed5d3d5c6ab4
- google-protobuf (4.34.0-arm64-darwin) sha256=f83967a8095a9da676b79ba372c58fef2ca3878428bd40febfce65b3752c90d1
- google-protobuf (4.34.0-x86_64-darwin) sha256=4a5b67281993345adca54bb32947f25a289597eafaa240e5b714d0a740f99321
- google-protobuf (4.34.0-x86_64-linux-gnu) sha256=bbb333fbe79c16f35a2e2154cf29f3ce26f60390dba286b339861206d5435ef9
- google-protobuf (4.34.0-x86_64-linux-musl) sha256=0b75858a388b17e73aa4176df2e722762dbc92551b7075fdc562d33c1c6de0b0
+ google-protobuf (4.34.1) sha256=347181542b8d659c60f028fa3791c9cccce651a91ad27782dbc5c5e374796cdc
+ google-protobuf (4.34.1-aarch64-linux-gnu) sha256=f9c07607dc139c895f2792a7740fcd01cd94d4d7b0e0a939045b50d7999f0b1d
+ google-protobuf (4.34.1-aarch64-linux-musl) sha256=db58e5a4a492b43c6614486aea31b7fb86955b175d1d48f28ebf388f058d78a9
+ google-protobuf (4.34.1-arm64-darwin) sha256=2745061f973119e6e7f3c81a0c77025d291a3caa6585a2cd24a25bbc7bedb267
+ google-protobuf (4.34.1-x86_64-darwin) sha256=4dc498376e218871613589c4d872400d42ad9ae0c700bdb2606fe1c77a593075
+ google-protobuf (4.34.1-x86_64-linux-gnu) sha256=87088c9fd8e47b5b40ca498fc1195add6149e941ff7e81c532a5b0b8876d4cc9
+ google-protobuf (4.34.1-x86_64-linux-musl) sha256=8c0e91436fbe504ffc64f0bd621f2e69adbcce8ed2c58439d7a21117069cfdd7
googleapis-common-protos-types (1.22.0) sha256=f97492b77bd6da0018c860d5004f512fe7cd165554d7019a8f4df6a56fbfc4c7
googleauth (1.16.2) sha256=15009502e2e38af71948cda918f230e27d327f6882a1e47967a5a4664930a638
- grape (3.1.1) sha256=774f16782d917a90e69de0499dfaab571e5ad967569ac066a2b0b918af12de69
+ grape (3.2.0) sha256=2aeeb020e5605f6314ce8ca8d30d90c9ee8f26bc959c5b34db7b8486764e4d2c
grape_logging (3.0.0) sha256=7b62d984ce96df15d120508668debe307e6a59ac1c511f1d9b5f3b4bea793e13
gravatar_image_tag (1.2.0) sha256=eb5630fea846b711e713b934a0178fb9785f02f4eb9ced8d6faa4d537c40fdcf
grids (1.0.0)
@@ -1976,7 +1977,7 @@ CHECKSUMS
htmlentities (4.3.4) sha256=125a73c6c9f2d1b62100b7c3c401e3624441b663762afa7fe428476435a673da
http-2 (1.1.3) sha256=1b2f379d35a11dbae94f8a1a52c053d8c161eb4a0c98b5d1605ff1b2bf171c9c
http_parser.rb (0.8.1) sha256=9ae8df145b39aa5398b2f90090d651c67bd8e2ebfe4507c966579f641e11097a
- httpx (1.7.4) sha256=91fb3e0f7325966a5da4d463a1dd7240e8550d8b0de79e346cc5dc1df1eacd2b
+ httpx (1.7.6) sha256=82d825abc9876a132adc3492c56a0c528478ac238dd6f74d3422ab0036c6b5c8
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
i18n-js (4.2.4) sha256=61390d372f8fa68c495c5907d577657e8cc3a7031f4945db1e91f935e1391355
i18n-tasks (1.1.2) sha256=4dcfba49e52a623f30661cb316cb80d84fbba5cb8c6d88ef5e02545fffa3637a
@@ -1990,8 +1991,8 @@ CHECKSUMS
irb (1.17.0) sha256=168c4ddb93d8a361a045c41d92b2952c7a118fa73f23fe14e55609eb7a863aae
iso8601 (0.13.0) sha256=298c2b15b7be5fa95a1372813d36a2257656cd8e906dfbc1f5cb409851425aa2
jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1
- job-iteration (1.12.0) sha256=0164057417750f6e9c3ed548f029f1136b18eb53975fa438b09304a525d6c6c0
- json (2.19.2) sha256=e7e1bd318b2c37c4ceee2444841c86539bc462e81f40d134cf97826cb14e83cf
+ job-iteration (1.13.0) sha256=3300844e81309fbd06fd2310d6aa8e1f43bf30fe03a3fc5067580b62f456b7e1
+ json (2.19.3) sha256=289b0bb53052a1fa8c34ab33cc750b659ba14a5c45f3fcf4b18762dc67c78646
json-jwt (1.17.0) sha256=6ff99026b4c54281a9431179f76ceb81faa14772d710ef6169785199caadc4cc
json-schema (6.2.0) sha256=e8bff46ed845a22c1ab2bd0d7eccf831c01fe23bb3920caa4c74db4306813666
json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
@@ -2000,7 +2001,6 @@ CHECKSUMS
ladle (1.0.1) sha256=e8586964108c798d48bf57d2a65bd5602e8e5223a176b6602a0fb36c0bda90dc
language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc
launchy (3.1.1) sha256=72b847b5cc961589dde2c395af0108c86ff0119f42d4648d25b5440ebb10059e
- lefthook (2.1.4) sha256=b3c5bba86911e85b239fea3861ba8c74740fc084ba9ac79dba3fe79267572d6a
letter_opener (1.10.0) sha256=2ff33f2e3b5c3c26d1959be54b395c086ca6d44826e8bf41a14ff96fdf1bdbb2
letter_opener_web (3.0.0) sha256=3f391efe0e8b9b24becfab5537dfb17a5cf5eb532038f947daab58cb4b749860
lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
@@ -2012,21 +2012,21 @@ CHECKSUMS
lookbook (2.3.14) sha256=c11a693bde9915b553c4463440ad5e750829f90bff08abdb6b8610373864cd7c
mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941
marcel (1.0.4) sha256=0d5649feb64b8f19f3d3468b96c680bae9746335d02194270287868a661516a4
- markly (0.15.2) sha256=65dae965d4dd4ecd997fba43b93acc0fe7dadfec6f07a748640c7a9299a8551e
+ markly (0.16.0) sha256=6f70d79e385b1efc9e171f74c81628826259039fe6c778e03c3924c71dac5511
matrix (0.4.3) sha256=a0d5ab7ddcc1973ff690ab361b67f359acbb16958d1dc072b8b956a286564c5b
- mcp (0.8.0) sha256=ae8bd146bb8e168852866fd26f805f52744f6326afb3211e073f78a95e0c34fb
+ mcp (0.10.0) sha256=09b9231eb16dff75cc7b8a95817c8acfcf4d1cab8d34f350671e43e765242b57
md_to_pdf (0.2.6)
messagebird-rest (5.0.0) sha256=da4cc1efba3d5e4aa021fad07426c2cb6b326ce5670da5104bb8f6056a39d59c
meta-tags (2.23.0) sha256=ffe78b5bee398de4ff5ac3316f5a786049538a651643b8476def06c3acc762c1
method_source (1.1.0) sha256=181301c9c45b731b4769bc81e8860e72f9161ad7d66dd99103c9ab84f560f5c5
mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56
- mime-types-data (3.2026.0317) sha256=77f078a4d8631d52b842ba77099734b06eddb7ad339d792e746d2272b67e511b
+ mime-types-data (3.2026.0407) sha256=909395cf029731355136527aa11bf58ea0655ee782359ccbf32c66238a8cadb3
mini_magick (5.3.1) sha256=29395dfd76badcabb6403ee5aff6f681e867074f8f28ce08d78661e9e4a351c4
mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef
- minitest (6.0.2) sha256=db6e57956f6ecc6134683b4c87467d6dd792323c7f0eea7b93f66bd284adbc3d
+ minitest (6.0.4) sha256=df1304664589d40f46089247fdc451f866b0ce0d7cae1457a15fc1eb7d48dca1
msgpack (1.8.0) sha256=e64ce0212000d016809f5048b48eb3a65ffb169db22238fb4b72472fecb2d732
- multi_json (1.19.1) sha256=7aefeff8f2c854bf739931a238e4aea64592845e0c0395c8a7d2eea7fdd631b7
- mustermann (3.0.4) sha256=85fadcb6b3c6493a8b511b42426f904b7f27b282835502233dd154daab13aa22
+ multi_json (1.20.1) sha256=2f3934e805cc45ef91b551a1f89d0e9191abd06a5e04a2ef09a6a036c452ca6d
+ mustermann (3.1.0) sha256=e73b006ffb7f743eae9303a7d6622e0dd9e1e5522718a2139c006085878768b9
mustermann-grape (1.1.0) sha256=8d258a986004c8f01ce4c023c0b037c168a9ed889cf5778068ad54398fa458c5
my_page (1.0.0)
net-http (0.9.1) sha256=25ba0b67c63e89df626ed8fac771d0ad24ad151a858af2cc8e6a716ca4336996
@@ -2044,7 +2044,7 @@ CHECKSUMS
nokogiri (1.19.2-x86_64-darwin) sha256=7d9af11fda72dfaa2961d8c4d5380ca0b51bc389dc5f8d4b859b9644f195e7a4
nokogiri (1.19.2-x86_64-linux-gnu) sha256=fa8feca882b73e871a9845f3817a72e9734c8e974bdc4fbad6e4bc6e8076b94f
nokogiri (1.19.2-x86_64-linux-musl) sha256=93128448e61a9383a30baef041bf1f5817e22f297a1d400521e90294445069a8
- oj (3.16.16) sha256=3635b36128991796434f55da8decc0de236a323535adcb36fc04e6d0253c013d
+ oj (3.16.17) sha256=a6688f666143632a1ef11a8d80c8d631b1112733c7da698ffafa4a22a8488244
okcomputer (1.19.1) sha256=7df770e768434816d228407f0786563827cbf34cb379933578829720cb4f1e77
omniauth (1.9.2)
omniauth-openid-connect (0.5.0)
@@ -2082,9 +2082,9 @@ CHECKSUMS
openproject-xls_export (1.0.0)
openssl (4.0.1) sha256=e27974136b7b02894a1bce46c5397ee889afafe704a839446b54dc81cb9c5f7d
openssl-signature_algorithm (1.3.0) sha256=a3b40b5e8276162d4a6e50c7c97cdaf1446f9b2c3946a6fa2c14628e0c957e80
- opentelemetry-api (1.8.0) sha256=3af51183daf0f56a164bc1579782245be70a40678566b9a393cbe5af28ea87c6
- opentelemetry-common (0.23.0) sha256=da721190479d57bae0ad2207468f47f3e2c3b9a91024b5bc32c9d280183eb32c
- opentelemetry-exporter-otlp (0.32.0) sha256=fd4c77a07bb96919e8ff8bbd19ed96d07cac1e368d8e920af2bf2ab02bfb1ec3
+ opentelemetry-api (1.9.0) sha256=d24065dd26583babd8d498d38ea35f74dfa193fb7102512e6e161649440079fb
+ opentelemetry-common (0.24.0) sha256=f1647b233b8ac667feeb74d66a65b702008d9ab55aae825c220b4fe2c14fa773
+ opentelemetry-exporter-otlp (0.33.0) sha256=6e9ce38e393c7eb9aea3fb57b128174a0066767bf495f4fd9e63d7607e0b2ad3
opentelemetry-helpers-mysql (0.5.0) sha256=8c2a5d5428aec271a7d2e25c158d06d4d8a914143b5004305964d1fcbc176eca
opentelemetry-helpers-sql (0.3.0) sha256=4bb08017d6a16dd41c4d1c53c7fd30f9c5bb691195d8b458933724627b3f37f9
opentelemetry-helpers-sql-processor (0.4.0) sha256=ec238d7a2887219bd247dc31d0eb8a1a03d414a899963b68e14bb9f4d18b23f4
@@ -2117,7 +2117,7 @@ CHECKSUMS
opentelemetry-instrumentation-httpx (0.7.0) sha256=3928185b62066cf6d8fe3b011dc5587ba53b09a5c7b573e36481b8d713d6aa03
opentelemetry-instrumentation-koala (0.23.0) sha256=8f324b50a2a64fd4994bb2b105a4cb0c80b64ec05cf5487d2daa906c650bc6f9
opentelemetry-instrumentation-lmdb (0.25.0) sha256=1e4d66d583ea242d4f72051062971f5af1ea353484d224abbd0aabdd1ce5f5cb
- opentelemetry-instrumentation-mongo (0.25.0) sha256=d04585669f928ea82e7c469f996061d39d8ff184278d57cf4fc77a6d607f9c7a
+ opentelemetry-instrumentation-mongo (0.25.1) sha256=b66a8544bb0c60ab032ecd224333d50138f2b280d2d394c508d2ff8ca3fb94b9
opentelemetry-instrumentation-mysql2 (0.33.0) sha256=b49b7957d5eef59e046e73be3ca370518965d61495745b4cb7ece3ef5470bcf9
opentelemetry-instrumentation-net_http (0.28.0) sha256=63b00c1c8fcfba15cd293ece8383d19bbc35e9b5cc04056b3e95799be11026f5
opentelemetry-instrumentation-pg (0.35.0) sha256=65a6e78bd45282b56021f1ee1b88b9fd318abf6812c32bd740465e6b9997aad4
@@ -2134,19 +2134,19 @@ CHECKSUMS
opentelemetry-instrumentation-sidekiq (0.28.1) sha256=abc85d62996a5362e7a9fd7af9f6c709d01ce04795514d12fee5126335ae97ae
opentelemetry-instrumentation-sinatra (0.29.0) sha256=08595fec08d198df581d96aceb4b27998b84431e44a679950af7d00ab6559bdb
opentelemetry-instrumentation-trilogy (0.67.0) sha256=40394d3071d92aa418ef5aedab8e74f7683c0566c285a5418f75ca0586fd025f
- opentelemetry-registry (0.4.0) sha256=903fa6bfaa29eac1c1d73a4fdd29b850977b5353b84b8cdff11222c00ad2968f
- opentelemetry-sdk (1.10.0) sha256=43719949be8df24dcaeb86ebbf75636cda87d51a01af2729499b92a48b80521a
- opentelemetry-semantic_conventions (1.36.0) sha256=c1b1607dbc7853aac7f9e23f6e8b76969c45b07f2b812a4aa4383c19a3b0f617
+ opentelemetry-registry (0.5.0) sha256=726ca58ada93a23efaa5f7bb81b8ab7a8a1e14602935c9c65dfa2e597a19fb4f
+ opentelemetry-sdk (1.11.0) sha256=427c6708f4732105ffa46c11afecb91807085c59e92538eaa6cf46b97b1850c6
+ opentelemetry-semantic_conventions (1.37.0) sha256=1e2dc5ad649e19ba2fb0fa7c6f9303e5cdd8d3952511415cb07efe28a0f8f4c3
optimist (3.2.1) sha256=8cf8a0fd69f3aa24ab48885d3a666717c27bc3d9edd6e976e18b9d771e72e34e
os (1.1.4) sha256=57816d6a334e7bd6aed048f4b0308226c5fb027433b67d90a9ab435f35108d3f
ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
overviews (1.0.0)
ox (2.14.23) sha256=4a9aedb4d6c78c5ebac1d7287dc7cc6808e14a8831d7adb727438f6a1b461b66
- pagy (43.4.1) sha256=a211fc64b2c396f84db08f8de7bf919e73732de9e9e170a33eec7960bbdd3822
+ pagy (43.5.1) sha256=ca5aaa6d65d21eee67a48fe8801d022d07ee72afbc5bea6a9e21b13a27b7c0b9
paper_trail (17.0.0) sha256=1c2842061d3874ca7015908e821e2aa14f9b982af2acb2a7974713bf79021c85
- parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
+ parallel (2.0.1) sha256=337782d3e39f4121e67563bf91dd8ece67f48923d90698614773a0ec9a5b2c7d
parallel_tests (4.10.1) sha256=df05458c691462b210f7a41fc2651d4e4e8a881e8190e6d1e122c92c07735d70
- parser (3.3.10.2) sha256=6f60c84aa4bdcedb6d1a2434b738fe8a8136807b6adc8f7f53b97da9bc4e9357
+ parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54
pdf-core (0.9.0) sha256=4f368b2f12b57ec979872d4bf4bd1a67e8648e0c81ab89801431d2fc89f4e0bb
pdf-inspector (1.3.0) sha256=fc107579d6f29b636e2da3d6743479b2624d9e390bf2d84beef8fd4ebe1a05bd
pdf-reader (2.15.1) sha256=18c6a986a84a3117fa49f4279fc2de51f5d2399b71833df5d2bccd595c7068ce
@@ -2170,7 +2170,7 @@ CHECKSUMS
prometheus-client-mmap (1.5.0-x86_64-darwin) sha256=96d360bbffc5603f8322a0b8c3353cf531c06410cf80dbdeda46efbd27a6a5a2
prometheus-client-mmap (1.5.0-x86_64-linux-gnu) sha256=2f5e7be72ea0b8bddd0e6a123e8f2468d7e2bdfa664a4d355fec4ed4f659d457
prometheus-client-mmap (1.5.0-x86_64-linux-musl) sha256=4673196ca44feb6db5eb63d5248feea32ffaae851f7861eee25218ccf7057ef4
- pry (0.16.0) sha256=d76c69065698ed1f85e717bd33d7942c38a50868f6b0673c636192b3d1b6054e
+ pry (0.16.0)
pry-byebug (3.12.0) sha256=594e094ae8a8390a7ad4c7b36ae36e13304ed02664c67417d108dc5f7213d1b7
pry-rails (0.3.11) sha256=a69e28e24a34d75d1f60bcf241192a54253f8f7ef8a62cba1e75750a9653593d
pry-rescue (1.6.0) sha256=985bfd506d9866b587fd86790cf8445266a41b7f92c627fc5b21ec7d92aba6db
@@ -2181,7 +2181,7 @@ CHECKSUMS
puma-plugin-statsd (2.7.0) sha256=04f243a7233f4d06ec0e26f1a3522bce18a5910ae711763fabff22681bdad08b
raabro (1.4.0) sha256=d4fa9ff5172391edb92b242eed8be802d1934b1464061ae5e70d80962c5da882
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
- rack (2.2.22) sha256=c5cf0b7f872559966d974abe3101a57d51caf12504ee76290b98720004f64542
+ rack (2.2.23) sha256=a8fe9d7e07064770b8ec123663fded8a59ef7e2b6db5cda7173d45a5718ab69c
rack-attack (6.8.0) sha256=f2499fdebf85bcc05573a22dff57d24305ac14ec2e4156cd3c28d47cafeeecf2
rack-cors (2.0.2) sha256=415d4e1599891760c5dc9ef0349c7fecdf94f7c6a03e75b2e7c2b54b82adda1b
rack-mini-profiler (4.0.1) sha256=485810c23211f908196c896ea10cad72ed68780ee2998bec1f1dfd7558263d78
@@ -2192,26 +2192,26 @@ CHECKSUMS
rack-timeout (0.7.0) sha256=757337e9793cca999bb73a61fe2a7d4280aa9eefbaf787ce3b98d860749c87d9
rack_session_access (0.2.0) sha256=03eb98f2027429ccbbeb18556006dfb6d928b0557ad3770783b8e2f368198d6b
rackup (1.0.1) sha256=ba86604a28989fe1043bff20d819b360944ca08156406812dca6742b24b3c249
- rails (8.1.2.1) sha256=93ebf1efc792c9bc47e9795259c920312d3920008dad3ae634b7a0457ffe0af8
+ rails (8.1.3) sha256=6d017ba5348c98fc909753a8169b21d44de14d2a0b92d140d1a966834c3c9cd3
rails-controller-testing (1.0.5) sha256=741448db59366073e86fc965ba403f881c636b79a2c39a48d0486f2607182e94
rails-dom-testing (2.3.0) sha256=8acc7953a7b911ca44588bf08737bc16719f431a1cc3091a292bca7317925c1d
rails-html-sanitizer (1.7.0) sha256=28b145cceaf9cc214a9874feaa183c3acba036c9592b19886e0e45efc62b1e89
rails-i18n (8.1.0) sha256=52d5fd6c0abef28d84223cc05647f6ae0fd552637a1ede92deee9545755b6cf3
- railties (8.1.2.1) sha256=f4d902869541af4e5b5552d726062fa59ec0fd9078f7ab87720dbd93f22c43ee
+ railties (8.1.3) sha256=913eb0e0cb520aac687ffd74916bd726d48fa21f47833c6292576ef6a286de22
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
- rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
+ rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
rake-compiler-dock (1.11.0) sha256=eab51f2cd533eb35cea6b624a75281f047123e70a64c58b607471bb49428f8c2
rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe
rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e
- rb_sys (0.9.124) sha256=513476557b12eaf73764b3da9f8746024558fe8699bda785fb548c9aa3877ae7
+ rb_sys (0.9.126) sha256=ba958e0b8b4b89eeae0b3d24b64c809eb2c37e0ab0773a49e9b1c2e22c95aef8
rbtrace (0.5.3) sha256=c432292f305d9ab12fd47d9722e0d5210d983758a951fe6107c36cc955cb923f
rbtree3 (0.7.1) sha256=ab60ead728a5491b70df4f4065e180b18dbab5319f817ce1dbf5dd906f26d8ba
rdoc (7.2.0) sha256=8650f76cd4009c3b54955eb5d7e3a075c60a57276766ebf36f9085e8c9f23192
- recaptcha (5.21.1) sha256=e003e9ceba9b993a9f0c6a828c192f2d46693cd2aa0b0beae94f936649507adb
+ recaptcha (5.21.2) sha256=8f7bb6cc9f04c523fff3f38126b7c5f1314c35fcb3691fc8e70d2b464533c12a
redcarpet (3.6.1) sha256=d444910e6aa55480c6bcdc0cdb057626e8a32c054c29e793fa642ba2f155f445
redis (5.4.1) sha256=b5e675b57ad22b15c9bcc765d5ac26f60b675408af916d31527af9bd5a81faae
redis-client (0.28.0) sha256=888892f9cd8787a41c0ece00bdf5f556dfff7770326ce40bb2bc11f1bfec824b
- regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4
+ regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
representable (3.2.0) sha256=cc29bf7eebc31653586849371a43ffe36c60b54b0a6365b5f7d95ec34d1ebace
request_store (1.7.0) sha256=e1b75d5346a315f452242a68c937ef8e48b215b9453a77a6c0acdca2934c88cb
@@ -2230,11 +2230,11 @@ CHECKSUMS
rspec-retry (0.6.2) sha256=6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
rspec-wait (1.0.2) sha256=865f921239325d3d26fc10ded4bdd485d8b58bcaaad1a28dd85ed15266b5a912
- rubocop (1.85.1) sha256=3dbcf9e961baa4c376eeeb2a03913dca5e3987033b04d38fa538aa1e7406cc77
+ rubocop (1.86.1) sha256=44415f3f01d01a21e01132248d2fd0867572475b566ca188a0a42133a08d4531
rubocop-ast (1.49.1) sha256=4412f3ee70f6fe4546cc489548e0f6fcf76cafcfa80fa03af67098ffed755035
rubocop-capybara (2.22.1) sha256=ced88caef23efea53f46e098ff352f8fc1068c649606ca75cb74650970f51c0c
rubocop-factory_bot (2.28.0) sha256=4b17fc02124444173317e131759d195b0d762844a71a29fe8139c1105d92f0cb
- rubocop-openproject (0.3.0) sha256=9554496e7ef0a2cf65dc2b32bee1bfa223b4f9ae058a5c603489d34e9001a828
+ rubocop-openproject (0.4.0) sha256=ce56d9e591f9be5a4d98125b10a73564b0557a5e408f97918f9630fb15ae66ae
rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834
rubocop-rails (2.34.3) sha256=10d37989024865ecda8199f311f3faca990143fbac967de943f88aca11eb9ad2
rubocop-rspec (3.9.0) sha256=8fa70a3619408237d789aeecfb9beef40576acc855173e60939d63332fdb55e2
@@ -2247,15 +2247,14 @@ CHECKSUMS
ruby-rc4 (0.1.5) sha256=00cc40a39d20b53f5459e7ea006a92cf584e9bc275e2a6f7aa1515510e896c03
ruby-saml (1.18.1) sha256=1b0e7a44aef150b4197955f5e015d593672e242cfdc5d06aa7554ec2350b9107
ruby-vips (2.3.0) sha256=e685ec02c13969912debbd98019e50492e12989282da5f37d05f5471442f5374
- ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef
rubytree (2.2.0) sha256=e312dc1ed814153583b57d9662e6caac1fd60830886a571b48bb06daef906eb6
rubyzip (2.4.1) sha256=8577c88edc1fde8935eb91064c5cb1aef9ad5494b940cf19c775ee833e075615
safety_net_attestation (0.5.0) sha256=c8cd01dd550dbe8553862918af6355a04672db11d218ec96104ce3955293f2aa
sanitize (7.0.0) sha256=269d1b9d7326e69307723af5643ec032ff86ad616e72a3b36d301ac75a273984
scimitar (2.15.0) sha256=700901afab9303b705a8f37644cd733ee3c3819b168d24a14a48dec060b16d63
securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
- selenium-devtools (0.145.0) sha256=629c4964ebeb140f0e08cd6e88e241b07a995416a0e45d8416ba25cf4a7f0513
- selenium-webdriver (4.41.0) sha256=cdc1173cd55cf186022cea83156cc2d0bec06d337e039b02ad25d94e41bedd22
+ selenium-devtools (0.147.0) sha256=8e9262c7c3bfafc7e16b773047912fb952e7bb59c2e6b592ea74a781700d6873
+ selenium-webdriver (4.43.0) sha256=a634377b964b701c6ac0a009ce3a08fa34ec1e1e7fe9a6d57e3088d14529a65c
semantic (1.6.1) sha256=3cdbb48f59198ebb782a3fdfb87b559e0822a311610db153bae22777a7d0c163
shoulda-context (2.0.0) sha256=7adf45342cd800f507d2a053658cb1cce2884b616b26004d39684b912ea32c34
shoulda-matchers (7.0.1) sha256=b4bfd8744c10e0a36c8ac1a687f921ee7e25ed529e50488d61b79a8688749c77
@@ -2268,7 +2267,7 @@ CHECKSUMS
spring-commands-rubocop (0.4.0) sha256=3e677a2c8a27ae8a986f04bfb69e66d5d55b017541e8be93bf0dc48a7f5690c1
sprockets (3.7.5) sha256=72c20f256548f8a37fe7db41d96be86c3262fddaf4ebe9d69ec8317394fed383
sprockets-rails (3.5.2) sha256=a9e88e6ce9f8c912d349aa5401509165ec42326baf9e942a85de4b76dbc4119e
- ssrf_filter (1.3.0) sha256=66882d7de7d09c019098d6d7372412950ae184ebbc7c51478002058307aba6f2
+ ssrf_filter (1.5.0) sha256=e03dcdb9d1730d7f6710532a606b3543df2a448a0293ce04a2d995523c5a97f6
stackprof (0.2.28) sha256=4ec2ace02f386012b40ca20ef80c030ad711831f59511da12e83b34efb0f9a04
statesman (13.1.0) sha256=3ecb78466dfd2682e433f335a7722aa0e5b8c6853d72d83e460151b8af17a84e
store_attribute (2.1.1) sha256=de53611c01d3fb4c91e0d7af4208861bd18d017c4cee682ed0473d0e4496f5b8
@@ -2280,11 +2279,11 @@ CHECKSUMS
sys-filesystem (1.5.5) sha256=6f995890a734b9f0aa55df5e09d99adeb9fd1c288f2c4097269a1f8c95e15033
table_print (1.5.7) sha256=436664281f93387b882335795e16cfeeb839ad0c785ff7f9110fc0f17c68b5cb
terminal-table (4.0.0) sha256=f504793203f8251b2ea7c7068333053f0beeea26093ec9962e62ea79f94301d2
- test-prof (1.5.2) sha256=185839fb7d3745b3770ec48e3e5718eff9e28c327a50a1e18a3a9ef1060f8576
+ test-prof (1.6.1) sha256=0332d9c39a7c118ed942b2db582f055d9f24964d150004ec6b964d2fa262499e
text-hyphen (1.5.0) sha256=c44a4533b8a554e7ff7c955e131bcccc78a0b4c56ce1d73f2c8c11f43b075a06
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
thread_safe (0.3.6) sha256=9ed7072821b51c57e8d6b7011a8e282e25aeea3a4065eab326e43f66f063b05a
- timecop (0.9.10) sha256=12ba45ce57cdcf6b1043cb6cdffa6381fd89ce10d369c28a7f6f04dc1b0cd8eb
+ timecop (0.9.11) sha256=41284dc6e5041f2184f781ace766f942108c842f8d8c1386a26e6343decc7542
timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb
tpm-key_attestation (0.14.1) sha256=7fd4e4653a7afd0a386632ddfb05d10ecfdd47678299c5e69165bc9ae111193f
trailblazer-option (0.1.2) sha256=20e4f12ea4e1f718c8007e7944ca21a329eee4eed9e0fa5dde6e8ad8ac4344a3
@@ -2304,7 +2303,7 @@ CHECKSUMS
validate_url (1.0.15) sha256=72fe164c0713d63a9970bd6700bea948babbfbdcec392f2342b6704042f57451
vcr (6.4.0) sha256=077ac92cc16efc5904eb90492a18153b5e6ca5398046d8a249a7c96a9ea24ae6
vernier (1.10.0) sha256=5b1dc57012e08ed23e14f4d2943540140d454aa8434c7c35e7eb97befd4969bf
- view_component (4.5.0) sha256=0d951360d830752da4d1daa5f6cb643f17c30f295fb779fd4de90a051537d9c1
+ view_component (4.6.0) sha256=aabbcc68ab4af8a0135bd3f488e1a4132180cb611aa2565f86cb6e9135f4ed7e
virtus (2.0.0) sha256=8841dae4eb7fcc097320ba5ea516bf1839e5d056c61ee27138aa4bddd6e3d1c2
warden (1.2.9) sha256=46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0
warden-basic_auth (0.2.1) sha256=bfc752e0109c0182c3e69e930284c5e1e81e7b4a354aeb2b5914ead1391f3c6e
@@ -2324,11 +2323,11 @@ CHECKSUMS
yabeda-puma-plugin (0.9.0) sha256=b78673ecc7ee30bc50691ddc41b7022c1c1801843900d5101418f4a14b550bc8
yabeda-rails (0.11.0) sha256=afa2581bd44c8f419cb3f2bbf9f6fb40f817c30476f7caf5d1c55c48d69a5b29
yaml (0.4.0) sha256=240e69d1e6ce3584d6085978719a0faa6218ae426e034d8f9b02fb54d3471942
- yard (0.9.38) sha256=721fb82afb10532aa49860655f6cc2eaa7130889df291b052e1e6b268283010f
+ yard (0.9.42) sha256=4e2be01f8623556093497731d44c801e600d7c9759ec7a35a2dd5dd83bbbba68
zeitwerk (2.7.5) sha256=d8da92128c09ea6ec62c949011b00ed4a20242b255293dd66bf41545398f73dd
RUBY VERSION
- ruby 4.0.1
+ ruby 4.0.2
BUNDLED WITH
- 4.0.3
+ 4.0.9
diff --git a/app/components/_index.sass b/app/components/_index.sass
index 3401f8f417e..ca04d7a7782 100644
--- a/app/components/_index.sass
+++ b/app/components/_index.sass
@@ -3,6 +3,7 @@
@import "op_primer/border_box_table_component"
@import "op_primer/full_page_prompt_component"
@import "op_primer/form_helpers"
+@import "op_primer/inline_macro_component"
@import "open_project/common/attribute_component"
@import "open_project/common/attribute_help_text_component"
@import "open_project/common/attribute_help_text_caption_component"
diff --git a/app/components/admin/departments/add_department_component.html.erb b/app/components/admin/departments/add_department_component.html.erb
new file mode 100644
index 00000000000..e8f954c223d
--- /dev/null
+++ b/app/components/admin/departments/add_department_component.html.erb
@@ -0,0 +1,75 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ component_wrapper do
+ primer_form_with(
+ url: add_department_admin_departments_path,
+ method: :post,
+ scope: :group
+ ) do |f|
+ cancel_path = if group
+ helpers.admin_department_path(group)
+ else
+ helpers.admin_departments_path
+ end
+
+ parent_id = group&.id
+
+ render_inline_form(f) do |form|
+ form.hidden(name: :parent_id, value: parent_id) if parent_id
+
+ form.group(layout: :horizontal) do |row|
+ row.text_field(
+ name: :lastname,
+ label: I18n.t("departments.add_department_form.name_label"),
+ visually_hide_label: true,
+ placeholder: I18n.t("departments.add_department_form.name_placeholder"),
+ required: true,
+ autofocus: true,
+ value: "",
+ autocomplete: "off"
+ )
+ row.button(
+ name: :cancel,
+ tag: :a,
+ label: I18n.t(:button_cancel),
+ scheme: :default,
+ href: cancel_path
+ )
+ row.submit(
+ name: :submit,
+ label: I18n.t(:button_add),
+ scheme: :primary
+ )
+ end
+ end
+ end
+ end
+%>
diff --git a/app/components/admin/departments/add_department_component.rb b/app/components/admin/departments/add_department_component.rb
new file mode 100644
index 00000000000..29401cea457
--- /dev/null
+++ b/app/components/admin/departments/add_department_component.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 Admin
+ module Departments
+ class AddDepartmentComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ attr_reader :group
+
+ def initialize(group:)
+ super()
+ @group = group
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/add_user_component.html.erb b/app/components/admin/departments/add_user_component.html.erb
new file mode 100644
index 00000000000..bbaffadb8d9
--- /dev/null
+++ b/app/components/admin/departments/add_user_component.html.erb
@@ -0,0 +1,77 @@
+<%#-- copyright
+OpenProject is an open source project management software.
+Copyright (C) the OpenProject GmbH
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License version 3.
+
+OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+Copyright (C) 2006-2013 Jean-Philippe Lang
+Copyright (C) 2010-2013 the ChiliProject Team
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+See COPYRIGHT and LICENSE files for more details.
+
+++#%>
+
+<%=
+ component_wrapper do
+ primer_form_with(
+ url: add_user_admin_department_path(group),
+ method: :post
+ ) do |f|
+ cancel_path = if group
+ helpers.admin_department_path(group)
+ else
+ helpers.admin_departments_path
+ end
+
+ autocompleter_filters = filters
+
+ render_inline_form(f) do |form|
+ form.group(layout: :horizontal) do |row|
+ row.autocompleter(
+ name: :user_id,
+ label: User.model_name.human,
+ visually_hide_label: true,
+ autocomplete_options: {
+ resource: "principals",
+ component: "opce-user-autocompleter",
+ url: ::API::V3::Utilities::PathHelper::ApiV3Path.principals,
+ searchKey: "any_name_attribute",
+ focusDirectly: true,
+ multiple: false,
+ filters: autocompleter_filters,
+ inputName: "user_id"
+ }
+ )
+ row.button(
+ name: :cancel,
+ tag: :a,
+ label: I18n.t(:button_cancel),
+ scheme: :default,
+ href: cancel_path
+ )
+ row.submit(
+ name: :submit,
+ label: I18n.t(:button_add),
+ scheme: :primary
+ )
+ end
+ end
+ end
+ end
+%>
diff --git a/app/components/admin/departments/add_user_component.rb b/app/components/admin/departments/add_user_component.rb
new file mode 100644
index 00000000000..61dddf5ae57
--- /dev/null
+++ b/app/components/admin/departments/add_user_component.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 Admin
+ module Departments
+ class AddUserComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ attr_reader :group
+
+ def initialize(group:)
+ super()
+ @group = group
+ end
+
+ def filters
+ filters = [
+ { name: "type", operator: "=", values: %w[User] },
+ { name: "status", operator: "=", values: [Principal.statuses[:active].to_s, Principal.statuses[:invited].to_s] }
+ ]
+
+ existing_user_ids = group.user_ids.map(&:to_s)
+ if existing_user_ids.any?
+ filters << { name: "id", operator: "!", values: existing_user_ids }
+ end
+
+ filters
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/blankslate_component.rb b/app/components/admin/departments/blankslate_component.rb
new file mode 100644
index 00000000000..525a091af0c
--- /dev/null
+++ b/app/components/admin/departments/blankslate_component.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+module Admin
+ module Departments
+ class BlankslateComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpPrimer::ComponentHelpers
+
+ def call
+ render(Primer::Beta::Blankslate.new(border: false)) do |component|
+ component.with_visual_icon(icon: :people, size: :medium)
+ component.with_heading(tag: :h2) { t("departments.blankslate.heading") }
+ component.with_description { t("departments.blankslate.description") }
+ component.with_primary_action(
+ href: new_department_admin_departments_path,
+ scheme: :primary,
+ data: { turbo_frame: Admin::Departments::DetailComponent.wrapper_key }
+ ) do |button|
+ button.with_leading_visual_icon(icon: :plus)
+ t("departments.blankslate.add_button")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/modules/backlogs/app/views/rb_master_backlogs/index.html.erb b/app/components/admin/departments/change_parent_dialog_component.html.erb
similarity index 54%
rename from modules/backlogs/app/views/rb_master_backlogs/index.html.erb
rename to app/components/admin/departments/change_parent_dialog_component.html.erb
index bf4222ec02e..a9c14c46dfb 100644
--- a/modules/backlogs/app/views/rb_master_backlogs/index.html.erb
+++ b/app/components/admin/departments/change_parent_dialog_component.html.erb
@@ -27,40 +27,40 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-<% html_title t(:label_backlogs) %>
-
-<% content_controller "backlogs" %>
-
-<% content_for :content_header do %>
- <%=
- render Primer::OpenProject::PageHeader.new do |header|
- header.with_title { t(:label_backlogs) }
- header.with_breadcrumbs(
- [{ href: project_overview_path(@project), text: @project.name },
- t(:label_backlogs)]
- )
- end
- %>
-
- <%=
- render(Primer::OpenProject::SubHeader.new) do |subheader|
- subheader.with_action_button(
- scheme: :primary,
- leading_icon: :plus,
- label: I18n.t(:label_version_new),
- tag: :a,
- href: new_project_version_path(@project)
- ) do
- Version.human_model_name
+<%=
+ render(
+ Primer::Alpha::Dialog.new(
+ id: DIALOG_ID,
+ title: I18n.t(:label_change_parent),
+ size: :medium_portrait
+ )
+ ) do |dialog|
+ dialog.with_body do
+ primer_form_with(**form_arguments) do |form|
+ render(
+ Primer::OpenProject::FilterableTreeView.new(
+ form_arguments: { builder: form, name: :new_parent_id },
+ include_sub_items_check_box_arguments: { hidden: true },
+ filter_mode_control_arguments: { hidden: true }
+ )
+ ) do |tree_view|
+ render_tree(tree_view)
+ end
end
end
- %>
-<% end %>
-<% content_for :content_body do %>
- <%= turbo_frame_tag :backlogs_container, refresh: :morph, src: backlogs_project_backlogs_path(@project), class: "op-backlogs-page" %>
-<% end %>
-
-<% content_for :content_body_right do %>
- <%= render(split_view_instance) if render_work_package_split_view? %>
-<% end %>
+ dialog.with_footer(show_divider: true) do
+ concat(render(Primer::Beta::Button.new(data: { close_dialog_id: DIALOG_ID })) { I18n.t(:button_cancel) })
+ concat(
+ render(
+ Primer::Beta::Button.new(
+ scheme: :primary,
+ form: FORM_ID,
+ type: :submit,
+ data: { turbo: true }
+ )
+ ) { I18n.t(:button_select) }
+ )
+ end
+ end
+%>
diff --git a/app/components/admin/departments/change_parent_dialog_component.rb b/app/components/admin/departments/change_parent_dialog_component.rb
new file mode 100644
index 00000000000..c9adbc875f5
--- /dev/null
+++ b/app/components/admin/departments/change_parent_dialog_component.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+module Admin
+ module Departments
+ class ChangeParentDialogComponent < ApplicationComponent
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ DIALOG_ID = "departments--change-parent-dialog"
+ FORM_ID = "departments--change-parent-form"
+
+ def initialize(department:, departments:)
+ super()
+ @department = department
+ @departments = departments
+ end
+
+ def form_arguments
+ {
+ id: FORM_ID,
+ url: change_parent_admin_department_path(@department),
+ method: :post
+ }
+ end
+
+ def render_tree(tree_view)
+ add_sub_tree(tree_view, nil)
+ end
+
+ private
+
+ def departments_by_parent_id
+ @departments_by_parent_id ||= @departments.group_by(&:parent_id)
+ end
+
+ def children_for(parent_id)
+ departments_by_parent_id[parent_id] || []
+ end
+
+ def add_sub_tree(tree_view, parent_id)
+ children_for(parent_id).each do |dept|
+ attrs = item_attributes(dept)
+ children = children_for(dept.id)
+
+ if children.any?
+ tree_view.with_sub_tree(**attrs) do |sub_tree|
+ add_sub_tree(sub_tree, dept.id)
+ end
+ else
+ tree_view.with_leaf(**attrs)
+ end
+ end
+ end
+
+ def item_attributes(dept)
+ {
+ label: dept.name,
+ value: dept.id,
+ select_variant: :single,
+ current: dept.id == @department.id,
+ disabled: disabled_ids.include?(dept.id),
+ expanded: dept.id == @department.parent_id
+ }
+ end
+
+ def disabled_ids
+ @disabled_ids ||= Set.new(
+ [@department.id, @department.parent_id].compact + descendant_ids(@department.id)
+ )
+ end
+
+ def descendant_ids(dept_id)
+ children_for(dept_id).flat_map { |child| [child.id] + descendant_ids(child.id) }
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/department_row_component.rb b/app/components/admin/departments/department_row_component.rb
new file mode 100644
index 00000000000..40559961be5
--- /dev/null
+++ b/app/components/admin/departments/department_row_component.rb
@@ -0,0 +1,125 @@
+# 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 Admin
+ module Departments
+ class DepartmentRowComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpPrimer::ComponentHelpers
+
+ def initialize(department:)
+ super()
+ @department = department
+ end
+
+ def call
+ flex_layout(align_items: :center, justify_content: :space_between) do |row|
+ row.with_column do
+ render(Primer::Beta::Link.new(href: admin_department_path(@department))) { @department.name }
+ end
+
+ row.with_column do
+ render(Primer::Alpha::ActionMenu.new) do |menu|
+ menu.with_show_button(
+ icon: "kebab-horizontal",
+ scheme: :invisible,
+ "aria-label": I18n.t(:label_actions)
+ )
+ menu_items(menu)
+ end
+ end
+ end
+ end
+
+ private
+
+ def menu_items(menu)
+ with_item_group(menu) { edit_item(menu) }
+ with_item_group(menu) do
+ add_sub_department_item(menu)
+ add_user_item(menu)
+ end
+ with_item_group(menu) { change_parent_item(menu) }
+ with_item_group(menu) { delete_item(menu) }
+ end
+
+ def edit_item(menu)
+ menu.with_item(
+ label: I18n.t(:button_edit),
+ tag: :a,
+ href: edit_admin_department_path(@department)
+ ) { it.with_leading_visual_icon(icon: :pencil) }
+ end
+
+ def add_sub_department_item(menu)
+ menu.with_item(
+ label: I18n.t("departments.context_menu.add_sub_department"),
+ tag: :a,
+ href: new_department_admin_departments_path(parent_id: @department.id),
+ content_arguments: { data: { turbo_frame: Admin::Departments::HierarchyLayoutComponent.wrapper_key } }
+ ) { it.with_leading_visual_icon(icon: "op-arrow-in") }
+ end
+
+ def add_user_item(menu)
+ menu.with_item(
+ label: I18n.t("departments.context_menu.add_user"),
+ tag: :a,
+ href: new_user_admin_department_path(@department),
+ content_arguments: { data: { turbo_frame: Admin::Departments::HierarchyLayoutComponent.wrapper_key } }
+ ) { it.with_leading_visual_icon(icon: "person-add") }
+ end
+
+ def change_parent_item(menu)
+ menu.with_item(
+ label: I18n.t(:label_change_parent),
+ tag: :a,
+ href: change_parent_admin_department_path(@department),
+ content_arguments: { data: { controller: "async-dialog" } }
+ ) { it.with_leading_visual_icon(icon: "arrow-switch") }
+ end
+
+ def delete_item(menu)
+ menu.with_item(
+ label: I18n.t(:button_delete),
+ scheme: :danger,
+ tag: :a,
+ href: admin_department_path(@department),
+ content_arguments: {
+ data: {
+ turbo_confirm: I18n.t(:text_are_you_sure),
+ turbo_method: :delete,
+ turbo_frame: "_top"
+ }
+ }
+ ) { it.with_leading_visual_icon(icon: :trash) }
+ end
+ end
+ end
+end
diff --git a/modules/backlogs/app/controllers/rb_wikis_controller.rb b/app/components/admin/departments/detail_blankslate_component.rb
similarity index 71%
rename from modules/backlogs/app/controllers/rb_wikis_controller.rb
rename to app/components/admin/departments/detail_blankslate_component.rb
index 7684363cffa..d0512272a44 100644
--- a/modules/backlogs/app/controllers/rb_wikis_controller.rb
+++ b/app/components/admin/departments/detail_blankslate_component.rb
@@ -28,16 +28,18 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-class RbWikisController < RbApplicationController
- # NOTE: The methods #show and #edit are public (see init.rb). We will let
- # OpenProject's WikiController#index take care of authorization
- #
- # NOTE: The methods #show and #edit create a template page when called.
- def show
- redirect_to controller: "/wiki", action: "index", project_id: @project, id: @sprint.wiki_page
- end
+module Admin
+ module Departments
+ class DetailBlankslateComponent < ApplicationComponent
+ include OpPrimer::ComponentHelpers
- def edit
- redirect_to controller: "/wiki", action: "edit", project_id: @project, id: @sprint.wiki_page
+ def call
+ render(Primer::Beta::Blankslate.new(border: false)) do |component|
+ component.with_visual_icon(icon: :people, size: :medium)
+ component.with_heading(tag: :h2) { t("departments.detail_blankslate.heading") }
+ component.with_description { t("departments.detail_blankslate.description") }
+ end
+ end
+ end
end
end
diff --git a/app/components/admin/departments/detail_component.html.erb b/app/components/admin/departments/detail_component.html.erb
new file mode 100644
index 00000000000..ed24540b0a1
--- /dev/null
+++ b/app/components/admin/departments/detail_component.html.erb
@@ -0,0 +1,94 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ component_wrapper(tag: "turbo-frame", target: "_top") do
+ render(Primer::Beta::BorderBox.new) do |box|
+ box.with_header do
+ flex_layout(align_items: :center, justify_content: :space_between) do |header|
+ header.with_column do
+ render(Primer::Beta::Breadcrumbs.new) do |loaf|
+ breadcrumb_items.each do |item|
+ loaf.with_item(href: item[:href] || "#", target: nil) { item[:label] }
+ end
+ end
+ end
+
+ if group
+ header.with_column do
+ render(
+ Primer::Beta::IconButton.new(
+ tag: :a,
+ href: edit_admin_department_path(group),
+ icon: :pencil,
+ scheme: :invisible,
+ "aria-label": I18n.t(:button_edit)
+ )
+ )
+ end
+ end
+ end
+ end
+
+ if show_global_empty_state? && !add_subgroup?
+ box.with_row do
+ render(Admin::Departments::BlankslateComponent.new)
+ end
+ elsif show_department_empty_state? && !add_user? && !add_subgroup?
+ box.with_row do
+ render(Admin::Departments::DetailBlankslateComponent.new)
+ end
+ else
+ child_groups.each do |child|
+ box.with_row do
+ render(Admin::Departments::DepartmentRowComponent.new(department: child))
+ end
+ end
+
+ if add_subgroup?
+ box.with_row do
+ render(Admin::Departments::AddDepartmentComponent.new(group:))
+ end
+ end
+
+ users.each do |user|
+ box.with_row do
+ render(Admin::Departments::UserRowComponent.new(user:, group:))
+ end
+ end
+
+ if add_user?
+ box.with_row do
+ render(Admin::Departments::AddUserComponent.new(group:))
+ end
+ end
+ end
+ end
+ end
+%>
diff --git a/app/components/admin/departments/detail_component.rb b/app/components/admin/departments/detail_component.rb
new file mode 100644
index 00000000000..9af578d7898
--- /dev/null
+++ b/app/components/admin/departments/detail_component.rb
@@ -0,0 +1,92 @@
+# 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 Admin
+ module Departments
+ class DetailComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ attr_reader :group, :ancestors, :child_groups
+
+ def initialize(group:, ancestors: [], child_groups: [], add_user: false, add_subgroup: false)
+ super(nil)
+ @group = group
+ @ancestors = ancestors
+ @child_groups = child_groups
+ @add_user = add_user
+ @add_subgroup = add_subgroup
+ end
+
+ def add_user?
+ @add_user
+ end
+
+ def add_subgroup?
+ @add_subgroup
+ end
+
+ def users
+ @users ||= group&.users || []
+ end
+
+ def breadcrumb_items
+ items = []
+
+ if group
+ items << { label: organization_name, href: admin_departments_path }
+ ancestors.each do |ancestor|
+ items << { label: ancestor.name, href: admin_department_path(ancestor) }
+ end
+ items << { label: group.name }
+ else
+ items << { label: organization_name }
+ end
+
+ items
+ end
+
+ def show_global_empty_state?
+ group.blank? && child_groups.empty?
+ end
+
+ def show_department_empty_state?
+ group.present? && child_groups.empty? && users.empty?
+ end
+
+ private
+
+ def organization_name
+ Setting.organization_name.presence || I18n.t("setting_organization_name")
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/edit_page_header_component.html.erb b/app/components/admin/departments/edit_page_header_component.html.erb
new file mode 100644
index 00000000000..b4a19bff6cf
--- /dev/null
+++ b/app/components/admin/departments/edit_page_header_component.html.erb
@@ -0,0 +1,69 @@
+<%#-- 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::OpenProject::PageHeader.new) do |header|
+ header.with_title { @group.name }
+ header.with_breadcrumbs(breadcrumb_items)
+
+ header.with_action_button(
+ tag: :a,
+ mobile_icon: :person,
+ mobile_label: t(:label_profile),
+ size: :medium,
+ href: show_group_path(@group),
+ aria: { label: I18n.t(:label_profile) },
+ title: I18n.t(:label_profile)
+ ) do |button|
+ button.with_leading_visual_icon(icon: :person)
+ t(:label_profile)
+ end
+
+ if @current_user.admin?
+ header.with_action_button(
+ tag: :a,
+ scheme: :danger,
+ mobile_icon: :trash,
+ mobile_label: t(:button_delete),
+ size: :medium,
+ href: group_path(@group),
+ aria: { label: I18n.t(:button_delete) },
+ data: {
+ turbo_confirm: t(:text_are_you_sure),
+ turbo_method: :delete
+ },
+ title: I18n.t(:button_delete)
+ ) do |button|
+ button.with_leading_visual_icon(icon: :trash)
+ t(:button_delete)
+ end
+ end
+
+ helpers.render_tab_header_nav(header, @tabs)
+ end
+%>
diff --git a/modules/backlogs/app/helpers/burndown_charts_helper.rb b/app/components/admin/departments/edit_page_header_component.rb
similarity index 66%
rename from modules/backlogs/app/helpers/burndown_charts_helper.rb
rename to app/components/admin/departments/edit_page_header_component.rb
index 1c087f11125..b50d9333bd1 100644
--- a/modules/backlogs/app/helpers/burndown_charts_helper.rb
+++ b/app/components/admin/departments/edit_page_header_component.rb
@@ -28,24 +28,26 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-module BurndownChartsHelper
- def xaxis_labels(burndown)
- # 14 entries (plus the axis label) have come along as the best value for a good optical result.
- # Thus it is enough space between the entries.
- entries_displayed = (burndown.days.length / 14.0).ceil
- burndown.days.enum_for(:each_with_index).map do |d, i|
- if (i % entries_displayed) == 0
- ["#{escape_javascript(::I18n.t('date.abbr_day_names')[d.wday % 7])} #{d.strftime('%d/%m')}"]
+module Admin
+ module Departments
+ class EditPageHeaderComponent < ApplicationComponent
+ include OpPrimer::ComponentHelpers
+ include ApplicationHelper
+ include TabsHelper
+
+ def initialize(group:, current_user:, tabs: nil)
+ super
+ @group = group
+ @tabs = tabs
+ @current_user = current_user
+ end
+
+ def breadcrumb_items
+ [{ href: admin_index_path, text: t("label_administration") },
+ { href: admin_settings_users_path, text: t(:label_user_and_permission) },
+ { href: admin_departments_path, text: t(:label_departments) },
+ @group.name]
end
end
end
-
- def dataseries(burndown)
- burndown.series.map do |s|
- {
- label: I18n.t("burndown.#{s.first}"),
- data: s.last.enum_for(:each)
- }
- end
- end
end
diff --git a/app/components/admin/departments/hierarchy_layout_component.html.erb b/app/components/admin/departments/hierarchy_layout_component.html.erb
new file mode 100644
index 00000000000..f58c8694484
--- /dev/null
+++ b/app/components/admin/departments/hierarchy_layout_component.html.erb
@@ -0,0 +1,87 @@
+<%#-- 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.
+
+++#%>
+
+<%# helpers.content_controller "admin--departments-page" %>
+
+<%=
+ component_wrapper(tag: "turbo-frame", class: "admin-groups-tree-page--wrapper", refresh: :morph, data: { turbo_action: :advance }) do
+ render(Primer::Alpha::Layout.new(stacking_breakpoint: :md, overflow: :hidden, h: :full, classes: "admin-groups-tree-page")) do |content|
+ content.with_main(overflow: :auto) do
+ flex_layout do |main|
+ main.with_row do
+ render(Primer::OpenProject::SubHeader.new) do |subheader|
+ subheader.with_action_menu(leading_icon: :plus, trailing_icon: :"triangle-down", label: I18n.t(:button_add), button_arguments: { scheme: :primary, "aria-label": I18n.t(:button_add) }) do |menu|
+ if active_group
+ menu.with_item(
+ label: I18n.t("departments.add_user"),
+ tag: :a,
+ href: new_user_admin_department_path(active_group),
+ content_arguments: { data: { turbo_frame: Admin::Departments::DetailComponent.wrapper_key } }
+ )
+ end
+ menu.with_item(
+ label: I18n.t("departments.add_department"),
+ tag: :a,
+ href: new_department_admin_departments_path(parent_id: active_group&.id),
+ content_arguments: { data: { turbo_frame: Admin::Departments::DetailComponent.wrapper_key } }
+ )
+ end
+ end
+ end
+
+ main.with_row do
+ render(
+ Admin::Departments::DetailComponent.new(
+ group: active_group,
+ ancestors: ancestors_for(active_group),
+ child_groups: children_for(active_group&.id),
+ add_user: @add_user,
+ add_subgroup: @add_subgroup
+ )
+ )
+ end
+ end
+ end
+
+ content.with_sidebar(row_placement: :start, col_placement: :start, border: true, border_bottom: 0, p: 3, overflow: :auto, classes: "admin-groups-tree-page--sidebar") do
+ flex_layout do |sidebar|
+ sidebar.with_row(mb: 3) do
+ render(Admin::Departments::OrganizationNameComponent.new)
+ end
+
+ sidebar.with_row do
+ render(Primer::Alpha::TreeView.new(node_variant: :anchor)) do |tree_view|
+ render_group_tree(tree_view)
+ end
+ end
+ end
+ end
+ end
+ end
+%>
diff --git a/app/components/admin/departments/hierarchy_layout_component.rb b/app/components/admin/departments/hierarchy_layout_component.rb
new file mode 100644
index 00000000000..fa9480f9978
--- /dev/null
+++ b/app/components/admin/departments/hierarchy_layout_component.rb
@@ -0,0 +1,115 @@
+# 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 Admin
+ module Departments
+ class HierarchyLayoutComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ attr_reader :groups, :active_group
+
+ def initialize(groups:, active_group: nil, add_user: false, add_subgroup: false)
+ super()
+ @groups = groups
+ @active_group = active_group
+ @add_user = add_user
+ @add_subgroup = add_subgroup
+ end
+
+ def render_group_tree(tree, parent_id: nil)
+ children_for(parent_id).each do |group|
+ node_attrs = {
+ label: group.name,
+ href: admin_department_path(group),
+ current: group == active_group
+ }
+
+ if children?(group)
+ tree.with_sub_tree(**node_attrs, expanded: expanded?(group)) do |sub_tree|
+ render_group_tree(sub_tree, parent_id: group.id)
+ end
+ else
+ tree.with_leaf(**node_attrs)
+ end
+ end
+ end
+
+ private
+
+ def children_by_parent_id
+ @children_by_parent_id ||= groups.group_by(&:parent_id)
+ end
+
+ def children_for(parent_id)
+ children_by_parent_id[parent_id] || []
+ end
+
+ def children?(group)
+ children_by_parent_id.key?(group.id)
+ end
+
+ def expanded?(group)
+ return false unless active_group
+
+ active_group == group || active_group_ancestor_ids.include?(group.id)
+ end
+
+ def active_group_ancestor_ids
+ @active_group_ancestor_ids ||= compute_ancestor_ids(active_group)
+ end
+
+ def groups_by_id
+ @groups_by_id ||= groups.index_by(&:id)
+ end
+
+ def ancestors_for(group)
+ return [] unless group
+
+ ancestor_ids = active_group_ancestor_ids
+ ancestor_ids.reverse.filter_map { |id| groups_by_id[id] }
+ end
+
+ def compute_ancestor_ids(group)
+ return [] unless group
+
+ ids = []
+ current = group
+ while current.parent_id
+ ids << current.parent_id
+ current = groups_by_id[current.parent_id]
+ break unless current
+ end
+ ids
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/move_user_dialog_component.html.erb b/app/components/admin/departments/move_user_dialog_component.html.erb
new file mode 100644
index 00000000000..88cbef2812a
--- /dev/null
+++ b/app/components/admin/departments/move_user_dialog_component.html.erb
@@ -0,0 +1,59 @@
+<%#-- 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::OpenProject::DangerDialog.new(
+ id: DIALOG_ID,
+ title: t("departments.move_user_dialog.title"),
+ confirm_button_text: t("departments.move_user_dialog.confirm"),
+ size: :medium_portrait,
+ form_arguments: {
+ action: add_user_admin_department_path(to_department),
+ method: :post
+ }
+ )
+ ) do |dialog|
+ dialog.with_confirmation_message do |message|
+ message.with_heading(tag: :h2) { t("departments.move_user_dialog.heading") }
+ message.with_description do
+ t(
+ "departments.move_user_dialog.description",
+ user: moved_user.name,
+ from_department: from_department.name
+ )
+ end
+ end
+
+ dialog.with_additional_details do
+ concat(hidden_field_tag(:user_id, moved_user.id))
+ concat(hidden_field_tag(:remove_from_previous_department, "true"))
+ end
+ end
+%>
diff --git a/app/components/admin/departments/move_user_dialog_component.rb b/app/components/admin/departments/move_user_dialog_component.rb
new file mode 100644
index 00000000000..0aa4bcbb041
--- /dev/null
+++ b/app/components/admin/departments/move_user_dialog_component.rb
@@ -0,0 +1,49 @@
+# 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 Admin
+ module Departments
+ class MoveUserDialogComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+
+ DIALOG_ID = "move-user-department-dialog"
+
+ attr_reader :moved_user, :from_department, :to_department
+
+ def initialize(user:, from_department:, to_department:)
+ super()
+ @moved_user = user
+ @from_department = from_department
+ @to_department = to_department
+ end
+ end
+ end
+end
diff --git a/app/components/admin/departments/organization_name_component.html.erb b/app/components/admin/departments/organization_name_component.html.erb
new file mode 100644
index 00000000000..c677b49a6b1
--- /dev/null
+++ b/app/components/admin/departments/organization_name_component.html.erb
@@ -0,0 +1,52 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ component_wrapper do
+ flex_layout(align_items: :center, justify_content: :space_between) do |container|
+ container.with_column do
+ render(Primer::Beta::Heading.new(tag: :h4)) { organization_name }
+ end
+
+ container.with_column do
+ render(
+ Primer::Beta::IconButton.new(
+ tag: :a,
+ href: edit_organization_name_admin_departments_path,
+ icon: :pencil,
+ scheme: :invisible,
+ "aria-label": I18n.t(:button_edit),
+ data: { turbo_stream: true },
+ test_selector: "edit-organization-name-button"
+ )
+ )
+ end
+ end
+ end
+%>
diff --git a/modules/backlogs/app/controllers/rb_burndown_charts_controller.rb b/app/components/admin/departments/organization_name_component.rb
similarity index 77%
rename from modules/backlogs/app/controllers/rb_burndown_charts_controller.rb
rename to app/components/admin/departments/organization_name_component.rb
index d5001d452a7..0ab12024364 100644
--- a/modules/backlogs/app/controllers/rb_burndown_charts_controller.rb
+++ b/app/components/admin/departments/organization_name_component.rb
@@ -28,18 +28,20 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-class RbBurndownChartsController < RbApplicationController
- helper :burndown_charts
+module Admin
+ module Departments
+ class OrganizationNameComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
- def show
- @burndown = if OpenProject::FeatureDecisions.scrum_projects_active?
- Burndown.new(@sprint, @project)
- else
- @sprint.burndown(@project)
- end
+ def initialize
+ super(nil)
+ end
- respond_to do |format|
- format.html { render layout: true }
+ def organization_name
+ Setting.organization_name.presence || I18n.t("setting_organization_name")
+ end
end
end
end
diff --git a/app/components/admin/departments/organization_name_form_component.html.erb b/app/components/admin/departments/organization_name_form_component.html.erb
new file mode 100644
index 00000000000..91d0fcf08fb
--- /dev/null
+++ b/app/components/admin/departments/organization_name_form_component.html.erb
@@ -0,0 +1,68 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ component_wrapper do
+ primer_form_with(
+ url: update_organization_name_admin_departments_path,
+ method: :patch,
+ data: { turbo_stream: true }
+ ) do |f|
+ render_inline_form(f) do |form|
+ form.group(layout: :horizontal) do |input_group|
+ input_group.text_field(
+ name: :organization_name,
+ label: I18n.t("setting_organization_name"),
+ value: Setting.organization_name,
+ visually_hide_label: true,
+ required: true,
+ autofocus: true,
+ input_width: :medium
+ )
+ end
+
+ form.group(layout: :horizontal) do |button_group|
+ button_group.button(
+ name: :cancel,
+ tag: :a,
+ label: I18n.t(:button_cancel),
+ scheme: :default,
+ href: helpers.cancel_edit_organization_name_admin_departments_path,
+ data: { turbo_stream: true, turbo_method: :patch }
+ )
+ button_group.submit(
+ name: :submit,
+ label: I18n.t(:button_save),
+ scheme: :primary
+ )
+ end
+ end
+ end
+ end
+%>
diff --git a/app/components/admin/departments/organization_name_form_component.rb b/app/components/admin/departments/organization_name_form_component.rb
new file mode 100644
index 00000000000..84183b1a386
--- /dev/null
+++ b/app/components/admin/departments/organization_name_form_component.rb
@@ -0,0 +1,45 @@
+# 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 Admin
+ module Departments
+ class OrganizationNameFormComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpTurbo::Streamable
+ include OpPrimer::ComponentHelpers
+
+ def initialize
+ super(nil)
+ end
+
+ delegate :wrapper_key, to: OrganizationNameComponent
+ end
+ end
+end
diff --git a/modules/backlogs/app/views/shared/not_configured.html.erb b/app/components/admin/departments/page_header_component.html.erb
similarity index 58%
rename from modules/backlogs/app/views/shared/not_configured.html.erb
rename to app/components/admin/departments/page_header_component.html.erb
index 03689ecfd3b..0b7596dc7c7 100644
--- a/modules/backlogs/app/views/shared/not_configured.html.erb
+++ b/app/components/admin/departments/page_header_component.html.erb
@@ -1,4 +1,4 @@
-<%# -- copyright
+<%#-- copyright
OpenProject is an open source project management software.
Copyright (C) the OpenProject GmbH
@@ -25,31 +25,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
-++# %>
+++#%>
-<% html_title t(:label_backlogs) %>
+<% helpers.html_title t(:label_administration), t(:label_departments) %>
-<% content_for :content_header do %>
- <%=
- render Primer::OpenProject::PageHeader.new do |header|
- header.with_title { t(:label_backlogs) }
- header.with_breadcrumbs(
- [{ href: project_overview_path(@project), text: @project.name },
- t(:label_backlogs)]
- )
- end
- %>
-<% end %>
-
-<% content_for :content_body do %>
- <%=
- render(Primer::Beta::Blankslate.new(border: true, spacious: true)) do |blankslate|
- blankslate.with_visual_icon(icon: :"op-backlogs")
- blankslate.with_heading(tag: :h2).with_content(t(:backlogs_not_configured_title))
- blankslate.with_description_content(t(:backlogs_not_configured_description))
- blankslate.with_secondary_action(href: admin_backlogs_settings_path, scheme: :default) do
- t(:backlogs_not_configured_action_text)
+<%= render(Primer::OpenProject::PageHeader.new) do |header|
+ header.with_title { t(:label_departments) }
+ header.with_description do
+ link_translate(:label_departments_description_html, links: { ldap_docs_article: "#" })
end
- end
- %>
-<% end %>
+ header.with_breadcrumbs(
+ [
+ { href: admin_index_path, text: t("label_administration") },
+ { href: admin_settings_users_path, text: t(:label_user_and_permission) },
+ t("label_departments")
+ ]
+ )
+ end %>
diff --git a/modules/backlogs/spec/views/shared/not_configured_spec.rb b/app/components/admin/departments/page_header_component.rb
similarity index 88%
rename from modules/backlogs/spec/views/shared/not_configured_spec.rb
rename to app/components/admin/departments/page_header_component.rb
index 57d240e138f..be4e00156f6 100644
--- a/modules/backlogs/spec/views/shared/not_configured_spec.rb
+++ b/app/components/admin/departments/page_header_component.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
@@ -26,12 +28,10 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-require "spec_helper"
-
-RSpec.describe "shared/not_configured" do
- before { assign(:project, create(:project)) }
-
- it "renders without errors" do
- render
+module Admin
+ module Departments
+ class PageHeaderComponent < ApplicationComponent
+ include ApplicationHelper
+ end
end
end
diff --git a/app/components/admin/departments/user_row_component.rb b/app/components/admin/departments/user_row_component.rb
new file mode 100644
index 00000000000..c0b9a3c6f2b
--- /dev/null
+++ b/app/components/admin/departments/user_row_component.rb
@@ -0,0 +1,75 @@
+# 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 Admin
+ module Departments
+ class UserRowComponent < ApplicationComponent
+ include ApplicationHelper
+ include OpPrimer::ComponentHelpers
+
+ def initialize(user:, group:)
+ super()
+ @user = user
+ @group = group
+ end
+
+ def call
+ flex_layout(align_items: :center, justify_content: :space_between) do |row|
+ row.with_column do
+ render(Users::AvatarComponent.new(user: @user, size: "mini"))
+ end
+
+ row.with_column do
+ render(Primer::Alpha::ActionMenu.new) do |menu|
+ menu.with_show_button(
+ icon: "kebab-horizontal",
+ scheme: :invisible,
+ "aria-label": I18n.t(:label_actions)
+ )
+ menu.with_item(
+ label: I18n.t(:button_remove),
+ scheme: :danger,
+ tag: :a,
+ href: remove_user_admin_department_path(@group, @user.id),
+ content_arguments: {
+ data: {
+ turbo_confirm: I18n.t(:text_are_you_sure),
+ turbo_method: :delete,
+ turbo_frame: "_top"
+ }
+ }
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/app/components/admin/import/jira/import_runs/wizard_step_review_component.rb b/app/components/admin/import/jira/import_runs/wizard_step_review_component.rb
index 2f337b3ccd5..566318ce4e8 100644
--- a/app/components/admin/import/jira/import_runs/wizard_step_review_component.rb
+++ b/app/components/admin/import/jira/import_runs/wizard_step_review_component.rb
@@ -50,7 +50,11 @@ module Admin::Import::Jira::ImportRuns
return nil if imported_projects.none?
ids = imported_projects.pluck(:op_entity_id).map(&:to_s)
- helpers.projects_path(filters: [{ id: { operator: "=", values: ids } }].to_json)
+ if ids.length == 1
+ helpers.project_path(id: ids[0])
+ else
+ helpers.projects_path(filters: [{ id: { operator: "=", values: ids } }].to_json)
+ end
end
def imported_work_packages
@@ -61,8 +65,13 @@ module Admin::Import::Jira::ImportRuns
def imported_work_packages_url
return nil if imported_work_packages.none?
- project_ids = imported_projects.pluck(:op_entity_id).map(&:to_s)
- helpers.work_packages_path(query_props: { f: [{ n: "project", o: "=", v: project_ids }] }.to_json)
+ wp_ids = imported_work_packages.pluck(:op_entity_id).map(&:to_s)
+ if wp_ids.length == 1
+ helpers.work_package_path(id: wp_ids[0])
+ else
+ project_ids = imported_projects.pluck(:op_entity_id).map(&:to_s)
+ helpers.work_packages_path(query_props: { f: [{ n: "project", o: "=", v: project_ids }] }.to_json)
+ end
end
def imported_users
diff --git a/app/components/enterprise_edition/plan_for_feature.rb b/app/components/enterprise_edition/plan_for_feature.rb
index 747708b6953..6d458270d3b 100644
--- a/app/components/enterprise_edition/plan_for_feature.rb
+++ b/app/components/enterprise_edition/plan_for_feature.rb
@@ -81,6 +81,16 @@ module EnterpriseEdition
end
def plan_text
+ if trial_feature?
+ safe_join [helpers.t("ee.upsell.trial_text"), upsell_plan_text], " "
+ else
+ upsell_plan_text
+ end
+ end
+
+ private
+
+ def upsell_plan_text
plan_name = render(Primer::Beta::Text.new(font_weight: :bold, classes: "upsell-colored-text")) do
I18n.t("ee.upsell.plan_name", plan: plan.capitalize)
end
diff --git a/app/components/groups/show_page_header_component.html.erb b/app/components/groups/show_page_header_component.html.erb
index da21c0482af..39f5d9b136c 100644
--- a/app/components/groups/show_page_header_component.html.erb
+++ b/app/components/groups/show_page_header_component.html.erb
@@ -35,15 +35,15 @@ See COPYRIGHT and LICENSE files for more details.
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
- mobile_label: t(:button_edit),
+ mobile_label: edit_label,
size: :medium,
- href: edit_group_path(@group),
- aria: { label: I18n.t(:button_edit) },
+ href: edit_path,
+ aria: { label: edit_label },
data: { "test-selector": "groups--edit-group-button" },
- title: I18n.t(:button_edit)
+ title: edit_label
) do |button|
button.with_leading_visual_icon(icon: :pencil)
- t(:button_edit)
+ edit_label
end
header.with_action_button(
diff --git a/app/components/groups/show_page_header_component.rb b/app/components/groups/show_page_header_component.rb
index 14a34d03869..df4090f3986 100644
--- a/app/components/groups/show_page_header_component.rb
+++ b/app/components/groups/show_page_header_component.rb
@@ -40,8 +40,50 @@ module Groups
end
def breadcrumb_items
- [{ href: groups_path, text: t(:label_group_plural) },
- @group.name]
+ if @current_user.admin?
+ admin_breadcrumb_items
+ else
+ non_admin_breadcrumb_items
+ end
+ end
+
+ private
+
+ def admin_breadcrumb_items
+ items = [{ href: admin_index_path, text: t("label_administration") },
+ { href: admin_settings_users_path, text: t(:label_user_and_permission) }]
+
+ items << if @group.organizational_unit?
+ { href: admin_departments_path, text: t(:label_departments) }
+ else
+ { href: groups_path, text: t(:label_group_plural) }
+ end
+
+ items << @group.name
+ end
+
+ def non_admin_breadcrumb_items
+ if @group.organizational_unit?
+ [t(:label_departments), @group.name]
+ else
+ [t(:label_group_plural), @group.name]
+ end
+ end
+
+ def edit_path
+ if @group.organizational_unit?
+ edit_admin_department_path(@group)
+ else
+ edit_group_path(@group)
+ end
+ end
+
+ def edit_label
+ if @group.organizational_unit?
+ t("departments.edit")
+ else
+ t(:button_edit)
+ end
end
end
end
diff --git a/app/components/homescreen/announcement_component.html.erb b/app/components/homescreen/announcement_component.html.erb
index 43b1086e845..72388f4d46d 100644
--- a/app/components/homescreen/announcement_component.html.erb
+++ b/app/components/homescreen/announcement_component.html.erb
@@ -27,4 +27,4 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-<%= render(Primer::Alpha::Banner.new(scheme: :default)) { format_text announcement.text } %>
+<%= render(Primer::Alpha::Banner.new(scheme: :default, mb: 3)) { format_text announcement.text } %>
diff --git a/app/components/homescreen/blocks/users.rb b/app/components/homescreen/blocks/meetings.rb
similarity index 81%
rename from app/components/homescreen/blocks/users.rb
rename to app/components/homescreen/blocks/meetings.rb
index 55ebe7d798b..1abfa96d312 100644
--- a/app/components/homescreen/blocks/users.rb
+++ b/app/components/homescreen/blocks/meetings.rb
@@ -30,19 +30,9 @@
module Homescreen
module Blocks
- class Users < Grids::WidgetComponent
- include IconsHelper
- include OpenProject::ObjectLinking
- include Redmine::I18n
-
- def initialize(*)
- super
-
- @newest_users = User.active.newest.take(3)
- end
-
- def title
- I18n.t(:label_user_plural)
+ class Meetings < Grids::WidgetComponent
+ def call
+ render(::Meetings::Widgets::Meetings.new(limit: 3))
end
end
end
diff --git a/app/components/homescreen/blocks/users.html.erb b/app/components/homescreen/blocks/users.html.erb
deleted file mode 100644
index f88f3887caf..00000000000
--- a/app/components/homescreen/blocks/users.html.erb
+++ /dev/null
@@ -1,23 +0,0 @@
-<%= widget_wrapper do %>
-
<%= t("homescreen.additional.users") %>
-
- <% unless @newest_users.empty? %>
-
- <% @newest_users.each do |user| %>
-
- <%= link_to_user user %>
- (<%= format_date(user.created_at) %>)
-
- <% end %>
-
- <% end %>
-
-
- <% if current_user.admin? %>
- <%= link_to new_user_path, class: "button -primary" do %>
- <%= op_icon("button--icon icon-add") %>
- <%= t(:label_invite_user) %>
- <% end %>
- <% end %>
-
-<% end %>
diff --git a/app/components/individual_principal_base_filter_component.rb b/app/components/individual_principal_base_filter_component.rb
index 7e1291b6cfe..362c30f683e 100644
--- a/app/components/individual_principal_base_filter_component.rb
+++ b/app/components/individual_principal_base_filter_component.rb
@@ -75,7 +75,7 @@ class IndividualPrincipalBaseFilterComponent < ApplicationComponent
end
def base_query
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
protected
@@ -93,7 +93,7 @@ class IndividualPrincipalBaseFilterComponent < ApplicationComponent
# INSTANCE METHODS:
def filter_path
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def initially_visible?
diff --git a/app/components/my/notifications/project_settings_dialog_component.html.erb b/app/components/my/notifications/project_settings_dialog_component.html.erb
new file mode 100644
index 00000000000..d92281d49d4
--- /dev/null
+++ b/app/components/my/notifications/project_settings_dialog_component.html.erb
@@ -0,0 +1,62 @@
+<%#-- 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: DIALOG_ID,
+ title: t("my_account.notifications.project_specific_settings.dialog_title"),
+ position: :right,
+ test_selector: "project-specific-settings-form"
+ )
+ ) do |d|
+ d.with_body do
+ primer_form_with(
+ model: notification_setting,
+ scope: :notification_setting,
+ url: @form_url,
+ method: edit_mode? ? :patch : :post,
+ html: { id: FORM_ID },
+ data: {
+ turbo: false,
+ controller: "show-when-checked",
+ show_when_checked_visibility_class: "d-none"
+ }
+ ) do |form|
+ forms = [My::Notifications::ProjectAutocompleterForm.new(form, readonly: edit_mode?, user: @user)]
+ forms << My::Notifications::ParticipatingForm.new(form, show_submit: false)
+ forms << My::Notifications::DateAlertsForm.new(form, show_submit: false) if date_alerts_available?
+ forms << My::Notifications::NonParticipatingForm.new(form, show_submit: false)
+ render(Primer::Forms::FormList.new(*forms))
+ end
+ end
+ d.with_footer(show_divider: true) do
+ concat(render(Primer::Beta::Button.new(data: { "close-dialog-id": DIALOG_ID })) { t("button_cancel") })
+ concat(render(Primer::Beta::Button.new(scheme: :primary, type: :submit, form: FORM_ID)) { t("button_save") })
+ end
+ end %>
diff --git a/app/components/my/notifications/project_settings_dialog_component.rb b/app/components/my/notifications/project_settings_dialog_component.rb
new file mode 100644
index 00000000000..1b2d0daaa87
--- /dev/null
+++ b/app/components/my/notifications/project_settings_dialog_component.rb
@@ -0,0 +1,62 @@
+# 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 My
+ module Notifications
+ class ProjectSettingsDialogComponent < ApplicationComponent
+ include OpTurbo::Streamable
+ include OpPrimer::FormHelpers
+
+ DIALOG_ID = "project-notification-settings-dialog"
+ FORM_ID = "project-notification-settings-form"
+
+ def initialize(user:, form_url:, notification_setting: nil)
+ super
+ @user = user
+ @form_url = form_url
+ @provided_setting = notification_setting
+ end
+
+ private
+
+ def notification_setting
+ @notification_setting ||= @provided_setting || @user.notification_settings.build
+ end
+
+ def edit_mode?
+ notification_setting.persisted?
+ end
+
+ def date_alerts_available?
+ EnterpriseToken.allows_to?(:date_alerts)
+ end
+ end
+ end
+end
diff --git a/app/components/my/notifications/show_page_component.html.erb b/app/components/my/notifications/show_page_component.html.erb
new file mode 100644
index 00000000000..2bb538428ce
--- /dev/null
+++ b/app/components/my/notifications/show_page_component.html.erb
@@ -0,0 +1,135 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ settings_primer_form_with(
+ model: global_notification_setting,
+ scope: :notification_setting,
+ url: update_participating_url,
+ method: :patch,
+ data: { turbo: false, test_selector: "participating-form" }
+ ) do |form|
+ render(My::Notifications::ParticipatingForm.new(form))
+ end
+%>
+
+<% if date_alerts_available? %>
+ <%=
+ settings_primer_form_with(
+ model: global_notification_setting,
+ scope: :notification_setting,
+ url: update_date_alerts_url,
+ method: :patch,
+ data: {
+ turbo: false,
+ controller: "show-when-checked",
+ show_when_checked_visibility_class: "d-none",
+ test_selector: "date-alerts-form"
+ }
+ ) do |form|
+ render(My::Notifications::DateAlertsForm.new(form))
+ end
+ %>
+<% else %>
+ <%= render(Primer::Beta::Subhead.new(mt: 3)) do |component|
+ component.with_heading(size: :medium) { t("my_account.notifications.date_alerts.title") }
+ end %>
+ <%= render(EnterpriseEdition::BannerComponent.new(:date_alerts, variant: :inline)) %>
+<% end %>
+
+<%=
+ settings_primer_form_with(
+ model: global_notification_setting,
+ scope: :notification_setting,
+ url: update_non_participating_url,
+ method: :patch,
+ data: { turbo: false, test_selector: "non-participating-form" }
+ ) do |form|
+ render(My::Notifications::NonParticipatingForm.new(form))
+ end
+%>
+
+<%= render(Primer::BaseComponent.new(tag: :div, classes: "op-admin-settings-form-wrapper")) do %>
+ <%= render(Primer::Beta::Subhead.new(mt: 3)) do |component|
+ component.with_heading(size: :medium) { t("my_account.notifications.project_specific_settings.title") }
+ end %>
+
+ <% if project_notification_settings.any? %>
+ <%= render(Primer::Beta::BorderBox.new(mb: 3)) do |box| %>
+ <% box.with_header { t("my_account.notifications.project_specific_settings.list_header") } %>
+ <% project_notification_settings.each do |setting| %>
+ <% box.with_row(test_selector: "project-specific-settings-list") do %>
+ <%= flex_layout(justify_content: :space_between, align_items: :center, width: :full) do |flex| %>
+ <%= flex.with_column do %>
+ <%= setting.project.name %>
+ <% end %>
+ <%= flex.with_column do %>
+ <%= render(Primer::Alpha::ActionMenu.new(test_selector: "project-specific-settings-list--action-menu")) do |menu|
+ menu.with_show_button(
+ scheme: :invisible,
+ size: :small,
+ icon: :"kebab-horizontal",
+ "aria-label": t(:label_open_menu),
+ tooltip_direction: :w
+ )
+ menu.with_item(
+ label: t("button_edit"),
+ href: edit_project_settings_url(setting.project_id),
+ content_arguments: { data: { controller: "async-dialog" } }
+ ) do |item|
+ item.with_leading_visual_icon(icon: :pencil)
+ end
+ menu.with_item(
+ label: t("button_delete"),
+ scheme: :danger,
+ href: project_setting_url(setting.project_id),
+ content_arguments: { data: { turbo_method: :delete, turbo_confirm: t("text_are_you_sure") } }
+ ) do |item|
+ item.with_leading_visual_icon(icon: :trash)
+ end
+ end %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <%= render(
+ Primer::Beta::Button.new(
+ tag: :a,
+ href: new_project_settings_url,
+ data: { controller: "async-dialog" },
+ mb: 3
+ )
+ ) do |b|
+ b.with_leading_visual_icon(icon: :plus)
+ helpers.t("my_account.notifications.project_specific_settings.add_button")
+ end %>
+<% end %>
diff --git a/app/components/my/notifications/show_page_component.rb b/app/components/my/notifications/show_page_component.rb
new file mode 100644
index 00000000000..d86e1c2d462
--- /dev/null
+++ b/app/components/my/notifications/show_page_component.rb
@@ -0,0 +1,78 @@
+# 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 My
+ module Notifications
+ class ShowPageComponent < ApplicationComponent
+ include OpPrimer::FormHelpers
+ include OpPrimer::ComponentHelpers
+
+ attr_reader :global_notification_setting,
+ :update_participating_url,
+ :update_non_participating_url,
+ :update_date_alerts_url,
+ :new_project_settings_url,
+ :project_notification_settings
+
+ def initialize(user:,
+ global_notification_setting:,
+ update_participating_url:,
+ update_non_participating_url:,
+ update_date_alerts_url:,
+ new_project_settings_url:,
+ edit_project_settings_url:,
+ project_setting_url:)
+ super
+
+ @user = user
+ @global_notification_setting = global_notification_setting
+ @update_participating_url = update_participating_url
+ @update_non_participating_url = update_non_participating_url
+ @update_date_alerts_url = update_date_alerts_url
+ @new_project_settings_url = new_project_settings_url
+ @edit_project_settings_url_builder = edit_project_settings_url
+ @project_setting_url_builder = project_setting_url
+ @project_notification_settings = user.notification_settings.where.not(project: nil).includes(:project)
+ end
+
+ def edit_project_settings_url(project_id)
+ @edit_project_settings_url_builder.call(project_id)
+ end
+
+ def project_setting_url(project_id)
+ @project_setting_url_builder.call(project_id)
+ end
+
+ def date_alerts_available?
+ EnterpriseToken.allows_to?(:date_alerts)
+ end
+ end
+ end
+end
diff --git a/app/components/my/notifications/show_page_header_component.rb b/app/components/my/notifications/show_page_header_component.rb
new file mode 100644
index 00000000000..20db77a9211
--- /dev/null
+++ b/app/components/my/notifications/show_page_header_component.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+module My
+ module Notifications
+ class ShowPageHeaderComponent < ApplicationComponent
+ def call
+ render(Primer::OpenProject::PageHeader.new) do |header|
+ header.with_title { t("my_account.notifications_and_email.title") }
+ header.with_breadcrumbs(
+ [{ href: helpers.my_account_path, text: t(:label_my_account) },
+ t("my_account.notifications_and_email.title")]
+ )
+
+ helpers.render_tab_header_nav(header, tabs)
+ end
+ end
+
+ def tabs
+ [
+ {
+ name: "notifications",
+ path: helpers.my_notifications_path(tab: "notifications"),
+ label: t("my_account.notifications_and_email.tabs.notifications"),
+ data: { turbo: false }
+ },
+ {
+ name: "reminders",
+ path: helpers.my_notifications_path(tab: "reminders"),
+ label: t("my_account.notifications_and_email.tabs.email_reminders"),
+ data: { turbo: false }
+ }
+ ]
+ end
+ end
+ end
+end
diff --git a/app/components/my/reminders/daily_times_component.html.erb b/app/components/my/reminders/daily_times_component.html.erb
new file mode 100644
index 00000000000..bb8c350caae
--- /dev/null
+++ b/app/components/my/reminders/daily_times_component.html.erb
@@ -0,0 +1,111 @@
+<%#-- 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.
+
+++#%>
+
+
+
+ <% @times.each do |time| %>
+ <%=
+ flex_layout(mb: 2, data: { "my--daily-reminders-target": "row" }) do |flex|
+ flex.with_column do
+ render(
+ Primer::Alpha::Select.new(
+ name: field_name,
+ label: t("my_account.email_reminders.daily_reminders.time_slot_label"),
+ visually_hide_label: true,
+ data: { test_selector: "settings-daily-time" }
+ )
+ ) do |select|
+ time_options.each do |label, value|
+ select.option(label:, value:, selected: selected_value_for(time) == value)
+ end
+ end
+ end
+
+ flex.with_column do
+ render(
+ Primer::Beta::IconButton.new(
+ icon: :x,
+ scheme: :invisible,
+ type: :button,
+ hidden: @times.size <= 1,
+ aria: { label: t("my_account.email_reminders.daily_reminders.remove_time") },
+ data: { action: "my--daily-reminders#removeTime", test_selector: "settings-daily-time--remove" }
+ )
+ )
+ end
+ end
+ %>
+ <% end %>
+
diff --git a/app/components/my/reminders/daily_times_component.rb b/app/components/my/reminders/daily_times_component.rb
new file mode 100644
index 00000000000..f83c5a2e6ea
--- /dev/null
+++ b/app/components/my/reminders/daily_times_component.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 My
+ module Reminders
+ class DailyTimesComponent < ApplicationComponent
+ include OpPrimer::ComponentHelpers
+
+ def initialize(times:, scope:)
+ super
+
+ @times = Array(times)
+ @scope = scope
+ end
+
+ def field_name
+ "#{@scope}[times][]"
+ end
+
+ def time_options
+ (0..23).map do |hour|
+ time = Time.utc(2000, 1, 1, hour)
+ [I18n.l(time, format: :time), time.strftime("%H:00:00+00:00")]
+ end
+ end
+
+ def selected_value_for(time_str)
+ Time.zone.parse(time_str.to_s).strftime("%H:00:00+00:00")
+ end
+ end
+ end
+end
diff --git a/app/components/my/reminders/show_page_component.html.erb b/app/components/my/reminders/show_page_component.html.erb
new file mode 100644
index 00000000000..b881f631bb4
--- /dev/null
+++ b/app/components/my/reminders/show_page_component.html.erb
@@ -0,0 +1,98 @@
+<%#-- 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.
+
+++#%>
+
+<%=
+ settings_primer_form_with(
+ model: @user.pref,
+ scope: "pref[immediate_reminders]",
+ url: update_url,
+ method: :patch,
+ data: { turbo: false, test_selector: "immediate-reminders-form" }
+ ) do |form|
+ render(My::Reminders::ImmediateRemindersForm.new(form))
+ end
+%>
+
+<%=
+ settings_primer_form_with(
+ model: daily_reminders_form_model,
+ scope: "pref[daily_reminders]",
+ url: update_url,
+ method: :patch,
+ data: {
+ turbo: false,
+ controller: "show-when-checked",
+ show_when_checked_visibility_class: "d-none",
+ test_selector: "daily-reminders-form"
+ }
+ ) do |form|
+ render(My::Reminders::DailyRemindersForm.new(form))
+ end
+%>
+
+<%=
+ settings_primer_form_with(
+ model: @user.pref,
+ scope: :pref,
+ url: update_workdays_url,
+ method: :patch,
+ data: { turbo: false, test_selector: "workdays-form" }
+ ) do |form|
+ render(My::Reminders::WorkdaysForm.new(form))
+ end
+%>
+
+<%=
+ settings_primer_form_with(
+ model: pause_reminders_form_model,
+ scope: "pref[pause_reminders]",
+ url: update_url,
+ method: :patch,
+ data: {
+ turbo: false,
+ controller: "show-when-checked",
+ show_when_checked_visibility_class: "d-none",
+ test_selector: "pause-reminders-form"
+ }
+ ) do |form|
+ render(My::Reminders::PauseRemindersForm.new(form))
+ end
+%>
+
+<%=
+ settings_primer_form_with(
+ model: global_notification_setting,
+ scope: :notification_setting,
+ url: update_email_alerts_url,
+ method: :patch,
+ data: { turbo: false }
+ ) do |form|
+ render(My::Reminders::EmailAlertsForm.new(form))
+ end
+%>
diff --git a/app/components/my/reminders/show_page_component.rb b/app/components/my/reminders/show_page_component.rb
new file mode 100644
index 00000000000..2826d704416
--- /dev/null
+++ b/app/components/my/reminders/show_page_component.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 My
+ module Reminders
+ class ShowPageComponent < ApplicationComponent
+ include OpPrimer::FormHelpers
+
+ attr_reader :global_notification_setting, :update_url, :update_workdays_url, :update_email_alerts_url
+
+ def initialize(user:, global_notification_setting:, update_url:, update_workdays_url:, update_email_alerts_url:)
+ super
+
+ @user = user
+ @global_notification_setting = global_notification_setting
+ @update_url = update_url
+ @update_workdays_url = update_workdays_url
+ @update_email_alerts_url = update_email_alerts_url
+ end
+
+ def daily_reminders_form_model
+ daily_reminders = @user.pref.daily_reminders
+ My::Reminders::DailyRemindersForm::DailyRemindersFormModel.new(
+ enabled: daily_reminders[:enabled],
+ times: daily_reminders[:times]
+ )
+ end
+
+ def pause_reminders_form_model
+ pause_reminders = @user.pref.pause_reminders
+ My::Reminders::PauseRemindersForm::PauseRemindersFormModel.new(
+ enabled: pause_reminders[:enabled],
+ first_day: pause_reminders[:first_day],
+ last_day: pause_reminders[:last_day]
+ )
+ end
+ end
+ end
+end
diff --git a/app/components/op_primer/email_updates_mode_selector_component.rb b/app/components/op_primer/email_updates_mode_selector_component.rb
index ba9ef59f64a..b4ce6d4f656 100644
--- a/app/components/op_primer/email_updates_mode_selector_component.rb
+++ b/app/components/op_primer/email_updates_mode_selector_component.rb
@@ -38,7 +38,7 @@ module OpPrimer
super()
if !show_button && alt_text.blank?
- raise NotImplementedError, "alt_text must be provided when the button is shown conditionally"
+ raise ArgumentError, "alt_text must be provided when the button is shown conditionally"
end
diff --git a/modules/backlogs/app/views/shared/_model_errors.html.erb b/app/components/op_primer/inline_macro_component.html.erb
similarity index 89%
rename from modules/backlogs/app/views/shared/_model_errors.html.erb
rename to app/components/op_primer/inline_macro_component.html.erb
index 328edde8973..71fb370380f 100644
--- a/modules/backlogs/app/views/shared/_model_errors.html.erb
+++ b/app/components/op_primer/inline_macro_component.html.erb
@@ -27,8 +27,7 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-
- <% model_errors.full_messages.each do |err| %>
-
<%= err %>
- <% end %>
-
+<%= render(Primer::BaseComponent.new(tag: :span, **@system_arguments)) do %>
+ <%= leading_visual_icon %>
+ <%= content %>
+<% end %>
diff --git a/modules/backlogs/spec/forms/admin/settings/backlogs_settings_model_spec.rb b/app/components/op_primer/inline_macro_component.rb
similarity index 74%
rename from modules/backlogs/spec/forms/admin/settings/backlogs_settings_model_spec.rb
rename to app/components/op_primer/inline_macro_component.rb
index f8a17c7cb56..008e0f47df5 100644
--- a/modules/backlogs/spec/forms/admin/settings/backlogs_settings_model_spec.rb
+++ b/app/components/op_primer/inline_macro_component.rb
@@ -28,16 +28,20 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-require "rails_helper"
+module OpPrimer
+ class InlineMacroComponent < Primer::Component
+ renders_one :leading_visual_icon, ->(icon:, color: :muted) do
+ Primer::Beta::Octicon.new(icon:, color:, mr: 2, vertical_align: :middle)
+ end
-RSpec.describe Admin::Settings::BacklogsSettingsModel, type: :model do
- describe "validations" do
- subject(:model) { described_class.new(story_types: [1, 2, 3]) }
+ def initialize(**system_arguments)
+ super()
- it "validates that a story type cannot be used as a task type" do
- expect(subject).to validate_exclusion_of(:task_type)
- .in_array([1, 2, 3])
- .with_message(I18n.t("errors.attributes.task_type.cannot_be_story_type"))
+ @system_arguments = system_arguments
+ @system_arguments[:classes] = class_names(
+ @system_arguments[:classes],
+ "op-inline-macro"
+ )
end
end
end
diff --git a/app/components/op_primer/inline_macro_component.sass b/app/components/op_primer/inline_macro_component.sass
new file mode 100644
index 00000000000..0356f0647d7
--- /dev/null
+++ b/app/components/op_primer/inline_macro_component.sass
@@ -0,0 +1,7 @@
+@media screen
+ .op-inline-macro
+ display: inline
+ background: var(--bgColor-muted)
+ border: 1px solid transparent
+ border-radius: var(--borderRadius-medium)
+ padding: 4px 8px
diff --git a/app/components/op_primer/status_button_component.rb b/app/components/op_primer/status_button_component.rb
index 74260921ff1..f98b7fc5f40 100644
--- a/app/components/op_primer/status_button_component.rb
+++ b/app/components/op_primer/status_button_component.rb
@@ -50,7 +50,7 @@ module OpPrimer
end
def default_button_title
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def disabled?
diff --git a/app/components/portfolios/details_component.html.erb b/app/components/portfolios/details_component.html.erb
index bb5223eb2f4..3acf1a9345b 100644
--- a/app/components/portfolios/details_component.html.erb
+++ b/app/components/portfolios/details_component.html.erb
@@ -40,7 +40,7 @@
size: :large,
data: {
hover_card_trigger_target: "trigger",
- hover_card_popover_id: sub_status_hover_card_id,
+ hover_card_popover_template_id: sub_status_hover_card_id,
test_selector: "op-portfolios--sub-status-bar"
}
)
@@ -166,9 +166,8 @@
<%=
# Card that appears when hovering over the progress bar
if render_sub_status_bar?
- content_tag(:div, class: "op-hover-card--hidden-container") do
+ content_tag(:template, id: sub_status_hover_card_id) do
flex_layout(
- id: sub_status_hover_card_id,
classes: "op-portfolios--popover",
data: {
test_selector: "op-portfolios--hover-card-#{portfolio.id}"
diff --git a/app/components/portfolios/details_component.sass b/app/components/portfolios/details_component.sass
index 43fda50c700..1a20a5fd433 100644
--- a/app/components/portfolios/details_component.sass
+++ b/app/components/portfolios/details_component.sass
@@ -51,3 +51,6 @@ $status_not-set: var(--progressBar-track-bgColor) // invisible background color
@media screen and (max-width: $breakpoint-sm)
margin-top: var(--base-size-16, 1rem)
margin-bottom: var(--base-size-16, 1rem) !important
+
+.op-hover-card:has(> .op-portfolios--popover)
+ width: fit-content
diff --git a/app/components/projects/concerns/identifier_suggestion.rb b/app/components/projects/concerns/identifier_suggestion.rb
index 2c970953180..2fbfb502fea 100644
--- a/app/components/projects/concerns/identifier_suggestion.rb
+++ b/app/components/projects/concerns/identifier_suggestion.rb
@@ -32,7 +32,7 @@ module Projects
module Concerns
module IdentifierSuggestion
def identifier_suggestion_data
- suggestion_mode = Setting::WorkPackageIdentifier.alphanumeric? ? "semantic" : "legacy"
+ suggestion_mode = Setting::WorkPackageIdentifier.semantic? ? "semantic" : "classic"
{
controller: "projects--identifier-suggestion",
diff --git a/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.html.erb b/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.html.erb
index 0ae9907be13..e3ce2548a28 100644
--- a/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.html.erb
+++ b/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.html.erb
@@ -50,9 +50,8 @@
# As a courtesy to users, we show a hover card explaining why the toggle is disabled.
if toggle_disabled?
concat(
- content_tag(:div, class: "op-hover-card--hidden-container") do
+ content_tag(:template, id: unique_hovercard_id) do
flex_layout(
- id: unique_hovercard_id,
classes: "op-project-custom-field--popover",
data: {
test_selector: "op-project-custom-field--hover-card-#{@project_custom_field.id}"
diff --git a/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.rb b/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.rb
index ffe15983c00..e42b00b4e99 100644
--- a/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.rb
+++ b/app/components/projects/settings/creation_wizard/project_custom_field_sections/custom_field_row_component.rb
@@ -72,7 +72,7 @@ module Projects
if toggle_disabled?
# Add hover card that explains why this toggle switch is disabled
data[:hover_card_trigger_target] = "trigger"
- data[:hover_card_popover_id] = unique_hovercard_id
+ data[:hover_card_popover_template_id] = unique_hovercard_id
end
end
end
diff --git a/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.html.erb b/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.html.erb
index 757625840dd..293dddeaff5 100644
--- a/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.html.erb
+++ b/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.html.erb
@@ -56,9 +56,8 @@
# As a courtesy to users, we show a hover card explaining why the toggle is disabled.
if toggle_disabled?
concat(
- content_tag(:div, class: "op-hover-card--hidden-container") do
+ content_tag(:template, id: unique_hovercard_id) do
flex_layout(
- id: unique_hovercard_id,
classes: "op-project-custom-field--popover",
data: {
test_selector: "op-project-custom-field--hover-card-#{@project_custom_field.id}"
diff --git a/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.rb b/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.rb
index 16974f62431..e72bde388c3 100644
--- a/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.rb
+++ b/app/components/projects/settings/project_custom_field_sections/custom_field_row_component.rb
@@ -87,7 +87,7 @@ module Projects
if toggle_disabled?
# Add hover card that explains why this toggle switch is disabled
data[:hover_card_trigger_target] = "trigger"
- data[:hover_card_popover_id] = unique_hovercard_id
+ data[:hover_card_popover_template_id] = unique_hovercard_id
end
end
end
diff --git a/app/components/versions/row_component.rb b/app/components/versions/row_component.rb
index 1a6187596f3..73dd9cb06db 100644
--- a/app/components/versions/row_component.rb
+++ b/app/components/versions/row_component.rb
@@ -85,7 +85,7 @@ module Versions
end
def button_links
- [edit_link, delete_link, backlogs_edit_link].compact
+ [edit_link, delete_link].compact
end
private
diff --git a/app/components/work_packages/admin/settings/change_identifiers_dialog_component.html.erb b/app/components/work_packages/admin/settings/change_identifiers_dialog_component.html.erb
index 480cf64bb7c..1895c9bc206 100644
--- a/app/components/work_packages/admin/settings/change_identifiers_dialog_component.html.erb
+++ b/app/components/work_packages/admin/settings/change_identifiers_dialog_component.html.erb
@@ -58,7 +58,7 @@
)
dialog.with_additional_details(display: :none) do
- hidden_field_tag("settings[work_packages_identifier]", Setting::WorkPackageIdentifier::ALPHANUMERIC)
+ hidden_field_tag("settings[work_packages_identifier]", Setting::WorkPackageIdentifier::SEMANTIC)
end
end
%>
diff --git a/app/components/work_packages/admin/settings/identifier_autofix_section_component.rb b/app/components/work_packages/admin/settings/identifier_autofix_section_component.rb
index 75ac28dd0db..7ca1d1acc62 100644
--- a/app/components/work_packages/admin/settings/identifier_autofix_section_component.rb
+++ b/app/components/work_packages/admin/settings/identifier_autofix_section_component.rb
@@ -34,7 +34,7 @@ module WorkPackages
class IdentifierAutofixSectionComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
- DISPLAY_COUNT = WorkPackages::IdentifierAutofix::PreviewQuery::DISPLAY_COUNT
+ DISPLAY_COUNT = ProjectIdentifiers::IdentifierAutofix::PreviewQuery::DISPLAY_COUNT
def initialize(projects_data:, total_count: projects_data.size)
super()
diff --git a/app/components/work_packages/admin/settings/identifier_settings_form_component.rb b/app/components/work_packages/admin/settings/identifier_settings_form_component.rb
index 3e9c28d41dd..5ddad8f2df5 100644
--- a/app/components/work_packages/admin/settings/identifier_settings_form_component.rb
+++ b/app/components/work_packages/admin/settings/identifier_settings_form_component.rb
@@ -46,7 +46,7 @@ module WorkPackages
super()
@state = state
if state == :edit
- result = WorkPackages::IdentifierAutofix::PreviewQuery.new.call
+ result = ProjectIdentifiers::IdentifierAutofix::PreviewQuery.new.call
@projects_data = result.projects_data
@total_count = result.total_count
else
@@ -64,7 +64,7 @@ module WorkPackages
def form_id = "wp-identifier-settings-form"
def show_autofix_section?
- state == :edit && Setting::WorkPackageIdentifier.alphanumeric? && has_problematic_projects?
+ state == :edit && Setting::WorkPackageIdentifier.semantic? && has_problematic_projects?
end
def change_in_progress? = state == :change_in_progress
diff --git a/app/components/work_packages/bulk_delete_dialog_component.html.erb b/app/components/work_packages/bulk_delete_dialog_component.html.erb
new file mode 100644
index 00000000000..148e8dc3f64
--- /dev/null
+++ b/app/components/work_packages/bulk_delete_dialog_component.html.erb
@@ -0,0 +1,81 @@
+<%#
+ -- 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::OpenProject::DangerDialog.new(
+ id:,
+ title:,
+ form_arguments: {
+ action: form_action,
+ method: :delete,
+ data: { turbo: false }
+ },
+ size: :medium_portrait
+ )
+ ) do |dialog|
+%>
+ <% dialog.with_confirmation_message do |message|
+ message.with_heading(tag: :h2) { heading }
+ message.with_description_content(description)
+ end %>
+
+ <% dialog.with_additional_details(display: :block) do %>
+ <% if multiple_projects? %>
+ <%= render(Primer::Alpha::Banner.new(mb: 2, scheme: :warning, icon: :alert)) do %>
+ <%= I18n.t("work_packages.bulk_delete_dialog.cross_project_warning", projects: project_names) %>
+ <% end %>
+ <% end %>
+ <%= render(OpPrimer::InsetBoxComponent.new) do %>
+ <% work_packages.each do |wp| %>
+ <%= render WorkPackages::InfoLineComponent.new(work_package: wp,
+ show_subject: true,
+ show_status: false,
+ show_project: multiple_projects?) %>
+ <% if descendants_for(wp).any? %>
+ <%= render(Primer::Box.new(pl: 2, my: 1)) do %>
+ <%= render(Primer::Beta::Text.new(mt: 1, font_size: :small, font_weight: :bold, display: :block, mb: 1)) do %>
+ <%= I18n.t("work_packages.bulk_delete_dialog.children_label") %>
+ <% end %>
+ <% descendants_for(wp).each do |descendant| %>
+ <%= render WorkPackages::InfoLineComponent.new(work_package: descendant,
+ show_subject: true,
+ show_status: false,
+ show_project: descendant.project != wp.project) %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <% dialog.with_confirmation_check_box_content(confirmation_checkbox_text) %>
+<% end %>
diff --git a/app/components/work_packages/bulk_delete_dialog_component.rb b/app/components/work_packages/bulk_delete_dialog_component.rb
new file mode 100644
index 00000000000..a3e75df4cbf
--- /dev/null
+++ b/app/components/work_packages/bulk_delete_dialog_component.rb
@@ -0,0 +1,118 @@
+# 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
+ class BulkDeleteDialogComponent < ApplicationComponent
+ include OpTurbo::Streamable
+
+ attr_reader :work_packages
+
+ def initialize(work_packages:, back_url: nil)
+ super
+ @work_packages = work_packages
+ @back_url = back_url
+ end
+
+ private
+
+ def id = "wp-delete-dialog"
+
+ def title
+ I18n.t("work_packages.bulk_delete_dialog.title", count: total_count)
+ end
+
+ def heading
+ I18n.t("work_packages.bulk_delete_dialog.heading", count: total_count)
+ end
+
+ def description
+ if has_descendants?
+ I18n.t("work_packages.bulk_delete_dialog.description_with_children")
+ else
+ I18n.t("work_packages.bulk_delete_dialog.description")
+ end
+ end
+
+ def confirmation_checkbox_text
+ if has_descendants?
+ I18n.t("work_packages.bulk_delete_dialog.confirm_children_deletion")
+ else
+ I18n.t("text_permanent_delete_confirmation_checkbox_label")
+ end
+ end
+
+ def total_count
+ @total_count ||= work_packages.count + descendants_by_work_package.values.sum(&:size)
+ end
+
+ def multiple_projects?
+ projects.size > 1
+ end
+
+ def project_names
+ projects.map(&:name).join(", ")
+ end
+
+ def descendants_for(work_package)
+ (descendants_by_work_package[work_package.id] || [])
+ .reject { |child| work_packages.include?(child) }
+ end
+
+ def has_descendants?
+ work_packages.any? { |wp| descendants_for(wp).any? }
+ end
+
+ def form_action
+ helpers.work_packages_bulk_path(ids: work_packages.map(&:id), back_url: @back_url)
+ end
+
+ def projects
+ @projects ||= work_packages.filter_map(&:project).uniq
+ end
+
+ def descendants_by_work_package
+ @descendants_by_work_package ||= begin
+ hierarchies = WorkPackageHierarchy
+ .where(ancestor_id: work_packages.map(&:id))
+ .where("generations > 0")
+ .order(:generations, :descendant_id)
+
+ descendant_records = WorkPackage
+ .where(id: hierarchies.pluck(:descendant_id))
+ .includes(:project, :type, :status)
+ .index_by(&:id)
+
+ hierarchies
+ .group_by(&:ancestor_id)
+ .transform_values { |rows| rows.filter_map { |r| descendant_records[r.descendant_id] } }
+ end
+ end
+ end
+end
diff --git a/app/components/work_packages/delete_dialog_component.html.erb b/app/components/work_packages/delete_dialog_component.html.erb
new file mode 100644
index 00000000000..ac66a997eab
--- /dev/null
+++ b/app/components/work_packages/delete_dialog_component.html.erb
@@ -0,0 +1,75 @@
+<%#
+ -- 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::OpenProject::DangerDialog.new(
+ id:,
+ title:,
+ form_arguments: {
+ action: form_action,
+ method: :delete,
+ data: { turbo: false }
+ },
+ size: :medium_portrait
+ )
+ ) do |dialog|
+%>
+ <% dialog.with_confirmation_message do |message|
+ message.with_heading(tag: :h2) { heading }
+ message.with_description_content(description)
+ end %>
+
+ <% if has_descendants? %>
+ <% dialog.with_additional_details(display: :block) do %>
+ <% if cross_project_descendants? %>
+ <%= render(Primer::Alpha::Banner.new(mb: 2, scheme: :warning, icon: :alert)) do %>
+ <%= I18n.t("work_packages.delete_dialog.cross_project_warning", projects: all_project_names) %>
+ <% end %>
+ <% end %>
+ <%= render(OpPrimer::InsetBoxComponent.new) do %>
+ <%= render(Primer::Beta::Text.new(font_size: :small, font_weight: :bold, display: :block, mb: 2)) do %>
+ <%= I18n.t("work_packages.bulk_delete_dialog.children_label") %>
+ <% end %>
+ <% descendants.each do |descendant| %>
+ <%= render WorkPackages::InfoLineComponent.new(pl:2,
+ my: 1,
+ work_package: descendant,
+ show_subject: true,
+ show_status: false,
+ show_project: descendant.project != work_package.project) %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <% dialog.with_confirmation_check_box_content(confirmation_checkbox_text) %>
+<% end %>
diff --git a/app/components/work_packages/delete_dialog_component.rb b/app/components/work_packages/delete_dialog_component.rb
new file mode 100644
index 00000000000..d2daf8ec27a
--- /dev/null
+++ b/app/components/work_packages/delete_dialog_component.rb
@@ -0,0 +1,100 @@
+# 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
+ class DeleteDialogComponent < ApplicationComponent
+ include OpTurbo::Streamable
+
+ attr_reader :work_package
+
+ def initialize(work_package:, back_url: nil)
+ super
+ @work_package = work_package
+ @back_url = back_url
+ end
+
+ private
+
+ def id = "wp-delete-dialog"
+
+ def title
+ I18n.t("work_packages.delete_dialog.title")
+ end
+
+ def heading
+ I18n.t("work_packages.delete_dialog.heading")
+ end
+
+ def description
+ I18n.t("work_packages.delete_dialog.description", name: work_package.to_s)
+ end
+
+ def confirmation_checkbox_text
+ if has_descendants?
+ I18n.t("work_packages.delete_dialog.confirm_descendants_deletion")
+ else
+ I18n.t("text_permanent_delete_confirmation_checkbox_label")
+ end
+ end
+
+ def descendants
+ @descendants ||= WorkPackage
+ .joins("INNER JOIN work_package_hierarchies ON work_package_hierarchies.descendant_id = work_packages.id")
+ .where(work_package_hierarchies: { ancestor_id: work_package.id })
+ .where("work_package_hierarchies.generations > 0")
+ .includes(:project, :type, :status)
+ .order("work_package_hierarchies.generations ASC, work_packages.id ASC")
+ end
+
+ def has_descendants?
+ descendants.any?
+ end
+
+ def cross_project_descendants?
+ descendants.any? { |d| d.project != work_package.project }
+ end
+
+ def all_project_names
+ names = descendants
+ .filter_map(&:project)
+ .uniq
+ .reject { |p| p == work_package.project }
+ .map(&:name)
+
+ names
+ .unshift(work_package.project.name)
+ .join(", ")
+ end
+
+ def form_action
+ helpers.work_packages_bulk_path(ids: [work_package.id], back_url: @back_url)
+ end
+ end
+end
diff --git a/app/components/work_packages/exports/base_export_settings_component.rb b/app/components/work_packages/exports/base_export_settings_component.rb
index 8f9be5894b4..88d6d572815 100644
--- a/app/components/work_packages/exports/base_export_settings_component.rb
+++ b/app/components/work_packages/exports/base_export_settings_component.rb
@@ -40,7 +40,7 @@ module WorkPackages
end
def format
- raise NotImplementedError, "Must be overridden in subclass"
+ raise SubclassResponsibilityError
end
def export_settings
diff --git a/app/components/work_packages/info_line_component.html.erb b/app/components/work_packages/info_line_component.html.erb
index e124a5c3582..1f590ec6550 100644
--- a/app/components/work_packages/info_line_component.html.erb
+++ b/app/components/work_packages/info_line_component.html.erb
@@ -1,9 +1,14 @@
<%=
- flex_layout(flex_wrap: :wrap) do |flex|
+ flex_layout(flex_wrap: :wrap, **@system_arguments) do |flex|
+ if @show_project && !@show_subject
+ flex.with_column(mr: 2) do
+ render(Primer::Beta::Text.new(font_size: @font_size)) { "#{@work_package.project.name}: " }
+ end
+ end
flex.with_column(mr: 2) do
render(WorkPackages::HighlightedTypeComponent.new(work_package: @work_package, font_size: :small))
end
- flex.with_column(mr: 2) do
+ flex.with_column do
render(
Primer::Beta::Link.new(
href: url_for(controller: "/work_packages", action: "show", id: @work_package),
@@ -13,8 +18,23 @@
)
) { "##{@work_package.id}" }
end
- flex.with_column do
- render WorkPackages::StatusBadgeComponent.new(status: @work_package.status)
+
+ if @show_status
+ flex.with_column(ml: 2) do
+ render WorkPackages::StatusBadgeComponent.new(status: @work_package.status)
+ end
+ end
+
+ if @show_subject
+ flex.with_column(classes: "ellipsis", ml: 1) do
+ render(Primer::Beta::Text.new(font_size: @font_size)) do
+ if @show_project
+ "#{@work_package.project.name}: #{@work_package.subject}"
+ else
+ @work_package.subject
+ end
+ end
+ end
end
end
%>
diff --git a/app/components/work_packages/info_line_component.rb b/app/components/work_packages/info_line_component.rb
index 293d79eedc5..9be082a5acc 100644
--- a/app/components/work_packages/info_line_component.rb
+++ b/app/components/work_packages/info_line_component.rb
@@ -31,10 +31,20 @@
class WorkPackages::InfoLineComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
- def initialize(work_package:, font_size: :small)
+ def initialize(work_package:,
+ show_project: false,
+ show_subject: false,
+ show_status: true,
+ font_size: :small,
+ **system_arguments)
super
@work_package = work_package
@font_size = font_size
+ @show_project = show_project
+ @show_subject = show_subject
+ @show_status = show_status
+
+ @system_arguments = system_arguments
end
end
diff --git a/app/contracts/groups/base_contract.rb b/app/contracts/groups/base_contract.rb
index 9b222968645..c54b69527a1 100644
--- a/app/contracts/groups/base_contract.rb
+++ b/app/contracts/groups/base_contract.rb
@@ -38,9 +38,9 @@ module Groups
attribute :name
attribute :lastname
attribute :parent_id
- attribute :organizational_unit
validate :validate_unique_users
+ validate :validate_users_not_in_other_department
private
@@ -53,5 +53,25 @@ module Groups
errors.add(:group_users, :taken)
end
end
+
+ def validate_users_not_in_other_department
+ return unless model.organizational_unit?
+
+ new_user_ids = model.group_users.select(&:new_record?).map(&:user_id)
+ return if new_user_ids.empty?
+
+ users_already_in_departments(new_user_ids).each do |user_id, department_id|
+ errors.add(:group_users, :user_already_in_department, user_id:, department_id:)
+ end
+ end
+
+ def users_already_in_departments(user_ids)
+ GroupUser
+ .joins(:group)
+ .merge(Group.organizational_units)
+ .where(user_id: user_ids)
+ .where.not(group_id: model.id)
+ .pluck(:user_id, :group_id)
+ end
end
end
diff --git a/app/contracts/groups/create_contract.rb b/app/contracts/groups/create_contract.rb
index fbb3c6fda7b..c3842bc1340 100644
--- a/app/contracts/groups/create_contract.rb
+++ b/app/contracts/groups/create_contract.rb
@@ -31,6 +31,7 @@
module Groups
class CreateContract < BaseContract
attribute :type
+ attribute :organizational_unit
validate :type_is_group
diff --git a/app/contracts/projects/base_contract.rb b/app/contracts/projects/base_contract.rb
index cbd84a3b725..ab0828a070c 100644
--- a/app/contracts/projects/base_contract.rb
+++ b/app/contracts/projects/base_contract.rb
@@ -122,7 +122,7 @@ module Projects
end
def manage_permission
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def with_unchanged_id
diff --git a/app/contracts/shares/base_contract.rb b/app/contracts/shares/base_contract.rb
index 2862511e740..cb76bd2546d 100644
--- a/app/contracts/shares/base_contract.rb
+++ b/app/contracts/shares/base_contract.rb
@@ -48,7 +48,7 @@ module Shares
end
def user_allowed_to_manage?
- raise NotImplementedError, "Must be overridden by subclass"
+ raise SubclassResponsibilityError
end
def single_non_inherited_role
@@ -76,7 +76,7 @@ module Shares
end
def assignable_role_class
- raise NotImplementedError, "Must be overridden by subclass"
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/contracts/users/update_contract.rb b/app/contracts/users/update_contract.rb
index 98ae032c688..993e1b3b0bd 100644
--- a/app/contracts/users/update_contract.rb
+++ b/app/contracts/users/update_contract.rb
@@ -32,6 +32,7 @@ module Users
class UpdateContract < BaseContract
validate :user_allowed_to_update
validate :at_least_one_admin_is_active
+ validate :user_limit_not_exceeded
##
# Users can only be updated when
@@ -60,6 +61,12 @@ module Users
end
end
+ def user_limit_not_exceeded
+ if activating_user? && OpenProject::Enterprise.user_limit_reached?
+ errors.add :base, :user_limit_reached
+ end
+ end
+
def editing_themself?
user == model
end
@@ -69,5 +76,9 @@ module Users
def can_manage_user?
user.allowed_globally?(:manage_user) && (user.admin? || !model.admin?)
end
+
+ def activating_user?
+ model.status_changed? && model.active?
+ end
end
end
diff --git a/app/controllers/admin/custom_fields/hierarchy/items_base_controller.rb b/app/controllers/admin/custom_fields/hierarchy/items_base_controller.rb
index 87323c15a7b..d10bae6ee24 100644
--- a/app/controllers/admin/custom_fields/hierarchy/items_base_controller.rb
+++ b/app/controllers/admin/custom_fields/hierarchy/items_base_controller.rb
@@ -227,7 +227,7 @@ module Admin
end
def find_custom_field
- raise NotImplementedError, "SubclassResponsibility"
+ raise SubclassResponsibilityError
end
def find_active_item
diff --git a/app/controllers/admin/departments_controller.rb b/app/controllers/admin/departments_controller.rb
new file mode 100644
index 00000000000..0f69ef8c9dd
--- /dev/null
+++ b/app/controllers/admin/departments_controller.rb
@@ -0,0 +1,270 @@
+# 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 Admin
+ class DepartmentsController < ::ApplicationController
+ include OpTurbo::ComponentStream
+ include GroupsHelper
+
+ layout :admin_or_frame_layout
+
+ menu_item :departments
+
+ # TODO: We will check for users permission here
+ before_action :require_admin
+ before_action :find_group,
+ only: %i[show edit new_user add_user remove_user update destroy change_parent_dialog change_parent
+ create_memberships edit_membership destroy_membership]
+
+ def index
+ @groups = Group.with_detail.organizational_units.visible.order(:lastname)
+ end
+
+ def new_user
+ @groups = Group.with_detail.organizational_units.visible.order(:lastname)
+ @add_user = true
+ render action: :index
+ end
+
+ def add_user # rubocop:disable Metrics/AbcSize
+ result = ::Departments::AddUserService
+ .new(@group, user: current_user)
+ .call(
+ user_id: params[:user_id],
+ remove_from_previous_department: params[:remove_from_previous_department] == "true"
+ )
+
+ if result.success?
+ flash[:notice] = I18n.t("departments.flash.user_added")
+ redirect_to admin_department_path(@group), status: :see_other
+ elsif result.result.is_a?(Group)
+ respond_with_dialog(
+ Admin::Departments::MoveUserDialogComponent.new(
+ user: User.find(params[:user_id]),
+ from_department: result.result,
+ to_department: @group
+ )
+ )
+ else
+ flash[:error] = result.errors.full_messages.join("\n")
+ redirect_to admin_department_path(@group), status: :see_other
+ end
+ end
+
+ def new_department
+ @group = Group.visible.with_detail.organizational_units.find(params[:parent_id]) if params[:parent_id].present?
+ @groups = Group.with_detail.organizational_units.visible.order(:lastname)
+ @add_subgroup = true
+ render action: :index
+ end
+
+ def add_department
+ service_call = ::Groups::CreateService
+ .new(user: current_user)
+ .call(permitted_params.group.merge(organizational_unit: true))
+
+ respond_department_created(service_call)
+ end
+
+ def remove_user
+ service_call = ::Groups::UpdateService
+ .new(user: current_user, model: @group)
+ .call(remove_user_ids: [params[:user_id]])
+
+ if service_call.success?
+ flash[:notice] = I18n.t("departments.flash.user_removed")
+ else
+ flash[:error] = service_call.errors.full_messages.join("\n")
+ end
+ redirect_to admin_department_path(@group), status: :see_other
+ end
+
+ def change_parent_dialog
+ departments = Group.with_detail.organizational_units.visible.order(:lastname)
+ respond_with_dialog(
+ Admin::Departments::ChangeParentDialogComponent.new(department: @group, departments:)
+ )
+ end
+
+ def change_parent
+ new_parent_id = parse_new_parent_id(params[:new_parent_id])
+ service_call = ::Groups::UpdateService
+ .new(user: current_user, model: @group)
+ .call(parent_id: new_parent_id)
+
+ respond_parent_changed(service_call)
+ end
+
+ def edit_organization_name
+ replace_via_turbo_stream(component: Admin::Departments::OrganizationNameFormComponent.new)
+ respond_with_turbo_streams
+ end
+
+ def cancel_edit_organization_name
+ replace_via_turbo_stream(component: Admin::Departments::OrganizationNameComponent.new)
+ respond_with_turbo_streams
+ end
+
+ def update_organization_name
+ ::Settings::UpdateService
+ .new(user: current_user)
+ .call(organization_name: params[:organization_name])
+
+ replace_via_turbo_stream(component: Admin::Departments::OrganizationNameComponent.new)
+ respond_with_turbo_streams
+ end
+
+ # old groups interface that we adapted for departments.
+
+ def show
+ @groups = Group.with_detail.organizational_units.visible.order(:lastname)
+ render action: :index
+ end
+
+ def edit; end
+
+ def update
+ service_call = ::Groups::UpdateService
+ .new(user: current_user, model: @group)
+ .call(permitted_params.group)
+
+ if service_call.success?
+ flash[:notice] = I18n.t(:notice_successful_update)
+ redirect_to edit_admin_department_path(@group), status: :see_other
+ else
+ render action: :edit, status: :unprocessable_entity
+ end
+ end
+
+ def destroy
+ redirect_target = @group.parent
+
+ ::Groups::DeleteService
+ .new(user: current_user, model: @group)
+ .call
+
+ flash[:info] = I18n.t(:notice_deletion_scheduled)
+ redirect_to redirect_target ? admin_department_path(redirect_target) : admin_departments_path, status: :see_other
+ end
+
+ def create_memberships
+ membership_params = permitted_params.group_membership[:membership]
+
+ service_call = ::Members::CreateService
+ .new(user: current_user)
+ .call(membership_params.merge(principal: @group))
+
+ respond_membership_altered(service_call)
+ end
+
+ def edit_membership
+ membership_params = permitted_params.group_membership
+
+ @membership = Member.find(membership_params[:membership_id])
+
+ service_call = ::Members::UpdateService
+ .new(model: @membership, user: current_user)
+ .call(membership_params[:membership])
+
+ respond_membership_altered(service_call)
+ end
+
+ def destroy_membership
+ member = Member.find(params[:membership_id])
+ ::Members::DeleteService
+ .new(model: member, user: current_user)
+ .call
+
+ flash[:notice] = I18n.t(:notice_successful_delete)
+ redirect_to edit_admin_department_path(@group, tab: redirected_to_tab(member)), status: :see_other
+ end
+
+ private
+
+ def admin_or_frame_layout
+ return "turbo_rails/frame" if turbo_frame_request?
+
+ "admin"
+ end
+
+ def redirect_target_for(department)
+ department.parent || department
+ end
+
+ def find_group
+ @group = Group.visible.organizational_units.includes(:members, :users, :group_detail).find(params[:id])
+ end
+
+ def parse_new_parent_id(input)
+ return nil if input.blank?
+
+ value = MultiJson.load(Array(input).first, symbolize_keys: true)[:value]
+ value.presence
+ end
+
+ def respond_parent_changed(service_call)
+ if service_call.success?
+ flash[:notice] = I18n.t(:notice_successful_update)
+ redirect_to admin_department_path(service_call.result.parent || service_call.result), status: :see_other
+ else
+ flash[:error] = service_call.errors.full_messages.join("\n")
+ redirect_to admin_department_path(@group), status: :see_other
+ end
+ end
+
+ def respond_department_created(service_call)
+ if service_call.success?
+ flash[:notice] = I18n.t("departments.flash.department_created")
+ redirect_to admin_department_path(redirect_target_for(service_call.result)), status: :see_other
+ else
+ flash[:error] = service_call.errors.full_messages.join("\n")
+ redirect_back_or_to(admin_departments_path)
+ end
+ end
+
+ def respond_membership_altered(service_call)
+ if service_call.success?
+ flash[:notice] = I18n.t(:notice_successful_update)
+ else
+ flash[:error] = service_call.errors.full_messages.join("\n")
+ end
+
+ redirect_to edit_admin_department_path(@group, tab: redirected_to_tab(service_call.result))
+ end
+
+ def redirected_to_tab(membership)
+ if membership.project
+ "memberships"
+ else
+ "global_roles"
+ end
+ end
+ end
+end
diff --git a/app/controllers/admin/settings/enumerations_controller_base.rb b/app/controllers/admin/settings/enumerations_controller_base.rb
index f1d9ff93623..c3346c8baf1 100644
--- a/app/controllers/admin/settings/enumerations_controller_base.rb
+++ b/app/controllers/admin/settings/enumerations_controller_base.rb
@@ -136,7 +136,7 @@ module Admin
end
def enumeration_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def enumeration_permitted_params
diff --git a/app/controllers/admin/settings/work_packages_identifier_controller.rb b/app/controllers/admin/settings/work_packages_identifier_controller.rb
index 1e4ecbb008f..a7ec6be5294 100644
--- a/app/controllers/admin/settings/work_packages_identifier_controller.rb
+++ b/app/controllers/admin/settings/work_packages_identifier_controller.rb
@@ -39,21 +39,14 @@ module Admin::Settings
end
def show
- @form_state = WorkPackages::IdentifierAutofix.job_in_progress? ? :change_in_progress : :edit
+ @form_state = ProjectIdentifiers::IdentifierAutofix.job_in_progress? ? :change_in_progress : :edit
end
def update
- return render_400 unless params[:settings]
-
- if autofix_requested?
- call = update_service.new(user: current_user).call(settings_params)
- call.on_success do
- WorkPackages::IdentifierAutofix::ApplyHandlesJob.perform_later
- redirect_to action: "show"
- end
- call.on_failure { failure_callback(call) }
- else
- super
+ case params.dig(:settings, :work_packages_identifier)
+ when Setting::WorkPackageIdentifier::SEMANTIC then switch_to_semantic
+ when Setting::WorkPackageIdentifier::CLASSIC then switch_to_classic
+ else render_400
end
end
@@ -62,7 +55,7 @@ module Admin::Settings
end
def status
- if WorkPackages::IdentifierAutofix.job_in_progress?
+ if ProjectIdentifiers::IdentifierAutofix.job_in_progress?
head :no_content
else
replace_via_turbo_stream(
@@ -74,12 +67,27 @@ module Admin::Settings
private
+ def switch_to_semantic
+ unless ProjectIdentifiers::IdentifierAutofix.job_in_progress?
+ ProjectIdentifiers::ConvertInstanceToSemanticIdsJob.perform_later
+ end
+ redirect_to action: "show"
+ end
+
+ def switch_to_classic
+ call = update_service.new(user: current_user)
+ .call(work_packages_identifier: Setting::WorkPackageIdentifier::CLASSIC)
+ call.on_success do
+ unless ProjectIdentifiers::IdentifierAutofix.job_in_progress?
+ ProjectIdentifiers::RevertInstanceToClassicIdsJob.perform_later
+ end
+ redirect_to action: "show"
+ end
+ call.on_failure { failure_callback(call) }
+ end
+
def check_feature_flag
render_404 unless OpenProject::FeatureDecisions.semantic_work_package_ids_active?
end
-
- def autofix_requested?
- ActiveRecord::Type::Boolean.new.cast(params[:confirm_dangerous_action])
- end
end
end
diff --git a/app/controllers/concerns/custom_fields/attribute_help_text_actions.rb b/app/controllers/concerns/custom_fields/attribute_help_text_actions.rb
index 125eee405be..f5d036f8661 100644
--- a/app/controllers/concerns/custom_fields/attribute_help_text_actions.rb
+++ b/app/controllers/concerns/custom_fields/attribute_help_text_actions.rb
@@ -51,11 +51,11 @@ module CustomFields
end
def show_path
- raise NotImplementedError, "#{self.class} must implement #show_path"
+ raise SubclassResponsibilityError, "#{self.class} must implement #show_path"
end
def render_attribute_help_text_form(status: :ok)
- raise NotImplementedError, "#{self.class} must implement #render_attribute_help_text_form"
+ raise SubclassResponsibilityError, "#{self.class} must implement #render_attribute_help_text_form"
end
def find_or_initialize_attribute_help_text
diff --git a/app/controllers/concerns/notifications/notification_settings_actions.rb b/app/controllers/concerns/notifications/notification_settings_actions.rb
new file mode 100644
index 00000000000..a96d0c74fe6
--- /dev/null
+++ b/app/controllers/concerns/notifications/notification_settings_actions.rb
@@ -0,0 +1,153 @@
+# 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 Notifications
+ module NotificationSettingsActions
+ extend ActiveSupport::Concern
+
+ included do
+ include OpTurbo::ComponentStream
+ end
+
+ def update_workdays
+ call = ::Users::UpdateService.new(model: @user, user: current_user).call(pref: workdays_pref_params)
+ flash[call.success? ? :notice : :error] = update_service_flash_message(call)
+ redirect_back_or_to(workdays_redirect_path)
+ end
+
+ def new_project_settings
+ respond_with_dialog My::Notifications::ProjectSettingsDialogComponent.new(
+ user: @user,
+ form_url: project_notifications_create_url
+ )
+ end
+
+ def create_project_settings
+ update_project_notification_setting
+ redirect_back_or_to(notifications_settings_path)
+ rescue ActiveRecord::RecordNotFound
+ flash[:error] = t(:notice_bad_request)
+ redirect_back_or_to(notifications_settings_path)
+ end
+
+ def edit_project_settings
+ setting = @user.notification_settings.find_by!(project_id: params[:project_id])
+ respond_with_dialog My::Notifications::ProjectSettingsDialogComponent.new(
+ user: @user,
+ notification_setting: setting,
+ form_url: project_setting_form_url(setting.project_id)
+ )
+ end
+
+ def update_project_settings
+ update_project_notification_setting(params[:project_id])
+ redirect_back_or_to(notifications_settings_path)
+ rescue ActiveRecord::RecordNotFound
+ flash[:error] = t(:notice_bad_request)
+ redirect_back_or_to(notifications_settings_path)
+ end
+
+ def destroy_project_settings
+ @user.notification_settings.find_by!(project_id: params[:project_id]).destroy!
+ flash[:notice] = I18n.t(:notice_successful_delete)
+ redirect_back_or_to(notifications_settings_path)
+ rescue ActiveRecord::RecordNotFound
+ flash[:error] = t(:notice_bad_request)
+ redirect_back_or_to(notifications_settings_path)
+ end
+
+ private
+
+ def update_project_notification_setting(project_id = params.dig(:notification_setting, :project_id))
+ project = Project.find(project_id)
+ setting = @user.notification_settings.find_or_initialize_by(project:)
+ persist_notification_setting(setting, project_notification_params)
+ end
+
+ def persist_notification_setting(setting, update_params)
+ if setting.update(update_params)
+ flash[:notice] = I18n.t(:notice_successful_update)
+ else
+ flash[:error] = I18n.t(:notice_failed_to_save_messages,
+ count: setting.errors.count,
+ object: setting.class.model_name.human)
+ end
+ end
+
+ def project_notification_params
+ permitted_params.notification_setting_project.except(:project_id).merge(build_date_alerts_params)
+ end
+
+ def build_date_alerts_params
+ ns_params = params.fetch(:notification_setting, {})
+ {
+ start_date: date_alert_value(ns_params, :start_date),
+ due_date: date_alert_value(ns_params, :due_date),
+ overdue: date_alert_value(ns_params, :overdue)
+ }
+ end
+
+ def workdays_pref_params
+ pref_params = permitted_params.pref.to_h
+ pref_params.merge("workdays" => pref_params.fetch("workdays", []))
+ end
+
+ def update_service_flash_message(call)
+ if call.success?
+ I18n.t(:notice_successful_update)
+ else
+ call.errors.full_messages.join(", ")
+ end
+ end
+
+ def date_alert_value(ns_params, field)
+ return nil unless ns_params["#{field}_active"] == "1"
+
+ ns_params[field.to_s].presence&.to_i
+ end
+
+ # To be implemented by the including controller
+ def notifications_settings_path
+ raise SubclassResponsibilityError
+ end
+
+ def workdays_redirect_path
+ raise SubclassResponsibilityError
+ end
+
+ def project_notifications_create_url
+ raise SubclassResponsibilityError
+ end
+
+ def project_setting_form_url(_project_id)
+ raise SubclassResponsibilityError
+ end
+ end
+end
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 676366dcb8d..76fb9fa2302 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -40,7 +40,7 @@ class GroupsController < ApplicationController
edit_membership add_users]
def index
- @groups = Group.in_tree_order
+ @groups = Group.with_detail.not_organizational_units.in_tree_order
end
def show
diff --git a/app/controllers/my_controller.rb b/app/controllers/my_controller.rb
index 290fba911ac..c226fe18129 100644
--- a/app/controllers/my_controller.rb
+++ b/app/controllers/my_controller.rb
@@ -34,6 +34,7 @@ class MyController < ApplicationController
include ActionView::Helpers::TagHelper
include OpTurbo::ComponentStream
include FlashMessagesOutputSafetyHelper
+ include Notifications::NotificationSettingsActions
layout "my"
@@ -46,20 +47,28 @@ class MyController < ApplicationController
:locale,
:interface,
:update_settings,
+ :update_workdays,
+ :update_email_alerts,
+ :update_participating,
+ :update_non_participating,
+ :update_date_alerts,
:password,
:change_password,
:password_confirmation_dialog,
:notifications,
- :reminders,
:non_working_times,
- :working_hours
+ :working_hours,
+ :new_project_settings,
+ :create_project_settings,
+ :edit_project_settings,
+ :update_project_settings,
+ :destroy_project_settings
menu_item :account, only: [:account]
menu_item :locale, only: [:locale]
menu_item :interface, only: [:interface]
menu_item :password, only: [:password]
menu_item :notifications, only: [:notifications]
- menu_item :reminders, only: [:reminders]
menu_item :working_hours, only: %i[working_hours non_working_times]
def account; end
@@ -74,6 +83,22 @@ class MyController < ApplicationController
write_settings
end
+ def update_email_alerts
+ update_global_notification_setting(permitted_params.notification_setting_email_alerts)
+ end
+
+ def update_participating
+ update_global_notification_setting(permitted_params.notification_setting_participating)
+ end
+
+ def update_non_participating
+ update_global_notification_setting(permitted_params.notification_setting_non_participating)
+ end
+
+ def update_date_alerts
+ update_global_notification_setting(build_date_alerts_params)
+ end
+
def interface; end
# Manage user's password
@@ -93,11 +118,10 @@ class MyController < ApplicationController
respond_with_dialog My::PasswordConfirmationDialog.new
end
- # Configure user's in app notifications
- def notifications; end
-
- # Configure user's mail reminders
- def reminders; end
+ # Configure user's notifications and email reminders
+ def notifications
+ set_global_notification_setting
+ end
def working_hours
render_403 unless OpenProject::FeatureDecisions.user_working_times_active?
@@ -164,6 +188,24 @@ class MyController < ApplicationController
permitted_params.user.to_h.merge(params.permit(pref: {}))
end
+ def update_global_notification_setting(update_params)
+ set_global_notification_setting
+ persist_notification_setting(@global_notification_setting, update_params)
+ redirect_back_or_to(my_notifications_path)
+ end
+
+ def set_global_notification_setting
+ @global_notification_setting = @user.notification_settings.find_or_initialize_by(project: nil)
+ end
+
+ def persist_notification_setting(setting, update_params)
+ if setting.update(update_params)
+ flash[:notice] = notice_account_updated
+ else
+ flash[:error] = error_account_update_failed(nil)
+ end
+ end
+
def notice_account_updated
OpenProject::LocaleHelper.with_locale_for(current_user) do
t(:notice_account_updated)
@@ -175,6 +217,22 @@ class MyController < ApplicationController
[t(:notice_account_update_failed), errors]
end
+ def notifications_settings_path
+ my_notifications_path
+ end
+
+ def workdays_redirect_path
+ my_notifications_path
+ end
+
+ def project_notifications_create_url
+ my_project_notifications_path
+ end
+
+ def project_setting_form_url(project_id)
+ my_project_setting_path(project_id:)
+ end
+
def set_current_user
@user = current_user
end
diff --git a/app/controllers/scim_v2/base_controller_actions.rb b/app/controllers/scim_v2/base_controller_actions.rb
index 01b3448478c..0617022889d 100644
--- a/app/controllers/scim_v2/base_controller_actions.rb
+++ b/app/controllers/scim_v2/base_controller_actions.rb
@@ -38,15 +38,9 @@ module ScimV2
rescue_from "ActiveRecord::RecordNotFound", with: :handle_resource_not_found
def index
- query = if params[:filter].blank?
- storage_scope
- else
- attribute_map = storage_class.new.scim_queryable_attributes
- parser = ::Scimitar::Lists::QueryParser.new(attribute_map)
-
- parser.parse(params[:filter])
- parser.to_activerecord_query(storage_scope)
- end
+ # Applies .distinct to avoid duplicate records caused by
+ # left_joins in storage_scope (e.g. groups, auth provider links).
+ query = scim_index_storage_query.distinct
pagination_info = scim_pagination_info(query.count)
page_of_results = query
@@ -75,19 +69,37 @@ module ScimV2
private
- def include_attributes
- first_level_attrs = storage_class.scim_attributes_map.keys.map(&:to_s)
- second_level_attrs =
- storage_class
- .scim_attributes_map
- .find_all { |_, v| v.is_a? Hash }
- .flat_map { |parent, childs| childs.map { |child, _| "#{parent}.#{child}" } }
- all_possible_attributes = (first_level_attrs + second_level_attrs)
+ # Builds the base query for the SCIM index action,
+ # applying any SCIM filter params if present.
+ def scim_index_storage_query
+ return storage_scope if params[:filter].blank?
+ # Returns the list of SCIM attributes to include in the response,
+ # excluding any attributes specified in the excludedAttributes param.
+ attribute_map = storage_class.new.scim_queryable_attributes
+ parser = ::Scimitar::Lists::QueryParser.new(attribute_map)
+
+ parser.parse(params[:filter])
+ parser.to_activerecord_query(storage_scope)
+ end
+
+ def include_attributes
+ # Collects all possible SCIM attribute names (top-level and nested)
+ # from the storage class's scim_attributes_map.
excluded_attributes = params.fetch(:excludedAttributes, "").split(",")
excluded_parents = excluded_attributes.filter_map { |attr| attr.split(".")[-2] }
- all_possible_attributes - excluded_attributes - excluded_parents
+ scim_all_attribute_names - excluded_attributes - excluded_parents
+ end
+
+ def scim_all_attribute_names
+ map = storage_class.scim_attributes_map
+ nested =
+ map
+ .find_all { |_, v| v.is_a? Hash }
+ .flat_map { |parent, childs| childs.map { |child, _| "#{parent}.#{child}" } }
+
+ map.keys.map(&:to_s) + nested
end
def raise_result_errors_for_scim(result)
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 01f21d2bb2e..b54d615a889 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -31,19 +31,33 @@
class UsersController < ApplicationController
include OpTurbo::ComponentStream
include WorkingTimesAuthorization
+ include Notifications::NotificationSettingsActions
layout "admin"
before_action :authorize_global, except: %i[show deletion_info destroy]
+ # rubocop:disable Rails/LexicallyScopedActionFilter
before_action :find_user, only: %i[show
edit
update
+ update_reminders
+ update_workdays
+ update_email_alerts
+ update_participating
+ update_non_participating
+ update_date_alerts
+ new_project_settings
+ create_project_settings
+ edit_project_settings
+ update_project_settings
+ destroy_project_settings
change_status_info
change_status
destroy
deletion_info
resend_invitation]
+ # rubocop:enable Rails/LexicallyScopedActionFilter
# should also contain destroy but post data can not be redirected
before_action :require_login, only: [:deletion_info]
before_action :authorize_for_user, only: [:destroy]
@@ -109,6 +123,30 @@ class UsersController < ApplicationController
end
end
+ def update_email_alerts
+ global_setting = @user.notification_settings.find_or_initialize_by(project: nil)
+ persist_notification_setting(global_setting, permitted_params.notification_setting_email_alerts)
+ redirect_back_or_to edit_user_path(@user, tab: "reminders")
+ end
+
+ def update_reminders
+ call = ::Users::UpdateService.new(model: @user, user: current_user).call(pref: permitted_params.pref.to_h)
+ flash[call.success? ? :notice : :error] = update_service_flash_message(call)
+ redirect_back_or_to edit_user_path(@user, tab: "reminders")
+ end
+
+ def update_participating
+ update_user_notification_setting(permitted_params.notification_setting_participating)
+ end
+
+ def update_non_participating
+ update_user_notification_setting(permitted_params.notification_setting_non_participating)
+ end
+
+ def update_date_alerts
+ update_user_notification_setting(build_date_alerts_params)
+ end
+
def update # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
update_params = build_user_update_params
call = ::Users::UpdateService.new(model: @user, user: current_user).call(update_params)
@@ -261,6 +299,28 @@ class UsersController < ApplicationController
private
+ def update_user_notification_setting(update_params)
+ global_setting = @user.notification_settings.find_or_initialize_by(project: nil)
+ persist_notification_setting(global_setting, update_params)
+ redirect_back_or_to edit_user_path(@user, tab: "notifications")
+ end
+
+ def notifications_settings_path
+ edit_user_path(@user, tab: "notifications")
+ end
+
+ def workdays_redirect_path
+ edit_user_path(@user, tab: "reminders")
+ end
+
+ def project_notifications_create_url
+ project_notifications_user_path(@user)
+ end
+
+ def project_setting_form_url(project_id)
+ project_setting_user_path(@user, project_id:)
+ end
+
def can_show_user?
return true if can_manage_or_create_users?
return true if @user == User.current
diff --git a/app/controllers/work_packages/bulk_controller.rb b/app/controllers/work_packages/bulk_controller.rb
index e281c2b4c10..2393cff6737 100644
--- a/app/controllers/work_packages/bulk_controller.rb
+++ b/app/controllers/work_packages/bulk_controller.rb
@@ -38,6 +38,18 @@ class WorkPackages::BulkController < ApplicationController
include QueriesHelper
include WorkPackages::BulkErrorMessage
+ include OpTurbo::ComponentStream
+
+ def delete_dialog
+ component =
+ if @work_packages.one?
+ WorkPackages::DeleteDialogComponent.new(work_package: @work_packages.first, back_url: params[:back_url])
+ else
+ WorkPackages::BulkDeleteDialogComponent.new(work_packages: @work_packages, back_url: params[:back_url])
+ end
+
+ respond_with_dialog component
+ end
def edit
setup_edit
@@ -70,20 +82,21 @@ class WorkPackages::BulkController < ApplicationController
end
end
- def destroy
+ def destroy # rubocop:disable Metrics/AbcSize
if WorkPackage.cleanup_associated_before_destructing_if_required(@work_packages, current_user, params[:to_do])
destroy_work_packages(@work_packages)
respond_to do |format|
format.html do
- redirect_to (project_work_packages_path(@work_packages.first.project))
+ redirect_back_or_default(project_work_packages_path(@work_packages.first.project),
+ status: :see_other)
end
format.json do
head :ok
end
end
else
- redirect_to(action: :reassign, ids: @work_packages.map(&:id))
+ redirect_to(action: :reassign, ids: @work_packages.map(&:id), back_url: params[:back_url])
end
end
diff --git a/app/controllers/work_packages/moves_controller.rb b/app/controllers/work_packages/moves_controller.rb
index 861e3c0dd59..15b0a3fad29 100644
--- a/app/controllers/work_packages/moves_controller.rb
+++ b/app/controllers/work_packages/moves_controller.rb
@@ -33,7 +33,8 @@ class WorkPackages::MovesController < ApplicationController
default_search_scope :work_packages
before_action :find_work_packages, :check_project_uniqueness
- before_action :authorize
+ before_action :authorize_move_or_copy
+ authorization_checked! :new, :create
def new
prepare_for_work_package_move
@@ -47,6 +48,11 @@ class WorkPackages::MovesController < ApplicationController
private
+ def authorize_move_or_copy
+ permission = params.has_key?(:copy) ? :copy_work_packages : :move_work_packages
+ do_authorize(permission)
+ end
+
def perform_operation
if within_frontend_treshold?
perform_in_frontend
diff --git a/app/forms/admin/settings/external_links_settings_form.rb b/app/forms/admin/settings/external_links_settings_form.rb
index 5aa54f233f0..1b26481695b 100644
--- a/app/forms/admin/settings/external_links_settings_form.rb
+++ b/app/forms/admin/settings/external_links_settings_form.rb
@@ -32,6 +32,8 @@ module Admin
module Settings
class ExternalLinksSettingsForm < ApplicationForm
settings_form do |sf|
+ helpers.call_hook(:component_admin_settings_external_redirect, form: sf)
+
sf.check_box(
name: :capture_external_links,
caption: I18n.t(:setting_capture_external_links_text)
diff --git a/app/forms/admin/settings/general_settings_form.rb b/app/forms/admin/settings/general_settings_form.rb
index a2ae499c254..a399108bba8 100644
--- a/app/forms/admin/settings/general_settings_form.rb
+++ b/app/forms/admin/settings/general_settings_form.rb
@@ -41,6 +41,11 @@ module Admin
input_width: :medium
)
+ sf.text_field(
+ name: :organization_name,
+ input_width: :medium
+ )
+
sf.text_field(
name: :per_page_options,
input_width: :medium
diff --git a/app/forms/custom_fields/custom_field_rendering.rb b/app/forms/custom_fields/custom_field_rendering.rb
index 8e5063e2991..ba2ef874492 100644
--- a/app/forms/custom_fields/custom_field_rendering.rb
+++ b/app/forms/custom_fields/custom_field_rendering.rb
@@ -69,7 +69,7 @@ module CustomFields::CustomFieldRendering
end
def custom_fields
- raise NotImplementedError, "#custom_fields method needs to be overwritten and provide all custom fields we want to show"
+ raise SubclassResponsibilityError, "#custom_fields needs to be overwritten and provide all custom fields we want to show"
end
private
diff --git a/app/forms/custom_fields/inputs/base/autocomplete/multi_value_input.rb b/app/forms/custom_fields/inputs/base/autocomplete/multi_value_input.rb
index 5317f2db92f..a635482ff44 100644
--- a/app/forms/custom_fields/inputs/base/autocomplete/multi_value_input.rb
+++ b/app/forms/custom_fields/inputs/base/autocomplete/multi_value_input.rb
@@ -49,7 +49,7 @@ class CustomFields::Inputs::Base::Autocomplete::MultiValueInput < CustomFields::
end
def decorated?
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def custom_values
diff --git a/app/forms/custom_fields/inputs/base/autocomplete/single_value_input.rb b/app/forms/custom_fields/inputs/base/autocomplete/single_value_input.rb
index ff38c99ea61..5a0466e2def 100644
--- a/app/forms/custom_fields/inputs/base/autocomplete/single_value_input.rb
+++ b/app/forms/custom_fields/inputs/base/autocomplete/single_value_input.rb
@@ -49,6 +49,6 @@ class CustomFields::Inputs::Base::Autocomplete::SingleValueInput < CustomFields:
end
def decorated?
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/app/forms/groups/form.rb b/app/forms/groups/form.rb
index b18a50f36b3..652baaabeb2 100644
--- a/app/forms/groups/form.rb
+++ b/app/forms/groups/form.rb
@@ -47,8 +47,7 @@ module Groups
caption: I18n.t(:label_parent_group_caption),
input_width: :medium
) do |list|
- excluded_ids = model.self_and_descendants.pluck(:id).to_set
- Group.in_tree_order.reject { |g| excluded_ids.include?(g.id) }.each do |group|
+ parent_candidates.each do |group|
prefix = "\u00A0\u00A0" * (group.hierarchy_depth || 0)
list.option(label: "#{prefix}#{group.name}", value: group.id, selected: model.parent_id == group.id)
end
@@ -75,5 +74,18 @@ module Groups
def custom_fields
model.available_custom_fields
end
+
+ def parent_candidates
+ @parent_candidates ||= begin
+ scope = if model.organizational_unit
+ Group.organizational_units
+ else
+ Group.not_organizational_units
+ end
+
+ excluded_ids = model.self_and_descendants.pluck(:id).to_set
+ scope.in_tree_order.reject { |group| excluded_ids.include?(group.id) }
+ end
+ end
end
end
diff --git a/app/forms/my/alerts_form.rb b/app/forms/my/alerts_form.rb
index c666a6ca054..7f7f4fe19e9 100644
--- a/app/forms/my/alerts_form.rb
+++ b/app/forms/my/alerts_form.rb
@@ -30,13 +30,15 @@
class My::AlertsForm < ApplicationForm
form do |f|
- f.check_box name: :warn_on_leaving_unsaved,
- label: I18n.t("activerecord.attributes.user_preference.warn_on_leaving_unsaved")
+ f.fieldset_group(title: helpers.t("activerecord.attributes.user_preference.header_alerts"), mt: 3) do |fg|
+ fg.check_box name: :warn_on_leaving_unsaved,
+ label: helpers.t("activerecord.attributes.user_preference.warn_on_leaving_unsaved")
- f.check_box name: :auto_hide_popups,
- label: I18n.t("activerecord.attributes.user_preference.auto_hide_popups"),
- caption: I18n.t("activerecord.attributes.user_preference.auto_hide_popups_caption")
+ fg.check_box name: :auto_hide_popups,
+ label: helpers.t("activerecord.attributes.user_preference.auto_hide_popups"),
+ caption: helpers.t("activerecord.attributes.user_preference.auto_hide_popups_caption")
- f.submit(name: :submit, label: I18n.t("activerecord.attributes.user_preference.button_update_alerts"), scheme: :default)
+ fg.submit(name: :submit, label: helpers.t("activerecord.attributes.user_preference.button_update_alerts"), scheme: :default)
+ end
end
end
diff --git a/app/forms/my/look_and_feel_form.rb b/app/forms/my/look_and_feel_form.rb
index 5d3904d930c..eccbe3c79ec 100644
--- a/app/forms/my/look_and_feel_form.rb
+++ b/app/forms/my/look_and_feel_form.rb
@@ -32,53 +32,55 @@ class My::LookAndFeelForm < ApplicationForm
include ApplicationHelper
form do |f|
- f.select_list(
- name: :theme,
- label: attribute_name(:theme),
- caption: attribute_name(:mode_guideline),
- required: true,
- include_blank: false,
- input_width: :small,
- data: {
- my__look_and_feel_target: "themeSelect",
- action: "my--look-and-feel#updateContrastOptions"
- }
- ) do |select|
- theme_options_for_select.each { |(label, value)| select.option(value:, label:) }
+ f.fieldset_group(title: helpers.t("activerecord.attributes.user_preference.header_look_and_feel")) do |fg|
+ fg.select_list(
+ name: :theme,
+ label: attribute_name(:theme),
+ caption: attribute_name(:mode_guideline),
+ required: true,
+ include_blank: false,
+ input_width: :small,
+ data: {
+ my__look_and_feel_target: "themeSelect",
+ action: "my--look-and-feel#updateContrastOptions"
+ }
+ ) do |select|
+ theme_options_for_select.each { |(label, value)| select.option(value:, label:) }
+ end
+
+ fg.check_box_group(data: { my__look_and_feel_target: "autoThemeContrast" }) do |group|
+ group.check_box name: :force_light_theme_contrast,
+ label: attribute_name(:force_light_theme_contrast),
+ caption: attribute_name(:force_light_theme_contrast_caption)
+ group.check_box name: :force_dark_theme_contrast,
+ label: attribute_name(:force_dark_theme_contrast),
+ caption: attribute_name(:force_dark_theme_contrast_caption)
+ end
+
+ fg.check_box_group(data: { my__look_and_feel_target: "singleThemeContrast" }) do |group|
+ group.check_box name: :increase_theme_contrast,
+ label: attribute_name(:increase_contrast),
+ caption: attribute_name(:increase_contrast_caption)
+ end
+
+ fg.select_list(
+ name: :comments_sorting,
+ label: attribute_name(:comments_sorting),
+ required: true,
+ include_blank: false,
+ input_width: :small
+ ) do |select|
+ comment_sort_order_options.each { |(label, value)| select.option(value:, label:) }
+ end
+
+ fg.check_box name: :disable_keyboard_shortcuts,
+ label: attribute_name(:disable_keyboard_shortcuts),
+ caption: disable_keyboard_shortcuts_caption
+
+ fg.submit(name: :submit,
+ label: attribute_name(:button_update_look_and_feel),
+ scheme: :default)
end
-
- f.check_box_group(data: { my__look_and_feel_target: "autoThemeContrast" }) do |group|
- group.check_box name: :force_light_theme_contrast,
- label: attribute_name(:force_light_theme_contrast),
- caption: attribute_name(:force_light_theme_contrast_caption)
- group.check_box name: :force_dark_theme_contrast,
- label: attribute_name(:force_dark_theme_contrast),
- caption: attribute_name(:force_dark_theme_contrast_caption)
- end
-
- f.check_box_group(data: { my__look_and_feel_target: "singleThemeContrast" }) do |group|
- group.check_box name: :increase_theme_contrast,
- label: attribute_name(:increase_contrast),
- caption: attribute_name(:increase_contrast_caption)
- end
-
- f.select_list(
- name: :comments_sorting,
- label: attribute_name(:comments_sorting),
- required: true,
- include_blank: false,
- input_width: :small
- ) do |select|
- comment_sort_order_options.each { |(label, value)| select.option(value:, label:) }
- end
-
- f.check_box name: :disable_keyboard_shortcuts,
- label: attribute_name(:disable_keyboard_shortcuts),
- caption: disable_keyboard_shortcuts_caption
-
- f.submit(name: :submit,
- label: attribute_name(:button_update_look_and_feel),
- scheme: :default)
end
private
diff --git a/app/forms/my/notifications/date_alerts_form.rb b/app/forms/my/notifications/date_alerts_form.rb
new file mode 100644
index 00000000000..8dee7a1f60d
--- /dev/null
+++ b/app/forms/my/notifications/date_alerts_form.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Notifications::DateAlertsForm < ApplicationForm
+ START_DUE_TIMES = %w[0 1 3 7].freeze
+ OVERDUE_TIMES = %w[1 3 7].freeze
+
+ def initialize(show_submit: true)
+ super()
+ @show_submit = show_submit
+ end
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.notifications.date_alerts.title"), mt: 3) do |fg|
+ %i[start_date due_date].each do |field|
+ active = model.send(:"#{field}_active")
+
+ fg.check_box(
+ name: :"#{field}_active",
+ label: helpers.t("my_account.notifications.date_alerts.#{field}"),
+ id: "op-notification-type-#{field}-date-active--#{SecureRandom.uuid}}",
+ data: {
+ show_when_checked_target: "cause",
+ target_name: field.to_s,
+ test_selector: "global-notification-type-op-settings-#{field}-date-active"
+ }
+ ) do |cb|
+ cb.nested_form(
+ classes: [{ "d-none" => !active }],
+ data: {
+ show_when_checked_target: "effect",
+ target_name: field.to_s,
+ show_when: "checked"
+ }
+ ) do |builder|
+ TimeSelectForm.new(builder, field:, times: START_DUE_TIMES)
+ end
+ end
+ end
+
+ active_overdue = model.overdue_active
+
+ fg.check_box(
+ name: :overdue_active,
+ label: helpers.t("my_account.notifications.date_alerts.overdue"),
+ id: "op-notification-type-overdue-date-active--#{SecureRandom.uuid}}",
+ data: {
+ show_when_checked_target: "cause",
+ target_name: "overdue",
+ test_selector: "global-notification-type-op-settings-overdue-date-active"
+ }
+ ) do |cb|
+ cb.nested_form(
+ classes: [{ "d-none" => !active_overdue }],
+ data: {
+ show_when_checked_target: "effect",
+ target_name: "overdue",
+ show_when: "checked"
+ }
+ ) do |builder|
+ TimeSelectForm.new(builder, field: :overdue, times: OVERDUE_TIMES)
+ end
+ end
+
+ if @show_submit
+ fg.submit(name: :submit, label: helpers.t("my_account.notifications.date_alerts.submit_button"),
+ scheme: :default)
+ end
+ end
+ end
+
+ class TimeSelectForm < ApplicationForm
+ def initialize(field:, times:)
+ super()
+ @field = field
+ @times = times
+ end
+
+ form do |f|
+ f.select_list(
+ name: @field,
+ label: helpers.t("my_account.notifications.date_alerts.#{@field}"),
+ visually_hide_label: true,
+ input_width: :xsmall,
+ data: { test_selector: "global-notification-type-op-reminder-settings-#{@field.to_s.underscore}-alerts" }
+ ) do |list|
+ @times.each do |value|
+ list.option(
+ label: helpers.t("my_account.notifications.date_alerts.times.#{time_key(value)}"),
+ value:
+ )
+ end
+ end
+ end
+
+ private
+
+ def time_key(value)
+ case value
+ when "0" then "same_day"
+ when "1" then @field == :overdue ? "one_day_after" : "one_day_before"
+ when "3" then @field == :overdue ? "three_days_after" : "three_days_before"
+ when "7" then @field == :overdue ? "seven_days_after" : "seven_days_before"
+ end
+ end
+ end
+end
diff --git a/app/forms/my/notifications/non_participating_form.rb b/app/forms/my/notifications/non_participating_form.rb
new file mode 100644
index 00000000000..beed3dd9bc7
--- /dev/null
+++ b/app/forms/my/notifications/non_participating_form.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Notifications::NonParticipatingForm < ApplicationForm
+ def initialize(show_submit: true)
+ super()
+ @show_submit = show_submit
+ end
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.notifications.non_participating.title"), mt: 3) do |fg|
+ NotificationSetting.non_participating_settings.each do |setting|
+ fg.check_box(
+ name: setting,
+ label: helpers.t("my_account.notifications.non_participating.#{setting}"),
+ data: { test_selector: "global-notification-type-#{setting}" },
+ id: "op-notification-type-#{setting}--#{SecureRandom.uuid}}"
+ )
+ end
+
+ if @show_submit
+ fg.submit(name: :submit, label: helpers.t("my_account.notifications.non_participating.submit_button"),
+ scheme: :default)
+ end
+ end
+ end
+end
diff --git a/app/forms/my/notifications/participating_form.rb b/app/forms/my/notifications/participating_form.rb
new file mode 100644
index 00000000000..6d6a25ce84a
--- /dev/null
+++ b/app/forms/my/notifications/participating_form.rb
@@ -0,0 +1,78 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Notifications::ParticipatingForm < ApplicationForm
+ def initialize(show_submit: true)
+ super()
+ @show_submit = show_submit
+ end
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.notifications.participating.title"), mt: 2) do |fg|
+ fg.check_box(
+ name: :mentioned,
+ label: helpers.t("my_account.notifications.participating.mentioned"),
+ disabled: true,
+ data: { test_selector: "global-notification-type-mentioned" },
+ id: "op-notification-mentioned--#{SecureRandom.uuid}}"
+ )
+ fg.check_box(
+ name: :watched,
+ label: helpers.t("my_account.notifications.participating.watched"),
+ disabled: true,
+ data: { test_selector: "global-notification-type-watched" },
+ id: "op-notification-watched--#{SecureRandom.uuid}}"
+ )
+ fg.check_box(
+ name: :assignee,
+ label: helpers.t("my_account.notifications.participating.assignee"),
+ data: { test_selector: "global-notification-type-assignee" },
+ id: "op-notification-assignee--#{SecureRandom.uuid}}"
+ )
+ fg.check_box(
+ name: :responsible,
+ label: helpers.t("my_account.notifications.participating.responsible"),
+ data: { test_selector: "global-notification-type-responsible" },
+ id: "op-notification-responsible--#{SecureRandom.uuid}}"
+ )
+ fg.check_box(
+ name: :shared,
+ label: helpers.t("my_account.notifications.participating.shared"),
+ data: { test_selector: "global-notification-type-shared" },
+ id: "op-notification-shared--#{SecureRandom.uuid}}"
+ )
+
+ if @show_submit
+ fg.submit(name: :submit, label: helpers.t("my_account.notifications.participating.submit_button"),
+ scheme: :default)
+ end
+ end
+ end
+end
diff --git a/app/forms/my/notifications/project_autocompleter_form.rb b/app/forms/my/notifications/project_autocompleter_form.rb
new file mode 100644
index 00000000000..db18efa0608
--- /dev/null
+++ b/app/forms/my/notifications/project_autocompleter_form.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Notifications::ProjectAutocompleterForm < ApplicationForm
+ def initialize(readonly: false, user: nil)
+ super()
+ @readonly = readonly
+ @excluded_project_ids = if !readonly && user
+ user.notification_settings.where.not(project: nil).pluck(:project_id).map(&:to_s)
+ else
+ []
+ end
+ end
+
+ form do |f|
+ filters = [{ name: "active", operator: "=", values: ["t"] }]
+ filters << { name: "id", operator: "!", values: @excluded_project_ids } if @excluded_project_ids.any?
+
+ f.project_autocompleter(
+ name: :project_id,
+ label: Project.model_name.human,
+ required: true,
+ autocomplete_options: {
+ data: { test_selector: "my-notifications-project-autocompleter" },
+ appendTo: "##{My::Notifications::ProjectSettingsDialogComponent::DIALOG_ID}",
+ readonly: @readonly,
+ filters:
+ }
+ )
+ end
+end
diff --git a/app/forms/my/reminders/daily_reminders_form.rb b/app/forms/my/reminders/daily_reminders_form.rb
new file mode 100644
index 00000000000..7a303b229de
--- /dev/null
+++ b/app/forms/my/reminders/daily_reminders_form.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Reminders::DailyRemindersForm < ApplicationForm
+ DailyRemindersFormModel = Data.define(:enabled, :times)
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.email_reminders.daily_reminders.title"), mt: 3) do |fg|
+ fg.check_box(
+ name: :enabled,
+ label: helpers.t("my_account.email_reminders.daily_reminders.enabled"),
+ data: {
+ target_name: "daily-enabled",
+ show_when_checked_target: "cause"
+ }
+ ) do |cb|
+ cb.nested_form(
+ classes: [{ "d-none" => !model.enabled }],
+ data: {
+ target_name: "daily-enabled",
+ show_when_checked_target: "effect",
+ show_when: "checked"
+ }
+ ) do |times_builder|
+ My::Reminders::DailyTimesComponent.new(
+ times: model.times || [],
+ scope: times_builder.object_name
+ )
+ end
+ end
+
+ fg.submit(name: :submit, label: helpers.t("button_save"), scheme: :default)
+ end
+ end
+end
diff --git a/app/forms/my/reminders/email_alerts_form.rb b/app/forms/my/reminders/email_alerts_form.rb
new file mode 100644
index 00000000000..a22c7375446
--- /dev/null
+++ b/app/forms/my/reminders/email_alerts_form.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Reminders::EmailAlertsForm < ApplicationForm
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.email_reminders.email_alerts.title"), mt: 3) do |fg|
+ NotificationSetting.email_settings.each do |setting|
+ fg.check_box(
+ name: setting,
+ label: helpers.t("my_account.email_reminders.email_alerts.#{setting}")
+ )
+ end
+
+ fg.submit(name: :submit, label: helpers.t("my_account.email_reminders.email_alerts.submit_button"), scheme: :default)
+ end
+ end
+end
diff --git a/app/forms/my/reminders/immediate_reminders_form.rb b/app/forms/my/reminders/immediate_reminders_form.rb
new file mode 100644
index 00000000000..7c5d010462e
--- /dev/null
+++ b/app/forms/my/reminders/immediate_reminders_form.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class My::Reminders::ImmediateRemindersForm < ApplicationForm
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.email_reminders.immediate_reminders.title"), mt: 2) do |fg|
+ fg.check_box(
+ name: :mentioned,
+ label: helpers.t("my_account.email_reminders.immediate_reminders.mentioned"),
+ data: { test_selector: "immediate-reminder-mentioned" }
+ )
+ fg.check_box(
+ name: :personal_reminder,
+ label: helpers.t("my_account.email_reminders.immediate_reminders.personal_reminder"),
+ data: { test_selector: "immediate-reminder-personal_reminder" }
+ )
+
+ fg.submit(name: :submit, label: helpers.t("button_save"), scheme: :default)
+ end
+ end
+end
diff --git a/app/forms/my/reminders/pause_reminders_form.rb b/app/forms/my/reminders/pause_reminders_form.rb
new file mode 100644
index 00000000000..4e20f282b26
--- /dev/null
+++ b/app/forms/my/reminders/pause_reminders_form.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.
+#++
+
+class My::Reminders::PauseRemindersForm < ApplicationForm
+ PauseRemindersFormModel = Data.define(:enabled, :first_day, :last_day)
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.email_reminders.pause_reminders.title"), mt: 3) do |fg|
+ fg.check_box(
+ name: :enabled,
+ id: "pause-reminders-enabled",
+ label: helpers.t("my_account.email_reminders.pause_reminders.enabled"),
+ data: {
+ target_name: "pause-enabled",
+ show_when_checked_target: "cause"
+ }
+ ) do |cb|
+ cb.nested_form(
+ classes: [{ "d-none" => !model.enabled }],
+ data: {
+ target_name: "pause-enabled",
+ show_when_checked_target: "effect",
+ show_when: "checked"
+ }
+ ) do |builder|
+ DateRangeForm.new(builder)
+ end
+ end
+
+ fg.submit(name: :submit, label: helpers.t("button_save"), scheme: :default)
+ end
+ end
+
+ class DateRangeForm < ApplicationForm
+ form do |f|
+ f.range_date_picker(
+ name: :date_range,
+ visually_hide_label: true,
+ input_width: :small,
+ label: helpers.t("my_account.email_reminders.pause_reminders.date_range"),
+ value: [model.first_day, model.last_day].compact_blank.join(" - ")
+ )
+ end
+ end
+end
diff --git a/app/forms/my/reminders/workdays_form.rb b/app/forms/my/reminders/workdays_form.rb
new file mode 100644
index 00000000000..a555a7ab05a
--- /dev/null
+++ b/app/forms/my/reminders/workdays_form.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.
+#++
+
+class My::Reminders::WorkdaysForm < ApplicationForm
+ WEEKDAY_NUMBERS = [1, 2, 3, 4, 5, 6, 7].freeze
+
+ form do |f|
+ f.fieldset_group(title: helpers.t("my_account.email_reminders.workdays.title"), mt: 3) do |fg|
+ fg.check_box_group(name: :workdays) do |group|
+ WEEKDAY_NUMBERS.each do |day_num|
+ day_label = helpers.t("date.day_names")[day_num % 7]
+ group.check_box(label: day_label, value: day_num)
+ end
+ end
+
+ fg.submit(name: :submit, label: helpers.t("my_account.email_reminders.workdays.submit_button"), scheme: :default)
+ end
+ end
+end
diff --git a/app/forms/projects/settings/editable_identifier_form.rb b/app/forms/projects/settings/editable_identifier_form.rb
index 2ff8af4b19c..979d60cfe87 100644
--- a/app/forms/projects/settings/editable_identifier_form.rb
+++ b/app/forms/projects/settings/editable_identifier_form.rb
@@ -31,7 +31,7 @@ module Projects
module Settings
class EditableIdentifierForm < ApplicationForm
form do |f|
- if Setting::WorkPackageIdentifier.alphanumeric?
+ if Setting::WorkPackageIdentifier.semantic?
f.text_field(
name: :identifier,
label: attribute_name(:identifier),
diff --git a/app/forms/projects/settings/identifier_form.rb b/app/forms/projects/settings/identifier_form.rb
index 872e8de891d..8404602c756 100644
--- a/app/forms/projects/settings/identifier_form.rb
+++ b/app/forms/projects/settings/identifier_form.rb
@@ -31,7 +31,7 @@ module Projects
module Settings
class IdentifierForm < ApplicationForm
form do |f|
- caption_key = if Setting::WorkPackageIdentifier.alphanumeric?
+ caption_key = if Setting::WorkPackageIdentifier.semantic?
:text_project_identifier_description
else
:text_project_identifier_url_description
diff --git a/app/forms/versions/form.rb b/app/forms/versions/form.rb
index 35f8b6b0533..778650eda8a 100644
--- a/app/forms/versions/form.rb
+++ b/app/forms/versions/form.rb
@@ -110,35 +110,6 @@ module Versions
end
end
- if backlogs_enabled?
- setting = version_setting_for_project
-
- f.select_list(
- name: "version[version_settings_attributes][][display]",
- scope_name_to_model: false,
- label: I18n.t(:label_column_in_backlog),
- input_width: :small
- ) do |list|
- position_display_options.each do |label, value|
- list.option(label:, value:, selected: setting.display == value)
- end
- end
-
- if setting.persisted?
- f.hidden(
- name: "version[version_settings_attributes][][id]",
- value: setting.id,
- scope_name_to_model: false
- )
- end
- end
-
- f.hidden(
- name: "project_id",
- value: project.id,
- scope_name_to_model: false
- )
-
render_custom_fields(form: f)
f.submit(
@@ -177,35 +148,5 @@ module Versions
def wiki_pages_disabled?
contract.assignable_wiki_pages.none?
end
-
- def backlogs_enabled?
- resolved_project.backlogs_enabled? && !OpenProject::FeatureDecisions.scrum_projects_active?
- end
-
- def resolved_project
- @project || version.project
- end
-
- def version_setting_for_project
- setting = version.version_settings.detect { |vs| vs.project_id == resolved_project.id || vs.project_id.nil? }
- setting || version.version_settings.new(display: VersionSetting::DISPLAY_LEFT, project: resolved_project)
- end
-
- def position_display_options
- [VersionSetting::DISPLAY_NONE,
- VersionSetting::DISPLAY_LEFT,
- VersionSetting::DISPLAY_RIGHT].map { |s| [humanize_display_option(s), s] }
- end
-
- def humanize_display_option(option)
- case option
- when VersionSetting::DISPLAY_NONE
- I18n.t("version_settings_display_option_none")
- when VersionSetting::DISPLAY_LEFT
- I18n.t("version_settings_display_option_left")
- when VersionSetting::DISPLAY_RIGHT
- I18n.t("version_settings_display_option_right")
- end
- end
end
end
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 2a36884936a..5fbc9751a9d 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -64,6 +64,29 @@ module GroupsHelper
]
end
+ def department_settings_tabs(group)
+ [
+ {
+ name: "general",
+ partial: "admin/departments/general",
+ path: edit_admin_department_path(group),
+ label: :label_general
+ },
+ {
+ name: "memberships",
+ partial: "admin/departments/memberships",
+ path: edit_admin_department_path(group, tab: :memberships),
+ label: :label_project_plural
+ },
+ {
+ name: "global_roles",
+ partial: "principals/global_roles",
+ path: edit_admin_department_path(group, tab: :global_roles),
+ label: :label_global_roles
+ }
+ ]
+ end
+
def autocompleter_filters(group)
[
{ name: "status", operator: "=", values: ["active", "invited"] },
diff --git a/app/helpers/members_helper.rb b/app/helpers/members_helper.rb
index d6416a80b0f..16e166e49e5 100644
--- a/app/helpers/members_helper.rb
+++ b/app/helpers/members_helper.rb
@@ -66,7 +66,9 @@ module MembersHelper
end
def principal_membership_path(principal, global_member, options = {})
- if principal.is_a?(Group)
+ if principal.is_a?(Group) && principal.organizational_unit?
+ membership_of_admin_department_path(principal, global_member, options)
+ elsif principal.is_a?(Group)
membership_of_group_path(principal, global_member, options)
else
user_membership_path(principal, global_member, options)
@@ -74,7 +76,9 @@ module MembersHelper
end
def principal_memberships_path(principal, options = {})
- if principal.is_a?(Group)
+ if principal.is_a?(Group) && principal.organizational_unit?
+ memberships_of_admin_department_path(principal, options)
+ elsif principal.is_a?(Group)
memberships_of_group_path(principal, options)
else
user_memberships_path(principal, options)
diff --git a/app/menus/submenu.rb b/app/menus/submenu.rb
index a6058e0ee21..92094f83971 100644
--- a/app/menus/submenu.rb
+++ b/app/menus/submenu.rb
@@ -72,7 +72,7 @@ class Submenu
end
def default_queries
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def global_queries
@@ -150,7 +150,7 @@ class Submenu
end
def query_path(query_params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def url_helpers
diff --git a/app/models/activities/event_mapper.rb b/app/models/activities/event_mapper.rb
index e563726ce75..368ccb78a25 100644
--- a/app/models/activities/event_mapper.rb
+++ b/app/models/activities/event_mapper.rb
@@ -77,11 +77,11 @@ module Activities
end
def event_data(journal)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def event_title(journal, data)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/models/attribute_help_text.rb b/app/models/attribute_help_text.rb
index a9351c28c14..5a4e7313457 100644
--- a/app/models/attribute_help_text.rb
+++ b/app/models/attribute_help_text.rb
@@ -80,15 +80,15 @@ class AttributeHelpText < ApplicationRecord
end
def type_caption
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.visible_condition(_user = nil)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.available_attributes
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/app/models/auth_provider.rb b/app/models/auth_provider.rb
index 0ef960a072e..5f69a4f24e3 100644
--- a/app/models/auth_provider.rb
+++ b/app/models/auth_provider.rb
@@ -49,7 +49,7 @@ class AuthProvider < ApplicationRecord
end
def human_type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def auth_url
diff --git a/app/models/capabilities/scopes/visible.rb b/app/models/capabilities/scopes/visible.rb
index 6d7b289d628..521ac4f13a1 100644
--- a/app/models/capabilities/scopes/visible.rb
+++ b/app/models/capabilities/scopes/visible.rb
@@ -34,7 +34,7 @@ module Capabilities::Scopes
class_methods do
def visible(user = User.current)
- scope = if user.admin?
+ scope = if user.active_admin?
all
else
where(context_id: nil)
diff --git a/app/models/concerns/has_details_table.rb b/app/models/concerns/has_details_table.rb
index e8b58db734d..8a8c7b7494e 100644
--- a/app/models/concerns/has_details_table.rb
+++ b/app/models/concerns/has_details_table.rb
@@ -59,6 +59,7 @@ module HasDetailsTable
setup_detail_association(association_name, detail_class, foreign_key)
setup_detail_aliases(association_name)
setup_detail_delegation(detail_class, foreign_key)
+ setup_detail_changed_tracking(detail_class, foreign_key)
setup_detail_dup
end
@@ -118,6 +119,112 @@ module HasDetailsTable
alias_method :build_detail, :"build_#{association_name}"
end
+ # Include detail column changes in the owner's `changed` and `changes` so
+ # that ModelContract can detect unauthorized writes to delegated attributes.
+ def setup_detail_changed_tracking(detail_class, foreign_key)
+ setup_changed_method(detail_class, foreign_key)
+ setup_changes_method(detail_class, foreign_key)
+ setup_changed_question_method(detail_class, foreign_key)
+ setup_changed_attributes_method(detail_class, foreign_key)
+ setup_previous_changes_method(detail_class, foreign_key)
+ setup_restore_attributes_method(detail_class, foreign_key)
+ setup_reload_method
+
+ # Rails 5.1+ alias - only define if the original method exists
+ alias_method :saved_changes, :previous_changes if method_defined?(:saved_changes)
+ end
+
+ def setup_changed_method(detail_class, foreign_key)
+ define_method(:changed) do
+ result = super()
+ return result unless detail&.persisted?
+
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+ result | (detail.changed & detail_columns)
+ end
+ end
+
+ def setup_changes_method(detail_class, foreign_key)
+ define_method(:changes) do
+ result = super()
+ return result unless detail&.persisted?
+
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+ detail_changes = detail.changes.slice(*detail_columns)
+ result.merge(detail_changes)
+ end
+ end
+
+ def setup_changed_question_method(detail_class, foreign_key) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
+ define_method(:changed?) do |attr = nil| # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+
+ if attr.nil?
+ return true if super()
+ return false unless detail&.persisted?
+
+ detail.changed.intersect?(detail_columns)
+ else
+ attr = attr.to_s
+ if detail_columns.include?(attr)
+ detail.persisted? && detail.changed.include?(attr)
+ else
+ return false unless super()
+
+ changed.include?(attr)
+ end
+ end
+ end
+ end
+
+ def setup_changed_attributes_method(detail_class, foreign_key)
+ define_method(:changed_attributes) do
+ result = super()
+ return result unless detail&.persisted?
+
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+ detail_changed = detail.changed_attributes.slice(*detail_columns)
+ result.merge(detail_changed)
+ end
+ end
+
+ def setup_previous_changes_method(detail_class, foreign_key)
+ define_method(:previous_changes) do
+ result = super()
+ return result unless detail&.persisted?
+
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+ detail_previous = detail.previous_changes.slice(*detail_columns)
+ result.merge(detail_previous)
+ end
+ end
+
+ def setup_restore_attributes_method(detail_class, foreign_key)
+ define_method(:restore_attributes) do |attributes = changed|
+ attributes = Array(attributes).map(&:to_s)
+ internal_columns = %w[id created_at updated_at] + [foreign_key]
+ detail_columns = detail_class.column_names - internal_columns
+ owner_attrs = attributes - detail_columns
+ detail_attrs = attributes & detail_columns
+
+ super(owner_attrs) if owner_attrs.any?
+ detail.restore_attributes(detail_attrs) if detail_attrs.any? && detail&.persisted?
+ end
+ end
+
+ def setup_reload_method
+ define_method(:reload) do |*args|
+ result = super(*args)
+ detail&.reload
+ result
+ end
+ end
+
def setup_detail_delegation(detail_class, foreign_key)
# Try to set up delegation eagerly so that writer methods exist
# during assign_attributes in new/create. Requires DB + table.
@@ -169,6 +276,10 @@ module HasDetailsTable
(detail_class.column_names - internal_columns).each do |col|
delegate col.to_sym, to: :detail
define_detail_writer(:"#{col}=")
+
+ if detail_class.columns_hash[col]&.type == :boolean
+ delegate :"#{col}?", to: :detail
+ end
end
end
diff --git a/app/models/custom_actions/actions/base.rb b/app/models/custom_actions/actions/base.rb
index a600586f581..3b131d6f80d 100644
--- a/app/models/custom_actions/actions/base.rb
+++ b/app/models/custom_actions/actions/base.rb
@@ -42,7 +42,7 @@ class CustomActions::Actions::Base
end
def allowed_values
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def value_objects
@@ -52,11 +52,11 @@ class CustomActions::Actions::Base
end
def type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def apply(_work_package)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def human_name
@@ -64,7 +64,7 @@ class CustomActions::Actions::Base
end
def self.key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.all
diff --git a/app/models/custom_actions/actions/custom_field.rb b/app/models/custom_actions/actions/custom_field.rb
index 55393c9dcea..dd796273c4f 100644
--- a/app/models/custom_actions/actions/custom_field.rb
+++ b/app/models/custom_actions/actions/custom_field.rb
@@ -35,7 +35,7 @@ class CustomActions::Actions::CustomField < CustomActions::Actions::Base
end
def custom_field
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def all
diff --git a/app/models/custom_actions/conditions/base.rb b/app/models/custom_actions/conditions/base.rb
index add9a84c872..9852d382fbc 100644
--- a/app/models/custom_actions/conditions/base.rb
+++ b/app/models/custom_actions/conditions/base.rb
@@ -67,7 +67,7 @@ class CustomActions::Conditions::Base
end
def self.key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def validate(errors)
diff --git a/app/models/custom_fields/scopes/visible.rb b/app/models/custom_fields/scopes/visible.rb
index 1a70ee93961..2709e8ba873 100644
--- a/app/models/custom_fields/scopes/visible.rb
+++ b/app/models/custom_fields/scopes/visible.rb
@@ -34,9 +34,13 @@ module CustomFields::Scopes
class_methods do
def visible(user = User.current)
- known_subclasses
- .inject(none) do |scope, klass|
- scope.or(where(type: klass.name).and(klass.visible(user)))
+ if user.active_admin?
+ all
+ else
+ known_subclasses
+ .inject(none) do |scope, klass|
+ scope.or(where(type: klass.name).and(klass.visible(user)))
+ end
end
end
diff --git a/app/models/custom_value/ar_object_strategy.rb b/app/models/custom_value/ar_object_strategy.rb
index f8cbb6f4280..4c9752ff8ed 100644
--- a/app/models/custom_value/ar_object_strategy.rb
+++ b/app/models/custom_value/ar_object_strategy.rb
@@ -69,7 +69,7 @@ class CustomValue::ARObjectStrategy < CustomValue::FormatStrategy
end
def ar_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def ar_object(value)
diff --git a/app/models/custom_value/format_strategy.rb b/app/models/custom_value/format_strategy.rb
index 85e484bb2a5..5f576e87bdf 100644
--- a/app/models/custom_value/format_strategy.rb
+++ b/app/models/custom_value/format_strategy.rb
@@ -42,7 +42,7 @@ class CustomValue::FormatStrategy
# Returns the value of the CustomValue in a typed fashion (i.e. not as the string
# that is used for representation in the database)
def typed_value
- raise "SubclassResponsibility"
+ raise SubclassResponsibilityError
end
# Returns the value of the CustomValue formatted to a string
@@ -59,6 +59,6 @@ class CustomValue::FormatStrategy
# Validates the type of the custom field and returns a symbol indicating the validation error
# if an error occurred; returns nil if no error occurred
def validate_type_of_value
- raise "SubclassResponsibility"
+ raise SubclassResponsibilityError
end
end
diff --git a/app/models/exports/exporter.rb b/app/models/exports/exporter.rb
index 17ab532b76d..0c42581fef4 100644
--- a/app/models/exports/exporter.rb
+++ b/app/models/exports/exporter.rb
@@ -63,7 +63,7 @@ module Exports
# Run the export, yielding the result of the render output
def export!
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
protected
diff --git a/app/models/group.rb b/app/models/group.rb
index 40b613afa4d..91ac56e2f6c 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -41,6 +41,7 @@ class Group < Principal
end
validate :no_circular_parent, if: -> { parent_id.present? }
+ validate :no_organizational_unit_mismatch, if: -> { parent_id.present? }
# Register a partial to be rendered on the synchronized groups tab of the groups admin page
#
@@ -170,4 +171,13 @@ class Group < Principal
errors.add(:parent_id, :circular_dependency)
end
end
+
+ def no_organizational_unit_mismatch
+ parent = self.class.find_by(id: parent_id)
+ return unless parent
+
+ if organizational_unit? != parent.organizational_unit?
+ errors.add(:parent_id, :organizational_unit_mismatch)
+ end
+ end
end
diff --git a/app/models/group_custom_fields/scopes/visible.rb b/app/models/group_custom_fields/scopes/visible.rb
index cd55eb2e953..7cb7e9b7706 100644
--- a/app/models/group_custom_fields/scopes/visible.rb
+++ b/app/models/group_custom_fields/scopes/visible.rb
@@ -34,7 +34,7 @@ module GroupCustomFields::Scopes
class_methods do
def visible(user = User.current)
- if user.admin?
+ if user.active_admin?
all
else
where(admin_only: false)
diff --git a/app/models/groups/hierarchy.rb b/app/models/groups/hierarchy.rb
index 3af58b2a189..bebe514c554 100644
--- a/app/models/groups/hierarchy.rb
+++ b/app/models/groups/hierarchy.rb
@@ -47,8 +47,22 @@ module Groups::Hierarchy
end
# All groups above this one in the tree up to the root.
- def ancestors
- Group.where(id: ancestor_ids)
+ # Pass `order: :asc` to get root-first, `:desc` for closest-ancestor-first.
+ def ancestors(order: nil)
+ ids = ancestor_ids
+ scope = Group.where(id: ids)
+
+ if order
+ # ancestor_ids are returned child-first by the CTE.
+ # Use array_position to preserve that order, then apply asc/desc.
+ ordered_ids = order == :asc ? ids.reverse : ids
+ order_sql = self.class.sanitize_sql_array(
+ ["array_position(ARRAY[?]::bigint[], #{Group.table_name}.id)", ordered_ids]
+ )
+ scope.order(Arel.sql(order_sql))
+ else
+ scope
+ end
end
# Self and all ancestor groups, ordered from root down.
diff --git a/app/models/groups/scopes/organizational_units.rb b/app/models/groups/scopes/organizational_units.rb
index e1741d7a369..e4db55b48cb 100644
--- a/app/models/groups/scopes/organizational_units.rb
+++ b/app/models/groups/scopes/organizational_units.rb
@@ -36,6 +36,10 @@ module Groups::Scopes
def organizational_units
where_detail(organizational_unit: true)
end
+
+ def not_organizational_units
+ where_detail(organizational_unit: false)
+ end
end
end
end
diff --git a/app/models/members/scopes/visible.rb b/app/models/members/scopes/visible.rb
index 8fe3adafe2e..f6429e5e468 100644
--- a/app/models/members/scopes/visible.rb
+++ b/app/models/members/scopes/visible.rb
@@ -35,7 +35,7 @@ module Members::Scopes
class_methods do
# Find all members visible to the inquiring user
def visible(user = User.current)
- if user.admin?
+ if user.active_admin?
visible_for_admins
else
visible_for_non_admins(user)
diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb
index 5640853e178..a717b650e47 100644
--- a/app/models/notification_setting.rb
+++ b/app/models/notification_setting.rb
@@ -68,6 +68,16 @@ class NotificationSetting < ApplicationRecord
]
end
+ def self.non_participating_settings
+ [
+ WORK_PACKAGE_CREATED,
+ WORK_PACKAGE_COMMENTED,
+ WORK_PACKAGE_PROCESSED,
+ WORK_PACKAGE_PRIORITIZED,
+ WORK_PACKAGE_SCHEDULED
+ ]
+ end
+
def self.date_alert_settings
[
START_DATE,
@@ -94,4 +104,18 @@ class NotificationSetting < ApplicationRecord
include Scopes::Scoped
scopes :applicable
+
+ # rubocop:disable Naming/PredicateMethod
+ def start_date_active
+ start_date.present?
+ end
+
+ def due_date_active
+ due_date.present?
+ end
+
+ def overdue_active
+ overdue.present?
+ end
+ # rubocop:enable Naming/PredicateMethod
end
diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb
index 5870bdd695a..d0a44db3c3a 100644
--- a/app/models/permitted_params.rb
+++ b/app/models/permitted_params.rb
@@ -274,7 +274,31 @@ class PermittedParams
:comments_sorting,
:disable_keyboard_shortcuts,
:warn_on_leaving_unsaved,
- :auto_hide_popups)
+ :auto_hide_popups,
+ immediate_reminders: %i[mentioned personal_reminder],
+ daily_reminders: [:enabled, { times: [] }],
+ workdays: [],
+ pause_reminders: %i[enabled date_range])
+ end
+
+ def notification_setting_email_alerts
+ params.fetch(:notification_setting, {}).permit(*NotificationSetting.email_settings)
+ end
+
+ def notification_setting_participating
+ params.fetch(:notification_setting, {}).permit(:assignee, :responsible, :shared)
+ end
+
+ def notification_setting_non_participating
+ params.fetch(:notification_setting, {}).permit(*NotificationSetting.non_participating_settings)
+ end
+
+ def notification_setting_project
+ params.fetch(:notification_setting, {}).permit(
+ :project_id,
+ :assignee, :responsible, :shared,
+ *NotificationSetting.non_participating_settings
+ )
end
def project
@@ -335,9 +359,6 @@ class PermittedParams
end
def version
- # `version_settings_attributes` is from a plugin. Unfortunately as it stands
- # now it is less work to do it this way than have the plugin override this
- # method. We hopefully will change this in the future.
permitted_params = params.fetch(:version, {}).permit(:name,
:description,
:effective_date,
@@ -345,8 +366,7 @@ class PermittedParams
:start_date,
:wiki_page_title,
:status,
- :sharing,
- version_settings_attributes: %i(id display project_id))
+ :sharing)
permitted_params.merge(custom_field_values(:version, required: false))
end
diff --git a/app/models/principal.rb b/app/models/principal.rb
index adbe8fa58c3..1ec1c24a00e 100644
--- a/app/models/principal.rb
+++ b/app/models/principal.rb
@@ -137,7 +137,7 @@ class Principal < ApplicationRecord
# Columns required for formatting the principal's name.
def self.columns_for_name(formatter = nil)
- raise NotImplementedError, "Redefine in subclass" unless self == Principal
+ raise SubclassResponsibilityError, "Redefine in subclass" unless self == Principal
[User, Group, PlaceholderUser].map { it.columns_for_name(formatter) }.inject(:|)
end
diff --git a/app/models/principals/scopes/visible.rb b/app/models/principals/scopes/visible.rb
index 1a25ab8da6a..20445de2230 100644
--- a/app/models/principals/scopes/visible.rb
+++ b/app/models/principals/scopes/visible.rb
@@ -42,7 +42,7 @@ module Principals::Scopes
class_methods do
def visible(user = ::User.current)
- if user.allowed_globally?(:view_all_principals) || user.admin?
+ if user.allowed_globally?(:view_all_principals)
all
else
in_visible_project_or_me_or_same_groups(user)
diff --git a/app/models/project.rb b/app/models/project.rb
index 3a5aa7853fd..8d01e969e0c 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -39,6 +39,7 @@ class Project < ApplicationRecord
include Projects::WorkPackageCustomFields
include Projects::CreationWizard
include Projects::Identifier
+ include Projects::SemanticIdentifier
include ::Scopes::Scoped
diff --git a/app/models/project_custom_field.rb b/app/models/project_custom_field.rb
index 10c3aadcb33..c13e97f75ee 100644
--- a/app/models/project_custom_field.rb
+++ b/app/models/project_custom_field.rb
@@ -56,7 +56,7 @@ class ProjectCustomField < CustomField
class << self
def visible(user = User.current, project: nil)
- if user.admin?
+ if user.active_admin?
all
elsif user.allowed_in_any_project?(:select_project_custom_fields) || user.allowed_globally?(:add_project)
where(admin_only: false)
diff --git a/app/models/project_custom_fields/scopes/visible.rb b/app/models/project_custom_fields/scopes/visible.rb
index eee99147a52..d0fec1ba6cf 100644
--- a/app/models/project_custom_fields/scopes/visible.rb
+++ b/app/models/project_custom_fields/scopes/visible.rb
@@ -34,7 +34,7 @@ module ProjectCustomFields::Scopes
class_methods do
def visible(user = User.current, project: nil)
- if user.admin?
+ if user.active_admin?
all
elsif user.allowed_in_any_project?(:select_project_custom_fields) || user.allowed_globally?(:add_project)
where(admin_only: false)
diff --git a/app/models/projects/identifier.rb b/app/models/projects/identifier.rb
index 5f7d690e770..e505f66e0b7 100644
--- a/app/models/projects/identifier.rb
+++ b/app/models/projects/identifier.rb
@@ -53,36 +53,30 @@ module Projects::Identifier
limit: IDENTIFIER_MAX_LENGTH,
blacklist: RESERVED_IDENTIFIERS,
adapter: OpenProject::ActsAsUrl::Adapter::OpActiveRecord, # use a custom adapter able to handle edge cases
- skip_if: -> { Setting::WorkPackageIdentifier.alphanumeric? }
+ skip_if: -> { Setting::WorkPackageIdentifier.semantic? }
# Generate semantic identifier (when in the semantic mode)
before_validation :generate_semantic_identifier,
on: :create,
- if: -> { Setting::WorkPackageIdentifier.alphanumeric? && identifier.blank? }
+ if: -> { Setting::WorkPackageIdentifier.semantic? && identifier.blank? }
### ID validators
- # Validators for the legacy underscored identifier format (e.g. "project_one")
+ # Shared validators for all identifier formats
validates :identifier,
presence: true,
- uniqueness: { case_sensitive: true },
+ uniqueness: { case_sensitive: false },
length: { maximum: IDENTIFIER_MAX_LENGTH },
- exclusion: RESERVED_IDENTIFIERS,
if: ->(p) { p.persisted? || p.identifier.present? }
- # Contains only a-z, 0-9, dashes and underscores but cannot consist of numbers only as it would clash with the id.
- validates :identifier,
- format: { with: /\A(?!^\d+\z)[a-z0-9\-_]+\z/ },
- if: ->(p) {
- p.identifier_changed? && p.identifier.present? && Setting::WorkPackageIdentifier.numeric?
- }
- # Validators for the semantic identifier format
- validates :identifier,
- format: { with: /\A[A-Z]/, message: :must_start_with_letter },
- if: ->(p) { p.identifier_changed? && p.identifier.present? && Setting::WorkPackageIdentifier.alphanumeric? }
- validates :identifier,
- format: { with: /\A[A-Z][A-Z0-9_]*\z/, message: :no_special_characters },
- length: { maximum: SEMANTIC_IDENTIFIER_MAX_LENGTH },
- if: ->(p) { p.identifier_changed? && p.identifier.present? && Setting::WorkPackageIdentifier.alphanumeric? }
+ # Validators for the numeric (legacy) identifier format (e.g. "my-project", "project_one")
+ validate :identifier_numeric_format,
+ if: ->(p) { p.identifier_changed? && p.identifier.present? && Setting::WorkPackageIdentifier.classic? }
+
+ # Validators for the semantic (alphanumeric) identifier format (e.g. "PROJ1")
+ validate :identifier_alphanumeric_format,
+ if: ->(p) { p.identifier_changed? && p.identifier.present? && Setting::WorkPackageIdentifier.semantic? }
+
+ validate :identifier_not_reserved, if: -> { identifier.present? }
# Complements the uniqueness validation above: once an identifier has been used by a
# project, it remains reserved for that project even after the project moves to a new
@@ -102,8 +96,10 @@ module Projects::Identifier
class_methods do
def suggest_identifier(name)
- if Setting::WorkPackageIdentifier.alphanumeric?
- WorkPackages::IdentifierAutofix::ProjectIdentifierSuggestionGenerator.suggest_identifier(name)
+ if Setting::WorkPackageIdentifier.semantic?
+ exclude = ProjectIdentifiers::IdentifierAutofix::ProblematicIdentifiers.reserved_identifiers
+ ProjectIdentifiers::IdentifierAutofix::ProjectIdentifierSuggestionGenerator
+ .suggest_identifier(name, exclude:)
else # This should closely enough emulate Project models' usage of acts_as_url
name.to_url.first(IDENTIFIER_MAX_LENGTH).presence || "project"
end
@@ -130,14 +126,38 @@ module Projects::Identifier
private
+ # Contains only a-z, 0-9, dashes and underscores but cannot consist of numbers only
+ # as that would clash with the numeric id.
+ def identifier_numeric_format
+ unless identifier.match?(/\A(?!^\d+\z)[a-z0-9\-_]+\z/)
+ errors.add(:identifier, :invalid)
+ end
+ end
+
+ def identifier_alphanumeric_format
+ errors.add(:identifier, :must_start_with_letter) unless identifier.match?(/\A[A-Z]/)
+ errors.add(:identifier, :no_special_characters) unless identifier.match?(/\A[A-Z0-9_]*\z/)
+ if identifier.length > SEMANTIC_IDENTIFIER_MAX_LENGTH
+ errors.add(:identifier, :too_long, count: SEMANTIC_IDENTIFIER_MAX_LENGTH)
+ end
+ end
+
+ def identifier_not_reserved
+ if RESERVED_IDENTIFIERS.include?(identifier&.downcase)
+ errors.add(:identifier, :exclusion)
+ end
+ end
+
# Checks friendly_id_slugs for any project that previously used this identifier and
- # has since changed it. It allows to switch back to an identifier the project itself
- # has used before.
+ # has since changed it. It allows a project to switch back to an identifier it has
+ # used before. Uses LOWER() because slugs may be stored in a different case than the
+ # incoming identifier (e.g. old lowercase slug vs new uppercase alphanumeric identifier).
def identifier_not_historically_reserved
return if errors.any? { |error| error.attribute == :identifier && error.type == :taken }
already_existing = FriendlyId::Slug
- .where(slug: identifier, sluggable_type: self.class.to_s)
+ .where("LOWER(slug) = LOWER(?)", identifier)
+ .where(sluggable_type: self.class.to_s)
.where.not(sluggable_id: id)
.exists?
@@ -145,6 +165,8 @@ module Projects::Identifier
end
def generate_semantic_identifier
- self.identifier = self.class.suggest_identifier(name) if name.present?
+ return if name.blank?
+
+ self.identifier = self.class.suggest_identifier(name)
end
end
diff --git a/app/models/projects/scopes/visible.rb b/app/models/projects/scopes/visible.rb
index 6ecae100fc3..ee627718e34 100644
--- a/app/models/projects/scopes/visible.rb
+++ b/app/models/projects/scopes/visible.rb
@@ -40,7 +40,7 @@ module Projects::Scopes
def visible(user = User.current)
# Use a shortcut for admins and anonymous where
# we don't need to calculate for work package roles which is more expensive
- if user.admin? || user.anonymous?
+ if user.active_admin? || user.anonymous?
allowed_to(user, :view_project)
else
active.public_projects.or(active.where(id: user.members.select(:project_id)))
diff --git a/app/models/projects/semantic_identifier.rb b/app/models/projects/semantic_identifier.rb
new file mode 100644
index 00000000000..100f04de7f3
--- /dev/null
+++ b/app/models/projects/semantic_identifier.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.
+#++
+
+module Projects::SemanticIdentifier
+ extend ActiveSupport::Concern
+
+ # Atomically allocates the next sequence number for a work package in this project
+ # and returns it paired with the resulting semantic identifier (e.g. [42, "PROJ-42"]).
+ # Uses an advisory lock scoped to this project to serialize concurrent allocations
+ # without blocking unrelated project row writes.
+ def allocate_wp_semantic_identifier!
+ seq = OpenProject::Mutex.with_advisory_lock(
+ self.class,
+ "wp_sequence_#{id}"
+ ) do
+ self.class.connection.select_value(<<~SQL.squish)
+ UPDATE projects
+ SET wp_sequence_counter = wp_sequence_counter + 1
+ WHERE id = #{self.class.connection.quote(id)}
+ RETURNING wp_sequence_counter
+ SQL
+ end
+
+ [seq, "#{identifier}-#{seq}"]
+ end
+
+ # Called after this project's identifier is renamed. Atomically:
+ # 1. Appends new-prefix aliases for every WP that ever carried an old-prefix alias.
+ # 2. Updates identifier on resident WPs to the new prefix.
+ def handle_semantic_rename(old_identifier, batch_size: 1000)
+ like_pattern = "#{self.class.sanitize_sql_like(old_identifier)}-%"
+ prefix = "#{old_identifier}-"
+ new_prefix = "#{identifier}-"
+
+ WorkPackageSemanticAlias.transaction do
+ append_aliases_with_new_prefix(like_pattern:, prefix:, new_prefix:, batch_size:)
+ rewrite_semantic_ids(like_pattern:, prefix:, new_prefix:, batch_size:)
+ end
+ end
+
+ private
+
+ # For every alias row whose identifier starts with the old prefix, inserts a
+ # corresponding row with the new prefix. This covers WPs still in the project
+ # as well as any that have moved out but still carry old-prefix alias rows.
+ def append_aliases_with_new_prefix(like_pattern:, prefix:, new_prefix:, batch_size:)
+ WorkPackageSemanticAlias
+ .where("identifier LIKE ?", like_pattern)
+ .in_batches(of: batch_size) do |relation|
+ now = Time.current
+ WorkPackageSemanticAlias.connection.execute(
+ WorkPackageSemanticAlias.sanitize_sql([<<~SQL.squish, { prefix:, new_prefix:, now: }])
+ INSERT INTO work_package_semantic_aliases (identifier, work_package_id, created_at, updated_at)
+ SELECT REPLACE(identifier, :prefix, :new_prefix), work_package_id, :now, :now
+ FROM (#{relation.to_sql}) AS batch
+ ON CONFLICT (identifier) DO NOTHING
+ SQL
+ )
+ end
+ end
+
+ # Updates the identifier column on all resident WPs to replace the old prefix with the new one.
+ def rewrite_semantic_ids(like_pattern:, prefix:, new_prefix:, batch_size:)
+ WorkPackage
+ .where("identifier LIKE ?", like_pattern)
+ .in_batches(of: batch_size) do |relation|
+ relation.update_all(["identifier = REPLACE(identifier, ?, ?)", prefix, new_prefix])
+ end
+ end
+end
diff --git a/app/models/queries/filters/base.rb b/app/models/queries/filters/base.rb
index bf739596141..1b049ce549a 100644
--- a/app/models/queries/filters/base.rb
+++ b/app/models/queries/filters/base.rb
@@ -79,11 +79,11 @@ class Queries::Filters::Base
end
def human_name
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def allowed_values
diff --git a/app/models/queries/filters/shared/parsed_filter.rb b/app/models/queries/filters/shared/parsed_filter.rb
index 7d16415cb06..928cc314970 100644
--- a/app/models/queries/filters/shared/parsed_filter.rb
+++ b/app/models/queries/filters/shared/parsed_filter.rb
@@ -50,11 +50,11 @@ module Queries::Filters::Shared::ParsedFilter
private
def split_values
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def value_conditions
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def validate_values
diff --git a/app/models/queries/filters/strategies/numeric.rb b/app/models/queries/filters/strategies/numeric.rb
index f2b1d938418..66531229922 100644
--- a/app/models/queries/filters/strategies/numeric.rb
+++ b/app/models/queries/filters/strategies/numeric.rb
@@ -42,11 +42,11 @@ module Queries::Filters::Strategies
private
def numeric_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def error_message
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def validate_values_all_numeric
diff --git a/app/models/queries/group_bys/base.rb b/app/models/queries/group_bys/base.rb
index ec2b2772db4..b1adc00d224 100644
--- a/app/models/queries/group_bys/base.rb
+++ b/app/models/queries/group_bys/base.rb
@@ -45,7 +45,7 @@ module Queries
end
def self.key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def association_class
diff --git a/app/models/queries/operators/base.rb b/app/models/queries/operators/base.rb
index 0aa864e84de..c70601a6de1 100644
--- a/app/models/queries/operators/base.rb
+++ b/app/models/queries/operators/base.rb
@@ -53,7 +53,7 @@ module Queries::Operators
end
def self.sql_for_field(_values, _db_table, _db_field)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.connection
diff --git a/app/models/queries/orders/base.rb b/app/models/queries/orders/base.rb
index 4d8f4630e6b..ab72786bae3 100644
--- a/app/models/queries/orders/base.rb
+++ b/app/models/queries/orders/base.rb
@@ -50,7 +50,7 @@ module Queries
end
def self.key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def apply_to(query_scope)
diff --git a/app/models/queries/projects/filters/dynamically_from_project_phase.rb b/app/models/queries/projects/filters/dynamically_from_project_phase.rb
index 1b27413f406..7d92fa3df50 100644
--- a/app/models/queries/projects/filters/dynamically_from_project_phase.rb
+++ b/app/models/queries/projects/filters/dynamically_from_project_phase.rb
@@ -56,7 +56,7 @@ module Queries::Projects::Filters::DynamicallyFromProjectPhase
end
def key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
private
@@ -77,7 +77,7 @@ module Queries::Projects::Filters::DynamicallyFromProjectPhase
end
def create_from_phase(_phase, _context)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def accessor_matches?(definition, match)
diff --git a/app/models/queries/projects/filters/filter_on_project_phase.rb b/app/models/queries/projects/filters/filter_on_project_phase.rb
index 0b6a5bf4613..ee137dd9492 100644
--- a/app/models/queries/projects/filters/filter_on_project_phase.rb
+++ b/app/models/queries/projects/filters/filter_on_project_phase.rb
@@ -74,23 +74,23 @@ module Queries::Projects::Filters::FilterOnProjectPhase
private
def on_date
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def on_today
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def between_date
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def this_week
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def none
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def project_phase_scope_limit(scope)
diff --git a/app/models/queries/relations/filters/visibility_checking.rb b/app/models/queries/relations/filters/visibility_checking.rb
index 4a5d102175e..6f4999cb581 100644
--- a/app/models/queries/relations/filters/visibility_checking.rb
+++ b/app/models/queries/relations/filters/visibility_checking.rb
@@ -54,7 +54,7 @@ module Queries
private
def visibility_checked_sql(_operator, _values, _visible_sql)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/models/queries/selects/base.rb b/app/models/queries/selects/base.rb
index a1d25a8e160..ec4175a41e9 100644
--- a/app/models/queries/selects/base.rb
+++ b/app/models/queries/selects/base.rb
@@ -32,7 +32,7 @@ class Queries::Selects::Base
include ActiveModel::Validations
def self.key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.available?
diff --git a/app/models/queries/work_packages/filter/attachment_base_filter.rb b/app/models/queries/work_packages/filter/attachment_base_filter.rb
index a8d97e4b7a4..c4fdb72c69a 100644
--- a/app/models/queries/work_packages/filter/attachment_base_filter.rb
+++ b/app/models/queries/work_packages/filter/attachment_base_filter.rb
@@ -68,7 +68,7 @@ class Queries::WorkPackages::Filter::AttachmentBaseFilter < Queries::WorkPackage
end
def search_column
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def normalization_type
diff --git a/app/models/queries/work_packages/filter/filter_on_directed_relations_mixin.rb b/app/models/queries/work_packages/filter/filter_on_directed_relations_mixin.rb
index 5594e280e57..0fefe8cf7cc 100644
--- a/app/models/queries/work_packages/filter/filter_on_directed_relations_mixin.rb
+++ b/app/models/queries/work_packages/filter/filter_on_directed_relations_mixin.rb
@@ -47,7 +47,7 @@ module Queries::WorkPackages::Filter::FilterOnDirectedRelationsMixin
end
def relation_type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def normalized_relation_type
@@ -57,10 +57,10 @@ module Queries::WorkPackages::Filter::FilterOnDirectedRelationsMixin
private
def relation_filter
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def relation_select
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/app/models/queries/work_packages/filter/filter_on_undirected_relations_mixin.rb b/app/models/queries/work_packages/filter/filter_on_undirected_relations_mixin.rb
index d8956e65ce6..131c6d37179 100644
--- a/app/models/queries/work_packages/filter/filter_on_undirected_relations_mixin.rb
+++ b/app/models/queries/work_packages/filter/filter_on_undirected_relations_mixin.rb
@@ -42,7 +42,7 @@ module Queries::WorkPackages::Filter::FilterOnUndirectedRelationsMixin
end
def relation_type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
private
diff --git a/app/models/queries/work_packages/filter/or_filter_for_wp_mixin.rb b/app/models/queries/work_packages/filter/or_filter_for_wp_mixin.rb
index 3ce0a5cd23d..8bab4565716 100644
--- a/app/models/queries/work_packages/filter/or_filter_for_wp_mixin.rb
+++ b/app/models/queries/work_packages/filter/or_filter_for_wp_mixin.rb
@@ -50,7 +50,7 @@ module Queries::WorkPackages::Filter::OrFilterForWpMixin
end
def filter_configurations
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def create_instances
diff --git a/app/models/query.rb b/app/models/query.rb
index d72939dcb9c..ed9b540a515 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -223,10 +223,12 @@ class Query < ApplicationRecord
end
def self.available_columns(project = nil)
- Queries::Register
- .selects[self]
- .map { |col| col.instances(project) }
- .flatten
+ RequestStore.fetch(:"available_columns_#{project&.id}") do
+ Queries::Register
+ .selects[self]
+ .map { |col| col.instances(project) }
+ .flatten
+ end
end
def self.displayable_columns
diff --git a/app/models/setting/work_package_identifier.rb b/app/models/setting/work_package_identifier.rb
index fb0004bada8..71afe4883f6 100644
--- a/app/models/setting/work_package_identifier.rb
+++ b/app/models/setting/work_package_identifier.rb
@@ -30,11 +30,12 @@
class Setting
module WorkPackageIdentifier
- NUMERIC = "numeric"
- ALPHANUMERIC = "alphanumeric"
- ALLOWED_VALUES = [NUMERIC, ALPHANUMERIC].freeze
+ CLASSIC = "classic"
+ SEMANTIC = "semantic"
+ ALLOWED_VALUES = [CLASSIC, SEMANTIC].freeze
- def self.alphanumeric? = Setting[:work_packages_identifier] == ALPHANUMERIC
- def self.numeric? = Setting[:work_packages_identifier] == NUMERIC
+ def self.semantic? = Setting[:work_packages_identifier] == SEMANTIC
+ def self.classic? = Setting[:work_packages_identifier] == CLASSIC
+ def self.semantic_mode_active? = semantic? && OpenProject::FeatureDecisions.semantic_work_package_ids_active?
end
end
diff --git a/app/models/sharing_strategies/base_strategy.rb b/app/models/sharing_strategies/base_strategy.rb
index cb47cf22d90..a9061e11974 100644
--- a/app/models/sharing_strategies/base_strategy.rb
+++ b/app/models/sharing_strategies/base_strategy.rb
@@ -40,36 +40,36 @@ module SharingStrategies
def available_roles
# format: [{ label: "Role name", value: 42, description: "Role description", default: true }]
- raise NotImplementedError, "Override in a subclass and return an array of roles that should be displayed"
+ raise SubclassResponsibilityError, "Override in a subclass and return an array of roles that should be displayed"
end
def viewable?
- raise NotImplementedError,
+ raise SubclassResponsibilityError,
"Override in a subclass and return true if the current user can view who the entity is shared with"
end
def manageable?
- raise NotImplementedError, "Override in a subclass and return true if the current user can manage sharing"
+ raise SubclassResponsibilityError, "Override in a subclass and return true if the current user can manage sharing"
end
def create_contract_class
- raise NotImplementedError, "Override in a subclass and return the contract class for creating a share"
+ raise SubclassResponsibilityError, "Override in a subclass and return the contract class for creating a share"
end
def update_contract_class
- raise NotImplementedError, "Override in a subclass and return the contract class for updating a share"
+ raise SubclassResponsibilityError, "Override in a subclass and return the contract class for updating a share"
end
def delete_contract_class
- raise NotImplementedError, "Override in a subclass and return the contract class for deleting a share"
+ raise SubclassResponsibilityError, "Override in a subclass and return the contract class for deleting a share"
end
def share_description(share)
- raise NotImplementedError, "Override in a subclass and return a description for the shared user"
+ raise SubclassResponsibilityError, "Override in a subclass and return a description for the shared user"
end
def title
- raise NotImplementedError, "Override in a subclass and return a title for the sharing dialog"
+ raise SubclassResponsibilityError, "Override in a subclass and return a title for the sharing dialog"
end
def enterprise_feature
diff --git a/app/models/type/attributes.rb b/app/models/type/attributes.rb
index 343258db690..bc4e787a1f5 100644
--- a/app/models/type/attributes.rb
+++ b/app/models/type/attributes.rb
@@ -82,10 +82,10 @@ module Type::Attributes
WorkPackageCustomField.pluck(Arel.sql("max(updated_at), count(id)")).flatten
end
- OpenProject::Cache.fetch("all_work_package_form_attributes",
- *wp_cf_cache_parts,
- EXCLUDED.length,
- merge_date) do
+ OpenProject::Cache.fetch_request_cached("all_work_package_form_attributes",
+ *wp_cf_cache_parts,
+ EXCLUDED.length,
+ merge_date) do
calculate_all_work_package_form_attributes(merge_date)
end
end
diff --git a/app/models/type/form_group.rb b/app/models/type/form_group.rb
index 7014859dff5..dbdb95d27af 100644
--- a/app/models/type/form_group.rb
+++ b/app/models/type/form_group.rb
@@ -57,10 +57,10 @@ class Type::FormGroup
end
def members
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def active_members(_project)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 707eeaa0b26..03e104a129b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -514,6 +514,10 @@ class User < Principal
!logged?
end
+ def active_admin?
+ admin? && active?
+ end
+
def consent_expired?
# Always if the user has not consented
return true if consented_at.blank?
diff --git a/app/models/user_custom_fields/scopes/visible.rb b/app/models/user_custom_fields/scopes/visible.rb
index ae7bfab44ba..e1fe79488e0 100644
--- a/app/models/user_custom_fields/scopes/visible.rb
+++ b/app/models/user_custom_fields/scopes/visible.rb
@@ -34,7 +34,7 @@ module UserCustomFields::Scopes
class_methods do
def visible(user = User.current)
- if user.admin?
+ if user.active_admin?
all
else
where(admin_only: false)
diff --git a/app/models/user_password.rb b/app/models/user_password.rb
index 35f027946d9..4b8fd2290cf 100644
--- a/app/models/user_password.rb
+++ b/app/models/user_password.rb
@@ -103,10 +103,10 @@ class UserPassword < ApplicationRecord
# Require the implementation to provide a secure comparison
def hash_matches?(_plain)
- raise NotImplementedError, "Must be overridden by subclass"
+ raise SubclassResponsibilityError
end
def derive_password!(_input)
- raise NotImplementedError, "Must be overridden by subclass"
+ raise SubclassResponsibilityError
end
end
diff --git a/app/models/user_preference.rb b/app/models/user_preference.rb
index ecedec0b147..2bf64584442 100644
--- a/app/models/user_preference.rb
+++ b/app/models/user_preference.rb
@@ -173,18 +173,51 @@ class UserPreference < ApplicationRecord
super.presence || { enabled: true, times: ["08:00:00+00:00"] }.with_indifferent_access
end
+ def daily_reminders=(value)
+ hash = value.to_h.with_indifferent_access
+ self.settings = settings.merge(
+ "daily_reminders" => {
+ "enabled" => ActiveRecord::Type::Boolean.new.cast(hash[:enabled]),
+ "times" => Array(hash[:times]).compact_blank
+ }
+ )
+ end
+
def workdays
super || WORKDAYS_FROM_MONDAY_TO_FRIDAY
end
+ def workdays=(value)
+ self.settings = settings.merge("workdays" => Array(value).map(&:to_i))
+ end
+
def immediate_reminders
super.presence || { mentioned: true, personal_reminder: true }.with_indifferent_access
end
+ def immediate_reminders=(value)
+ self.settings = settings.merge(
+ "immediate_reminders" => value.to_h.with_indifferent_access.transform_values { |v| ActiveRecord::Type::Boolean.new.cast(v) }
+ )
+ end
+
+ def mentioned
+ immediate_reminders[:mentioned]
+ end
+
+ def personal_reminder
+ immediate_reminders[:personal_reminder]
+ end
+
def pause_reminders
super.presence || { enabled: false }.with_indifferent_access
end
+ def pause_reminders=(value)
+ hash = value.to_h.with_indifferent_access
+ self.settings = settings.merge("pause_reminders" => pause_reminders_hash(hash))
+ end
+
def dismissed_banner?(feature)
dismissed_enterprise_banners.key?(feature.to_s)
end
@@ -206,4 +239,21 @@ class UserPreference < ApplicationRecord
def attribute?(name)
%i[user user_id].include?(name.to_sym)
end
+
+ def pause_reminders_hash(hash)
+ result = { "enabled" => ActiveRecord::Type::Boolean.new.cast(hash[:enabled]) }
+ date_fields = if hash[:date_range].present?
+ parsed_date_range(hash[:date_range])
+ else
+ { "first_day" => hash[:first_day].presence, "last_day" => hash[:last_day].presence }
+ end
+ result.merge(date_fields).compact
+ end
+
+ def parsed_date_range(date_range)
+ return {} if date_range.blank?
+
+ first_day, last_day = date_range.split(" - ", 2)
+ { "first_day" => first_day.presence, "last_day" => last_day.presence }
+ end
end
diff --git a/app/models/users/function_user.rb b/app/models/users/function_user.rb
index f1bbf2f8d3a..95b1c04c04f 100644
--- a/app/models/users/function_user.rb
+++ b/app/models/users/function_user.rb
@@ -45,7 +45,7 @@ module Users::FunctionUser
def builtin? = true
- def name(*_args); raise NotImplementedError end
+ def name(*_args) = raise SubclassResponsibilityError
def mail = nil
diff --git a/app/models/work_package.rb b/app/models/work_package.rb
index 93aa490b535..b80a5ef9427 100644
--- a/app/models/work_package.rb
+++ b/app/models/work_package.rb
@@ -29,6 +29,7 @@
#++
class WorkPackage < ApplicationRecord
+ include WorkPackage::SemanticIdentifier
include WorkPackage::Validations
include WorkPackage::SchedulingRules
include WorkPackage::StatusTransitions
diff --git a/app/models/work_package/semantic_identifier.rb b/app/models/work_package/semantic_identifier.rb
new file mode 100644
index 00000000000..0d8861ac95d
--- /dev/null
+++ b/app/models/work_package/semantic_identifier.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+module WorkPackage::SemanticIdentifier
+ extend ActiveSupport::Concern
+
+ included do
+ has_many :semantic_aliases,
+ class_name: "WorkPackageSemanticAlias",
+ foreign_key: :work_package_id,
+ inverse_of: :work_package,
+ dependent: :delete_all
+
+ after_create :allocate_and_register_semantic_id, if: -> { Setting::WorkPackageIdentifier.semantic? }
+ end
+
+ class_methods do
+ def semantic_id?(identifier)
+ identifier.to_s.to_i.to_s != identifier.to_s
+ end
+
+ # Resolves any identifier form to a WorkPackage.
+ # - Numeric string ("12345") → find by primary key
+ # - Semantic string ("PROJ-42") → lookup via work_packages table and alias table
+ #
+ # Returns nil on miss.
+ def find_by_id_or_identifier(identifier)
+ return find_by(id: identifier) unless semantic_id?(identifier)
+
+ find_by_semantic_identifier(identifier)
+ end
+
+ # Same as find_by_id_or_identifier but raises ActiveRecord::RecordNotFound on miss.
+ def find_by_id_or_identifier!(identifier)
+ find_by_id_or_identifier(identifier) || raise(ActiveRecord::RecordNotFound, "WorkPackage not found: #{identifier}")
+ end
+
+ private
+
+ def find_by_semantic_identifier(identifier)
+ wp = find_by(identifier:)
+ return wp if wp
+
+ # Fallback: alias table lookup. The table holds every identifier a WP has ever been known by:
+ # Done via a single join to:
+ # * Respect any parent scoping (e.g. when called as WorkPackage.visible.find_by_semantic_identifier)
+ # * Reduce lookup to a single DB round trip
+ joins(:semantic_aliases).find_by(work_package_semantic_aliases: { identifier: })
+ end
+ end
+
+ # Returns the user-facing identifier for this work package.
+ # In semantic mode: the project-based identifier (e.g. "PROJ-42")
+ # In classic mode: the numeric database ID
+ def display_id
+ Setting::WorkPackageIdentifier.semantic_mode_active? ? identifier : id
+ end
+
+ # Allocates the next semantic identifier in the current project and assigns it to the WP.
+ # Also writes alias rows for every identifier the project has ever used (including "ghost" aliases).
+ #
+ # This should generally be run following project_id-mutating operations on WorkPackage records (like create or move).
+ def allocate_and_register_semantic_id
+ WorkPackageSemanticAlias.transaction do
+ sequence_number, identifier = project.allocate_wp_semantic_identifier!
+ # Re-map the semantic identifier to the new project
+ update_columns(sequence_number:, identifier:)
+ # Insert current, historical + ghost aliases for the new project
+ # Note: In case of WP move, the previous mapping for the old project is assumed
+ # to be present in the alias table already, ever since its prior create/move operation.
+ semantic_aliases.insert_all(alias_rows_for_sequence_number(sequence_number),
+ unique_by: :identifier)
+ end
+ end
+
+ private
+
+ # Builds alias rows for every identifier this project has ever used at the given sequence (including the current one).
+ # This also includes "ghost identifiers" -- i.e. those that weren't ever actually generated, but should work
+ # as a historical alias (e.g. OLDPROJ-42 should work even if WP #42 was created after rename to NEWPROJ)
+ def alias_rows_for_sequence_number(seq)
+ project.slugs
+ .pluck(:slug)
+ .map { |prefix| { identifier: "#{prefix}-#{seq}", work_package_id: id } }
+ end
+end
diff --git a/app/models/work_package_semantic_alias.rb b/app/models/work_package_semantic_alias.rb
new file mode 100644
index 00000000000..e85e56cbad2
--- /dev/null
+++ b/app/models/work_package_semantic_alias.rb
@@ -0,0 +1,45 @@
+# 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.
+#++
+
+# Maps a semantic identifier (e.g. "PROJ-42") to a work package.
+# This acts as a registry of all semantic identifiers for a work package,
+# including both the current identifier and any retired ones created by moves
+# or project renames. The current identifier is also stored directly on
+# work_packages.identifier for faster access.
+#
+# The write side of the registry lives in WorkPackage::SemanticIdentifier:
+# wp.allocate_and_register_semantic_id # on WP project change (call post-save)
+# project.handle_semantic_rename(old_identifier) # on project identifier change
+class WorkPackageSemanticAlias < ApplicationRecord
+ belongs_to :work_package, inverse_of: :semantic_aliases
+
+ validates :identifier, presence: true, uniqueness: true
+ validates :work_package, presence: true
+end
diff --git a/app/policies/scm/authorization_policy.rb b/app/policies/scm/authorization_policy.rb
index 132aa7cddff..4e67e48b74d 100644
--- a/app/policies/scm/authorization_policy.rb
+++ b/app/policies/scm/authorization_policy.rb
@@ -51,7 +51,7 @@ class SCM::AuthorizationPolicy
# Determines whether the given request is a read access
# Must be implemented by descendents of this policy.
def readonly_request?(_params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
##
diff --git a/app/seeders/basic_data/model_seeder.rb b/app/seeders/basic_data/model_seeder.rb
index 5aece770aee..f2f032a0d0e 100644
--- a/app/seeders/basic_data/model_seeder.rb
+++ b/app/seeders/basic_data/model_seeder.rb
@@ -68,7 +68,7 @@ module BasicData
end
def model_attributes(model_data)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def applicable?
diff --git a/app/seeders/basic_data_seeder.rb b/app/seeders/basic_data_seeder.rb
index 733566e3d19..c2919e13860 100644
--- a/app/seeders/basic_data_seeder.rb
+++ b/app/seeders/basic_data_seeder.rb
@@ -29,7 +29,7 @@
#++
class BasicDataSeeder < CompositeSeeder
def data_seeder_classes
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def namespace
diff --git a/app/seeders/composite_seeder.rb b/app/seeders/composite_seeder.rb
index 80fb3625140..3c2ac929f30 100644
--- a/app/seeders/composite_seeder.rb
+++ b/app/seeders/composite_seeder.rb
@@ -50,7 +50,7 @@ class CompositeSeeder < Seeder
end
def data_seeder_classes
- raise NotImplementedError, "has to be implemented by subclasses"
+ raise SubclassResponsibilityError
end
def discovered_seeders
@@ -71,7 +71,7 @@ class CompositeSeeder < Seeder
end
def namespace
- raise NotImplementedError, "has to be implemented by subclasses"
+ raise SubclassResponsibilityError
end
##
diff --git a/app/seeders/demo_data/references.rb b/app/seeders/demo_data/references.rb
index 543e10f821c..9a71c86d505 100644
--- a/app/seeders/demo_data/references.rb
+++ b/app/seeders/demo_data/references.rb
@@ -48,8 +48,8 @@ module DemoData
#
# For instance:
# - Turns `##sprint:sprint_backlog` into
- # `/projects/demo-project/sprints/23/taskboard` given there is a sprint
- # referenced with :sprint_backlog and its ID here is 23.
+ # `/projects/demo-project/backlogs/sprints/23/taskboard` given there is a
+ # sprint referenced with :sprint_backlog and its ID here is 23.
#
# Alternatively `##sprint.id:sprint_backlog` is translated into just the
# id.
@@ -123,7 +123,7 @@ module DemoData
end
def sprint_link(sprint)
- url_helpers.backlogs_project_sprint_taskboard_path(
+ url_helpers.project_backlogs_sprint_taskboard_path(
sprint_id: sprint.id,
project_id: sprint.project.identifier
)
diff --git a/app/seeders/seeder.rb b/app/seeders/seeder.rb
index d858dd84432..52174768f9b 100644
--- a/app/seeders/seeder.rb
+++ b/app/seeders/seeder.rb
@@ -68,7 +68,7 @@ class Seeder
end
def seed_data!
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def applicable?
diff --git a/app/services/api/parse_resource_params_service.rb b/app/services/api/parse_resource_params_service.rb
index 23a863e82d6..fbfcf90ce99 100644
--- a/app/services/api/parse_resource_params_service.rb
+++ b/app/services/api/parse_resource_params_service.rb
@@ -60,7 +60,7 @@ module API
private
def deduce_representer(_model)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def parsing_representer
diff --git a/app/services/authorization/user_permissible_service.rb b/app/services/authorization/user_permissible_service.rb
index 2099903aef3..2579bdb82a0 100644
--- a/app/services/authorization/user_permissible_service.rb
+++ b/app/services/authorization/user_permissible_service.rb
@@ -39,37 +39,38 @@ module Authorization
def allowed_globally?(permission)
perms = contextual_permissions(permission, :global)
return false unless authorizable_user?
+ return true if admin_and_all_granted_to_admin?(perms)
cached_permissions(nil).intersect?(perms.map(&:name))
end
def allowed_in_project?(permission, projects_to_check)
- perms = contextual_permissions(permission, :project)
+ permissions = contextual_permissions(permission, :project)
return false if projects_to_check.blank?
return false unless authorizable_user?
Array(projects_to_check).all? do |project|
- allowed_in_single_project?(perms, project)
+ allowed_in_single_project?(permissions, project)
end
end
def allowed_in_any_project?(permission)
- perms = contextual_permissions(permission, :project)
+ permissions = contextual_permissions(permission, :project)
return false unless authorizable_user?
- cached_in_any_project?(perms)
+ cached_in_any_project?(permissions)
end
def allowed_in_entity?(permission, entities_to_check, entity_class)
return false if entities_to_check.blank?
return false unless authorizable_user?
- perms = contextual_permissions(permission, context_name(entity_class))
+ permissions = contextual_permissions(permission, context_name(entity_class))
entities = Array(entities_to_check)
entities.all? do |entity|
- allowed_in_single_entity?(perms, entity, entity_class)
+ allowed_in_single_entity?(permissions, entity, entity_class)
end
end
@@ -110,6 +111,7 @@ module Authorization
permissions_filtered_for_project = permissions_by_enabled_project_modules(project, permissions)
return false if permissions_filtered_for_project.empty?
+ return true if admin_and_all_granted_to_admin?(permissions)
cached_permissions(project).intersect?(permissions_filtered_for_project)
end
@@ -164,7 +166,7 @@ module Authorization
end
def admin_and_all_granted_to_admin?(permissions)
- user.admin? && permissions.all?(&:grant_to_admin?)
+ user.active_admin? && permissions.all?(&:grant_to_admin?)
end
def authorizable_user?
diff --git a/app/services/base_services/base_callable.rb b/app/services/base_services/base_callable.rb
index 7b746f3f0cd..b5951d18025 100644
--- a/app/services/base_services/base_callable.rb
+++ b/app/services/base_services/base_callable.rb
@@ -59,7 +59,7 @@ module BaseServices
attr_accessor :params
def perform(*)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
private
diff --git a/app/services/base_services/base_contracted.rb b/app/services/base_services/base_contracted.rb
index 8f028b15eb4..0cf0c93bde6 100644
--- a/app/services/base_services/base_contracted.rb
+++ b/app/services/base_services/base_contracted.rb
@@ -117,7 +117,7 @@ module BaseServices
end
def default_contract_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def namespace
diff --git a/app/services/base_services/write.rb b/app/services/base_services/write.rb
index 45edaf4705e..348a105f108 100644
--- a/app/services/base_services/write.rb
+++ b/app/services/base_services/write.rb
@@ -67,11 +67,11 @@ module BaseServices
end
def instance(_params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def default_contract_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def instance_class
diff --git a/app/services/bulk_services/project_mappings/base_create_service.rb b/app/services/bulk_services/project_mappings/base_create_service.rb
index fea2c8bbd43..644b56a1409 100644
--- a/app/services/bulk_services/project_mappings/base_create_service.rb
+++ b/app/services/bulk_services/project_mappings/base_create_service.rb
@@ -107,12 +107,12 @@ module BulkServices
# @return [Symbol] the permission required to create the mapping
def permission
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
# @return [Symbol] the column name of the mapping
def model_foreign_key_id
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def attributes_service_class
diff --git a/app/services/bulk_services/project_mappings/mapping_context_base.rb b/app/services/bulk_services/project_mappings/mapping_context_base.rb
index 9a27261df03..d2bc8df05f8 100644
--- a/app/services/bulk_services/project_mappings/mapping_context_base.rb
+++ b/app/services/bulk_services/project_mappings/mapping_context_base.rb
@@ -39,11 +39,11 @@ module BulkServices
end
def mapping_attributes_for_all_projects(params)
- raise NotImplementedError, "This method must be implemented in a subclass"
+ raise SubclassResponsibilityError
end
def incoming_projects
- raise NotImplementedError, "This method must be implemented in a subclass"
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/services/copy/dependency.rb b/app/services/copy/dependency.rb
index 2f90ca1fd20..f52a9bdf4f8 100644
--- a/app/services/copy/dependency.rb
+++ b/app/services/copy/dependency.rb
@@ -96,7 +96,7 @@ module Copy
end
def copy_dependency(params:)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb
index 2d0cb23593b..98fec862060 100644
--- a/app/services/custom_fields/hierarchy/hierarchical_item_service.rb
+++ b/app/services/custom_fields/hierarchy/hierarchical_item_service.rb
@@ -159,9 +159,9 @@ module CustomFields
Success()
end
+ # Soft delete the item and children
def soft_delete_item(item:)
- # Soft delete the item and children
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
# Returns a hash of Item => { Item => [Item] }
diff --git a/app/services/departments/add_user_service.rb b/app/services/departments/add_user_service.rb
new file mode 100644
index 00000000000..2e4cc76ad7f
--- /dev/null
+++ b/app/services/departments/add_user_service.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.
+#++
+
+module Departments
+ class AddUserService < ::BaseServices::BaseContracted
+ def initialize(department, user:, contract_class: AdminOnlyContract)
+ self.model = department
+ super(user:, contract_class:)
+ end
+
+ private
+
+ def persist(call)
+ user_id = params[:user_id].to_i
+ existing_department = find_existing_department(user_id)
+
+ if existing_department.nil? || existing_department.id == model.id
+ add_user_to_department(model, user_id, call)
+ else
+ handle_existing_membership(existing_department, user_id, call)
+ end
+
+ call
+ end
+
+ def handle_existing_membership(existing_department, user_id, call)
+ if params[:remove_from_previous_department]
+ move_user(from: existing_department, to: model, user_id:, call:)
+ else
+ call.success = false
+ call.result = existing_department
+ end
+ end
+
+ def find_existing_department(user_id)
+ GroupUser
+ .joins(:group)
+ .merge(Group.organizational_units)
+ .where(user_id:)
+ .first
+ &.group
+ end
+
+ def add_user_to_department(department, user_id, call)
+ result = Groups::UpdateService
+ .new(user:, model: department)
+ .call(add_user_ids: [user_id])
+
+ call.add_dependent!(result)
+ end
+
+ def remove_user_from_department(department, user_id, call)
+ result = Groups::UpdateService
+ .new(user:, model: department)
+ .call(remove_user_ids: [user_id])
+
+ call.add_dependent!(result)
+ end
+
+ def move_user(from:, to:, user_id:, call:)
+ Group.transaction do
+ remove_user_from_department(from, user_id, call)
+ raise ActiveRecord::Rollback unless call.success?
+
+ add_user_to_department(to, user_id, call)
+ raise ActiveRecord::Rollback unless call.success?
+ end
+ end
+ end
+end
diff --git a/app/services/groups/add_users_service.rb b/app/services/groups/add_users_service.rb
index 3740295df17..25cb572189c 100644
--- a/app/services/groups/add_users_service.rb
+++ b/app/services/groups/add_users_service.rb
@@ -42,6 +42,9 @@ module Groups
private
def persist(call)
+ validate_department_membership(call)
+ return call unless call.success?
+
sql_query = ::OpenProject::SqlSanitization
.sanitize add_to_group,
group_id: model.id,
@@ -51,6 +54,30 @@ module Groups
call
end
+ # The same validation exists in Groups::BaseContract, but it relies on in-memory
+ # group_users that are new_record?. This service inserts group_users via raw SQL,
+ # so the contract never sees them. We duplicate the check here against the params directly.
+ def validate_department_membership(call)
+ return unless model.organizational_unit?
+
+ conflicts = users_already_in_departments(params[:ids])
+
+ conflicts.each do |user_id, department_id|
+ call.errors.add(:group_users, :user_already_in_department, user_id:, department_id:)
+ end
+
+ call.success = false if conflicts.any?
+ end
+
+ def users_already_in_departments(user_ids)
+ GroupUser
+ .joins(:group)
+ .merge(Group.organizational_units)
+ .where(user_id: user_ids)
+ .where.not(group_id: model.id)
+ .pluck(:user_id, :group_id)
+ end
+
def after_perform(call)
create_inherited_roles(model)
diff --git a/app/services/groups/concerns/membership_manipulation.rb b/app/services/groups/concerns/membership_manipulation.rb
index dc074a1110d..2d24f38fb2f 100644
--- a/app/services/groups/concerns/membership_manipulation.rb
+++ b/app/services/groups/concerns/membership_manipulation.rb
@@ -65,7 +65,7 @@ module Groups::Concerns
end
def modify_members_and_roles(_params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def execute_query(query)
diff --git a/app/services/import/jira_client.rb b/app/services/import/jira_client.rb
index ae1d6c00ea5..a37da18f54f 100644
--- a/app/services/import/jira_client.rb
+++ b/app/services/import/jira_client.rb
@@ -269,7 +269,7 @@ module Import
parse_json(response)
else
raise ApiError.new(
- I18n.t("admin.jira.client.api_error", status: response.status),
+ I18n.t("admin.jira.client.#{response.status}_error", status: response.status, default: :"admin.jira.client.api_error"),
status: response.status,
response_body: response.body.to_s
)
diff --git a/app/services/incoming_emails/handlers/base.rb b/app/services/incoming_emails/handlers/base.rb
index a580f2502f9..bcb709775f1 100644
--- a/app/services/incoming_emails/handlers/base.rb
+++ b/app/services/incoming_emails/handlers/base.rb
@@ -41,12 +41,12 @@ module IncomingEmails::Handlers
# Override in subclasses to determine if this handler can process the email
def self.handles?(email, reference:, automated_email:)
- raise NotImplementedError, "Subclasses must implement can_handle? method"
+ raise SubclassResponsibilityError, "Subclasses must implement handles? method"
end
# Override in subclasses to process the email
def process
- raise NotImplementedError, "Subclasses must implement handle method"
+ raise SubclassResponsibilityError, "Subclasses must implement process method"
end
def cleaned_up_text_body
diff --git a/app/services/ldap/base_service.rb b/app/services/ldap/base_service.rb
index d6e81cb8052..51d7e059b9f 100644
--- a/app/services/ldap/base_service.rb
+++ b/app/services/ldap/base_service.rb
@@ -45,7 +45,7 @@ module Ldap
end
def perform
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
protected
diff --git a/app/services/members/concerns/notification_sender.rb b/app/services/members/concerns/notification_sender.rb
index 8255d6720e9..91b1acc226f 100644
--- a/app/services/members/concerns/notification_sender.rb
+++ b/app/services/members/concerns/notification_sender.rb
@@ -55,7 +55,7 @@ module Members::Concerns::NotificationSender
end
def event_type
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/services/work_packages/identifier_autofix.rb b/app/services/project_identifiers/identifier_autofix.rb
similarity index 86%
rename from app/services/work_packages/identifier_autofix.rb
rename to app/services/project_identifiers/identifier_autofix.rb
index b1917080f79..eab2cf347a3 100644
--- a/app/services/work_packages/identifier_autofix.rb
+++ b/app/services/project_identifiers/identifier_autofix.rb
@@ -28,11 +28,14 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-module WorkPackages
+module ProjectIdentifiers
module IdentifierAutofix
def self.job_in_progress?
GoodJob::Job
- .where(job_class: WorkPackages::IdentifierAutofix::ApplyHandlesJob.name)
+ .where(job_class: [
+ ProjectIdentifiers::ConvertInstanceToSemanticIdsJob.name,
+ ProjectIdentifiers::RevertInstanceToClassicIdsJob.name
+ ])
.exists?(finished_at: nil)
end
end
diff --git a/app/services/project_identifiers/identifier_autofix/preview_query.rb b/app/services/project_identifiers/identifier_autofix/preview_query.rb
new file mode 100644
index 00000000000..11f9f22ff04
--- /dev/null
+++ b/app/services/project_identifiers/identifier_autofix/preview_query.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 ProjectIdentifiers
+ module IdentifierAutofix
+ class PreviewQuery
+ Result = Data.define(:projects_data, :total_count)
+ DISPLAY_COUNT = 5
+
+ def call
+ analysis = ProblematicIdentifiers.new
+ total_count = analysis.count
+ projects_data = build_projects_data(analysis)
+
+ Result.new(projects_data:, total_count:)
+ end
+
+ private
+
+ def build_projects_data(analysis)
+ generate_suggestions(analysis).map do |entry|
+ entry.merge(error_reason: analysis.error_reason(entry[:current_identifier]))
+ end
+ end
+
+ def generate_suggestions(analysis)
+ ProjectIdentifierSuggestionGenerator.call(
+ preview_projects(analysis.scope),
+ exclude: analysis.exclusion_set.to_set(&:upcase)
+ )
+ end
+
+ def preview_projects(scope)
+ scope
+ .select(:id, :name, :identifier)
+ .order(:id)
+ .limit(DISPLAY_COUNT)
+ .to_a
+ end
+ end
+ end
+end
diff --git a/app/services/project_identifiers/identifier_autofix/problematic_identifiers.rb b/app/services/project_identifiers/identifier_autofix/problematic_identifiers.rb
new file mode 100644
index 00000000000..a4d0b765f3a
--- /dev/null
+++ b/app/services/project_identifiers/identifier_autofix/problematic_identifiers.rb
@@ -0,0 +1,126 @@
+# 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 ProjectIdentifiers
+ module IdentifierAutofix
+ # Identifies projects whose identifiers violate the semantic identifier format
+ # and provides classification and exclusion sets for suggestion generation.
+ #
+ # For main use by admin UI preview and batch migration job.
+ #
+ # == Performance notes
+ #
+ # * +#exclusion_set+ loads all non-problematic identifiers and historical slugs
+ # into memory. Fine for a one-off admin migration; if this ever becomes a hot
+ # path, consider a DB-backed exclusion check instead.
+ #
+ # * The regex scope conditions (+identifier ~ ?+) and +UPPER(identifier)+ won't
+ # hit a regular index. If queries get slow on large tables, a functional index
+ # on +UPPER(identifier)+ or a +pg_trgm+ GIN index would help.
+ #
+ #
+ class ProblematicIdentifiers
+ # Returns all project identifiers (current and historical) tracked by
+ # FriendlyId's slug history. Useful as an exclusion set when generating
+ # new identifiers, since any slug that was ever in use must not be reused.
+ def self.reserved_identifiers
+ FriendlyId::Slug.where(sluggable_type: Project.name).pluck(:slug).to_set
+ end
+
+ # Priority-ordered format rules for identifier classification.
+ FORMAT_RULES = [
+ [:too_long, ->(id, max) { id.length > max }],
+ [:numerical, ->(id, _) { id.match?(/\A\d+\z/) }],
+ [:starts_with_number, ->(id, _) { id.match?(/\A\d/) }],
+ [:special_characters, ->(id, _) { id.match?(/[^a-zA-Z0-9_]/) }],
+ [:not_fully_uppercased, ->(id, _) { id != id.upcase }]
+ ].freeze
+
+ def scope
+ @scope ||= exceeds_max_length
+ .or(contains_non_alphanumeric)
+ .or(starts_with_digit)
+ .or(not_fully_uppercased)
+ end
+
+ delegate :count, to: :scope
+
+ # Returns a symbol classifying why the identifier is problematic.
+ # Must handle all identifiers matched by #scope.
+ def error_reason(identifier)
+ format_error_reason(identifier) || collision_error_reason(identifier) || :unknown
+ end
+
+ # Returns a Set of identifiers that must not be suggested for new assignments.
+ # Combines currently active identifiers from non-problematic projects with
+ # historically reserved identifiers from FriendlyId slug history.
+ def exclusion_set
+ historical_identifiers | in_use_identifiers
+ end
+
+ private
+
+ def historical_identifiers
+ @historical_identifiers ||= FriendlyId::Slug
+ .where(sluggable_type: Project.name)
+ .where("LOWER(slug) NOT IN (SELECT LOWER(identifier) FROM projects)")
+ .pluck(:slug)
+ .to_set
+ end
+
+ def exceeds_max_length = Project.where("length(identifier) > ?", max_identifier_length)
+ def contains_non_alphanumeric = Project.where("identifier ~ ?", "[^a-zA-Z0-9_]")
+ def starts_with_digit = Project.where("identifier ~ ?", "^[0-9]")
+ def not_fully_uppercased = Project.where("identifier != UPPER(identifier)")
+
+ def max_identifier_length = ProjectIdentifierSuggestionGenerator::IDENTIFIER_LENGTH[:max]
+
+ def format_error_reason(identifier)
+ FORMAT_RULES.each do |reason, check|
+ return reason if check.call(identifier, max_identifier_length)
+ end
+ nil
+ end
+
+ def collision_error_reason(identifier)
+ if in_use_identifiers.include?(identifier)
+ :in_use
+ elsif historical_identifiers.include?(identifier)
+ :reserved
+ end
+ end
+
+ def in_use_identifiers
+ @in_use_identifiers ||= Project.where.not(id: scope.select(:id)).pluck(:identifier).to_set
+ end
+
+ end
+ end
+end
diff --git a/app/services/work_packages/identifier_autofix/project_identifier_suggestion_generator.rb b/app/services/project_identifiers/identifier_autofix/project_identifier_suggestion_generator.rb
similarity index 99%
rename from app/services/work_packages/identifier_autofix/project_identifier_suggestion_generator.rb
rename to app/services/project_identifiers/identifier_autofix/project_identifier_suggestion_generator.rb
index 10af6ce4777..5945eb60db4 100644
--- a/app/services/work_packages/identifier_autofix/project_identifier_suggestion_generator.rb
+++ b/app/services/project_identifiers/identifier_autofix/project_identifier_suggestion_generator.rb
@@ -28,7 +28,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
-module WorkPackages
+module ProjectIdentifiers
module IdentifierAutofix
# Generates a short uppercase semantic identifier for each project.
#
diff --git a/app/services/projects/update_service.rb b/app/services/projects/update_service.rb
index 2c0b4678cff..d4cbacef8ed 100644
--- a/app/services/projects/update_service.rb
+++ b/app/services/projects/update_service.rb
@@ -57,6 +57,7 @@ module Projects
ret = super
touch_on_custom_values_update
+ update_semantic_ids_on_identifier_change if Setting::WorkPackageIdentifier.semantic?
notify_on_identifier_renamed
send_update_notification
update_wp_versions_on_parent_change
@@ -69,6 +70,13 @@ module Projects
model.touch if only_custom_values_updated?
end
+ def update_semantic_ids_on_identifier_change
+ return unless memoized_changes["identifier"]
+
+ old_identifier = memoized_changes["identifier"].first
+ model.handle_semantic_rename(old_identifier)
+ end
+
def notify_on_identifier_renamed
return unless memoized_changes["identifier"]
diff --git a/app/services/reports/report.rb b/app/services/reports/report.rb
index 5cbc37b9153..a78bb3b4f27 100644
--- a/app/services/reports/report.rb
+++ b/app/services/reports/report.rb
@@ -47,18 +47,18 @@ class Reports::Report
# ---- every report needs to implement these methods to supply all needed data for a report -----
def field
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def rows
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def data
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def title
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/app/services/work_packages/bulk/bulked_service.rb b/app/services/work_packages/bulk/bulked_service.rb
index 06f6eae2772..0c6b29080c1 100644
--- a/app/services/work_packages/bulk/bulked_service.rb
+++ b/app/services/work_packages/bulk/bulked_service.rb
@@ -73,11 +73,11 @@ module WorkPackages
end
def alter_work_package(_work_package, _params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def call_move_hook(_work_package, _params)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/app/services/work_packages/identifier_autofix/preview_query.rb b/app/services/work_packages/identifier_autofix/preview_query.rb
deleted file mode 100644
index 0c3c54ea341..00000000000
--- a/app/services/work_packages/identifier_autofix/preview_query.rb
+++ /dev/null
@@ -1,89 +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.
-#++
-
-module WorkPackages
- module IdentifierAutofix
- class PreviewQuery
- Result = Data.define(:projects_data, :total_count)
- DISPLAY_COUNT = 5
-
- def call
- total = problematic_scope.count
- preview = problematic_scope
- .select(:id, :name, :identifier)
- .limit(DISPLAY_COUNT)
- .to_a
-
- suggestions = WorkPackages::IdentifierAutofix::ProjectIdentifierSuggestionGenerator.call(
- preview,
- exclude: reserved_identifiers | in_use_identifiers
- )
-
- projects_data = suggestions.map do |entry|
- entry.merge(error_reason: error_reason(entry[:current_identifier]))
- end
-
- Result.new(projects_data:, total_count: total)
- end
-
- private
-
- def problematic_scope
- @problematic_scope ||= Project.where(
- "length(identifier) > ? OR identifier ~ ?",
- ProjectIdentifierSuggestionGenerator::IDENTIFIER_LENGTH[:max],
- "[^a-zA-Z0-9_]"
- )
- end
-
- def error_reason(identifier)
- if identifier.length > ProjectIdentifierSuggestionGenerator::IDENTIFIER_LENGTH[:max]
- :too_long
- elsif identifier.match?(/[^a-zA-Z0-9_]/)
- :special_characters
- elsif in_use_identifiers.include?(identifier)
- :in_use
- elsif reserved_identifiers.include?(identifier)
- :reserved
- end
- end
-
- def in_use_identifiers
- @in_use_identifiers ||= Project.where.not(id: problematic_scope.select(:id)).pluck(:identifier).to_set
- end
-
- def reserved_identifiers
- # TODO: OldProjectIdentifier.pluck(:identifier).to_set
- # once the OldProjectIdentifier model and migration are added.
- Set.new
- end
- end
- end
-end
diff --git a/app/services/work_packages/update_service.rb b/app/services/work_packages/update_service.rb
index 89c4aa2da5d..833c2744447 100644
--- a/app/services/work_packages/update_service.rb
+++ b/app/services/work_packages/update_service.rb
@@ -102,12 +102,17 @@ class WorkPackages::UpdateService < BaseServices::Update
delete_relations(moved_work_packages)
move_time_entries(moved_work_packages, work_package.project_id)
move_work_package_memberships(moved_work_packages, work_package.project_id)
+ update_semantic_ids(moved_work_packages) if Setting::WorkPackageIdentifier.semantic?
end
if work_package.saved_change_to_type_id?
reset_custom_values(work_package)
end
end
+ def update_semantic_ids(work_packages)
+ work_packages.each(&:allocate_and_register_semantic_id)
+ end
+
def delete_relations(work_packages)
unless Setting.cross_project_work_package_relations?
Relation
diff --git a/modules/backlogs/app/views/rb_tasks/index.html.erb b/app/views/admin/departments/_general.html.erb
similarity index 73%
rename from modules/backlogs/app/views/rb_tasks/index.html.erb
rename to app/views/admin/departments/_general.html.erb
index 8631ae80618..edbd5dd3521 100644
--- a/modules/backlogs/app/views/rb_tasks/index.html.erb
+++ b/app/views/admin/departments/_general.html.erb
@@ -27,10 +27,8 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-
+<%=
+ settings_primer_form_with(model: @group, url: admin_department_path(@group), method: :put) do |f|
+ render Groups::Form.new(f)
+ end
+%>
diff --git a/app/views/admin/departments/_memberships.html.erb b/app/views/admin/departments/_memberships.html.erb
new file mode 100644
index 00000000000..1f862da9523
--- /dev/null
+++ b/app/views/admin/departments/_memberships.html.erb
@@ -0,0 +1,165 @@
+<%#-- 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.
+
+++#%>
+<% roles = ProjectRole.givable %>
+<% projects = Project.active.order(Arel.sql("lft")) %>
+<% memberships = @group.memberships %>
+
+
+
+ <% if @group.memberships.any? %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= Project.model_name.human %>
+
+
+
+
+
+
+
+
+ <%= t(:label_role_plural) %>
+
+
+
+
+
+
+
+
+
+
+ <% memberships.where.not(project: nil).find_each do |membership| %>
+ <% next if membership.new_record? %>
+
+ <% if projects.any? %>
+ <%= styled_form_tag(memberships_of_admin_department_path(@group), method: :post) do %>
+
+ <% end %>
+ <% end %>
+
+
diff --git a/app/views/admin/departments/edit.html.erb b/app/views/admin/departments/edit.html.erb
new file mode 100644
index 00000000000..a6fef515639
--- /dev/null
+++ b/app/views/admin/departments/edit.html.erb
@@ -0,0 +1,36 @@
+<%#-- 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), "#{t(:label_edit)} #{Group.model_name.human} #{h @group.name}" %>
+
+<% tabs = department_settings_tabs(@group) %>
+
+<%= render Admin::Departments::EditPageHeaderComponent.new(group: @group, current_user:, tabs: tabs) %>
+
+<%= render_tabs tabs %>
diff --git a/app/views/admin/departments/index.html.erb b/app/views/admin/departments/index.html.erb
new file mode 100644
index 00000000000..7b8260adb2c
--- /dev/null
+++ b/app/views/admin/departments/index.html.erb
@@ -0,0 +1,3 @@
+<%= render(Admin::Departments::PageHeaderComponent.new) %>
+
+<%= render(Admin::Departments::HierarchyLayoutComponent.new(groups: @groups, active_group: @group, add_user: @add_user, add_subgroup: @add_subgroup)) %>
diff --git a/app/views/admin/departments/new_department.html.erb b/app/views/admin/departments/new_department.html.erb
new file mode 100644
index 00000000000..197f97661e2
--- /dev/null
+++ b/app/views/admin/departments/new_department.html.erb
@@ -0,0 +1,8 @@
+<%= render(
+ Admin::Departments::DetailComponent.new(
+ group: @group,
+ ancestors: @ancestors || [],
+ child_groups: @child_groups,
+ add_subgroup: true
+ )
+ ) %>
diff --git a/app/views/admin/departments/new_user.html.erb b/app/views/admin/departments/new_user.html.erb
new file mode 100644
index 00000000000..486e6b9731c
--- /dev/null
+++ b/app/views/admin/departments/new_user.html.erb
@@ -0,0 +1,8 @@
+<%= render(
+ Admin::Departments::DetailComponent.new(
+ group: @group,
+ ancestors: @ancestors,
+ child_groups: @child_groups,
+ add_user: true
+ )
+ ) %>
diff --git a/app/views/announcement_mailer/announce.html.erb b/app/views/announcement_mailer/announce.html.erb
index a3fabee74f6..bdfdb3a701a 100644
--- a/app/views/announcement_mailer/announce.html.erb
+++ b/app/views/announcement_mailer/announce.html.erb
@@ -46,7 +46,7 @@
<%= render partial: "mailer/notification_settings_table",
locals: {
- button_url: my_reminders_url,
+ button_url: my_notifications_url(tab: "reminders"),
button_text: I18n.t(:"mail.notification.settings")
} %>
<% end %>
diff --git a/app/views/digest_mailer/work_packages.html.erb b/app/views/digest_mailer/work_packages.html.erb
index 4c981c96b7c..36e9bcbd94c 100644
--- a/app/views/digest_mailer/work_packages.html.erb
+++ b/app/views/digest_mailer/work_packages.html.erb
@@ -42,7 +42,7 @@
<%= render layout: "mailer/notification_settings_table",
locals: {
- button_url: my_reminders_url,
+ button_url: my_notifications_url(tab: "reminders"),
button_text: I18n.t(:"mail.notification.settings")
} do %>
<% if @aggregated_notifications.length > DigestMailer::MAX_SHOWN_WORK_PACKAGES %>
diff --git a/app/views/my/interface.html.erb b/app/views/my/interface.html.erb
index 3bc01fb9f44..dddb9c37ec4 100644
--- a/app/views/my/interface.html.erb
+++ b/app/views/my/interface.html.erb
@@ -41,11 +41,6 @@ See COPYRIGHT and LICENSE files for more details.
<%= error_messages_for "user" %>
-<%=
- render(Primer::Beta::Subhead.new) do |component|
- component.with_heading(tag: :h3, size: :medium) { I18n.t("activerecord.attributes.user_preference.header_look_and_feel") }
- end
-%>
<%=
settings_primer_form_with(
model: @user.pref,
@@ -58,11 +53,6 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
-<%=
- render(Primer::Beta::Subhead.new(mt: 3)) do |component|
- component.with_heading(tag: :h3, size: :medium) { I18n.t("activerecord.attributes.user_preference.header_alerts") }
- end
-%>
<%=
settings_primer_form_with(model: @user.pref, scope: :pref, url: { action: "update_settings" }, data: { turbo: false }) do |form|
render(My::AlertsForm.new(form))
diff --git a/app/views/my/notifications.html.erb b/app/views/my/notifications.html.erb
index 641c1ba1ef4..90aa8342e6e 100644
--- a/app/views/my/notifications.html.erb
+++ b/app/views/my/notifications.html.erb
@@ -27,16 +27,31 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-<% html_title(t(:label_my_account), I18n.t("js.notifications.settings.title")) -%>
+<% html_title(t(:label_my_account), t("my_account.notifications_and_email.title")) -%>
-<%=
- render(Primer::OpenProject::PageHeader.new) do |header|
- header.with_title { I18n.t("js.notifications.settings.title") }
- header.with_breadcrumbs(
- [{ href: my_account_path, text: t(:label_my_account) },
- I18n.t("js.notifications.settings.title")]
- )
- end
-%>
+<%= render(My::Notifications::ShowPageHeaderComponent.new) %>
-<%= angular_component_tag "opce-notification-settings" %>
+<% if params[:tab] == "reminders" %>
+ <%= render(
+ My::Reminders::ShowPageComponent.new(
+ user: @user,
+ global_notification_setting: @global_notification_setting,
+ update_url: { action: "update_settings" },
+ update_workdays_url: { action: "update_workdays" },
+ update_email_alerts_url: { action: "update_email_alerts" }
+ )
+ ) %>
+<% else %>
+ <%= render(
+ My::Notifications::ShowPageComponent.new(
+ user: @user,
+ global_notification_setting: @global_notification_setting,
+ update_participating_url: { action: "update_participating" },
+ update_non_participating_url: { action: "update_non_participating" },
+ update_date_alerts_url: { action: "update_date_alerts" },
+ new_project_settings_url: new_my_project_settings_path,
+ edit_project_settings_url: ->(project_id) { edit_my_project_settings_path(project_id:) },
+ project_setting_url: ->(project_id) { my_project_setting_path(project_id:) }
+ )
+ ) %>
+<% end %>
diff --git a/app/views/reminders/notification_mailer/reminder_notification.html.erb b/app/views/reminders/notification_mailer/reminder_notification.html.erb
index f6967d68d87..4d9fe588831 100644
--- a/app/views/reminders/notification_mailer/reminder_notification.html.erb
+++ b/app/views/reminders/notification_mailer/reminder_notification.html.erb
@@ -38,7 +38,7 @@
<%= render layout: "mailer/notification_settings_table",
locals: {
- button_url: my_reminders_url,
+ button_url: my_notifications_url(tab: "reminders"),
button_text: I18n.t(:"mail.notification.settings")
} do %>
<% end %>
diff --git a/app/views/sharing_mailer/shared_work_package.html.erb b/app/views/sharing_mailer/shared_work_package.html.erb
index 2f15ffa749e..b80954e2ba0 100644
--- a/app/views/sharing_mailer/shared_work_package.html.erb
+++ b/app/views/sharing_mailer/shared_work_package.html.erb
@@ -49,7 +49,7 @@
<%= render partial: "mailer/notification_settings_table",
locals: {
- button_url: my_reminders_url,
+ button_url: my_notifications_url(tab: "reminders"),
button_text: I18n.t(:"mail.notification.settings")
} %>
diff --git a/app/views/users/_notifications.html.erb b/app/views/users/_notifications.html.erb
index 24c7dde5162..b13ecbe6818 100644
--- a/app/views/users/_notifications.html.erb
+++ b/app/views/users/_notifications.html.erb
@@ -26,4 +26,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
++#%>
-<%= angular_component_tag "opce-notification-settings", inputs: { userId: @user.id } %>
+<%= render(
+ My::Notifications::ShowPageComponent.new(
+ user: @user,
+ global_notification_setting: @user.notification_settings.find_or_initialize_by(project: nil),
+ update_participating_url: update_participating_user_path(@user),
+ update_non_participating_url: update_non_participating_user_path(@user),
+ update_date_alerts_url: update_date_alerts_user_path(@user),
+ new_project_settings_url: new_project_settings_user_path(@user),
+ edit_project_settings_url: ->(project_id) { edit_project_settings_user_path(@user, project_id:) },
+ project_setting_url: ->(project_id) { project_setting_user_path(@user, project_id:) }
+ )
+ ) %>
diff --git a/app/views/users/_reminders.html.erb b/app/views/users/_reminders.html.erb
index bb5d1fb15d0..b3bfad50477 100644
--- a/app/views/users/_reminders.html.erb
+++ b/app/views/users/_reminders.html.erb
@@ -26,4 +26,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
++#%>
-<%= angular_component_tag "opce-reminder-settings", inputs: { userId: @user.id } %>
+<%= render(
+ My::Reminders::ShowPageComponent.new(
+ user: @user,
+ global_notification_setting: @user.notification_settings.find_or_initialize_by(project: nil),
+ update_url: update_reminders_user_path(@user),
+ update_workdays_url: update_workdays_user_path(@user),
+ update_email_alerts_url: update_email_alerts_user_path(@user)
+ )
+ ) %>
diff --git a/app/views/work_package_mailer/mentioned.html.erb b/app/views/work_package_mailer/mentioned.html.erb
index 9ebcfeded0f..69831d69f34 100644
--- a/app/views/work_package_mailer/mentioned.html.erb
+++ b/app/views/work_package_mailer/mentioned.html.erb
@@ -34,7 +34,7 @@
<%= render partial: "mailer/notification_settings_table",
locals: {
- button_url: my_reminders_url,
+ button_url: my_notifications_url(tab: "reminders"),
button_text: I18n.t(:"mail.notification.settings")
} %>
diff --git a/app/workers/exports/export_job.rb b/app/workers/exports/export_job.rb
index 4fad5e98617..14af27ffd7a 100644
--- a/app/workers/exports/export_job.rb
+++ b/app/workers/exports/export_job.rb
@@ -66,7 +66,7 @@ module Exports
attr_accessor :export, :current_user, :mime_type, :query, :options
def prepare!
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def list_export?
diff --git a/app/workers/import/jira_import_projects_job.rb b/app/workers/import/jira_import_projects_job.rb
index e391216981a..aea7b64f492 100644
--- a/app/workers/import/jira_import_projects_job.rb
+++ b/app/workers/import/jira_import_projects_job.rb
@@ -68,7 +68,8 @@ module Import
Import::JiraProject.where(jira_id:, jira_project_id: project_ids).find_each do |jira_project|
### PROJECT
- identifier = jira_project.payload.fetch("key").downcase
+ project_key = jira_project.payload.fetch("key")
+ identifier = Setting::WorkPackageIdentifier.semantic? ? project_key.upcase : project_key.downcase
service_call = Projects::CreateService
.new(user:, contract_class: EmptyContract)
.call(
diff --git a/app/workers/mails/deliver_job.rb b/app/workers/mails/deliver_job.rb
index 4cff5c80bb4..0aefee241ee 100644
--- a/app/workers/mails/deliver_job.rb
+++ b/app/workers/mails/deliver_job.rb
@@ -57,12 +57,12 @@ class Mails::DeliverJob < ApplicationJob
# To be implemented by subclasses.
# Returns a Mail::Message, or nil if no message should be sent.
def render_mail
- raise NotImplementedError, "SubclassResponsibility"
+ raise SubclassResponsibilityError
end
def build_mail
render_mail
- rescue NotImplementedError
+ rescue SubclassResponsibilityError
# Notify subclass of the need to implement
raise
rescue StandardError => e
diff --git a/app/workers/mails/member_job.rb b/app/workers/mails/member_job.rb
index f0b861ef773..e86ed27a4f1 100644
--- a/app/workers/mails/member_job.rb
+++ b/app/workers/mails/member_job.rb
@@ -69,11 +69,11 @@ class Mails::MemberJob < ApplicationJob
end
def send_for_group_user(_current_user, _member, _group, _message)
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def send_for_project_user(_current_user, _member, _message)
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def send_updated_global(current_user, member, member_message)
diff --git a/app/workers/mails/watcher_job.rb b/app/workers/mails/watcher_job.rb
index 8f1ecc64070..494360b9db9 100644
--- a/app/workers/mails/watcher_job.rb
+++ b/app/workers/mails/watcher_job.rb
@@ -73,6 +73,6 @@ class Mails::WatcherJob < Mails::DeliverJob
end
def action
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
end
diff --git a/app/workers/project_identifiers/convert_instance_to_semantic_ids_job.rb b/app/workers/project_identifiers/convert_instance_to_semantic_ids_job.rb
new file mode 100644
index 00000000000..29d6613aadf
--- /dev/null
+++ b/app/workers/project_identifiers/convert_instance_to_semantic_ids_job.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class ProjectIdentifiers::ConvertInstanceToSemanticIdsJob < ApplicationJob
+ include GoodJob::ActiveJobExtensions::Concurrency
+
+ good_job_control_concurrency_with(total_limit: 1)
+
+ def perform(*); end
+end
diff --git a/app/workers/project_identifiers/revert_instance_to_classic_ids_job.rb b/app/workers/project_identifiers/revert_instance_to_classic_ids_job.rb
new file mode 100644
index 00000000000..2321aabc5bb
--- /dev/null
+++ b/app/workers/project_identifiers/revert_instance_to_classic_ids_job.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class ProjectIdentifiers::RevertInstanceToClassicIdsJob < ApplicationJob
+ include GoodJob::ActiveJobExtensions::Concurrency
+
+ good_job_control_concurrency_with(total_limit: 1)
+
+ def perform(*); end
+end
diff --git a/app/workers/work_packages/bulk_job.rb b/app/workers/work_packages/bulk_job.rb
index de61a594fad..63330701ba0 100644
--- a/app/workers/work_packages/bulk_job.rb
+++ b/app/workers/work_packages/bulk_job.rb
@@ -72,7 +72,7 @@ module WorkPackages
end
def service_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def successful_status_update(call)
diff --git a/bin/setup_dev b/bin/setup_dev
index 06962d647bd..9eb4dfbd4c2 100755
--- a/bin/setup_dev
+++ b/bin/setup_dev
@@ -41,5 +41,10 @@ echo 'prefer using Overmind over Foreman if available.'
echo ""
echo 'Setting up git hooks'
-echo 'If you want to have commit hooks for rubocop and eslint errors, you can install lefthook like so:'
-echo '`bundle exec lefthook install`'
+echo 'If you want to have commit hooks for rubocop and eslint errors, you can use lefthook.'
+echo 'We provide a `lefthook.yml`. To install lefthook, use an installation method of your choice, e.g.:'
+echo '`gem install lefthook`'
+echo '(Do not forget to make the executable available on the $PATH.)'
+echo ""
+echo 'To configure the git hooks:'
+echo '`lefthook install`'
diff --git a/config/constants/settings/definition.rb b/config/constants/settings/definition.rb
index 2d6d5375dcc..73b710c064d 100644
--- a/config/constants/settings/definition.rb
+++ b/config/constants/settings/definition.rb
@@ -78,6 +78,9 @@ module Settings
app_title: {
default: "OpenProject"
},
+ organization_name: {
+ default: "My Organization"
+ },
attachment_max_size: {
default: 5120
},
@@ -1323,12 +1326,12 @@ module Settings
},
work_packages_identifier: {
description: "Defines how work packages are identified in the UI (e.g. in links and titles). " \
- "The 'numeric' option uses the work package numerical ID, " \
- "while 'alphanumeric' uses the project identifier and the work package ID separated by a dash " \
+ "The 'classic' option uses the work package numerical ID, " \
+ "while 'semantic' uses the project identifier and the work package ID separated by a dash " \
"(e.g. 'PROJA-123').",
format: :string,
allowed: -> { Setting::WorkPackageIdentifier::ALLOWED_VALUES },
- default: "numeric"
+ default: "classic"
},
work_package_list_default_highlighted_attributes: {
default: ["status", "priority", "due_date"],
@@ -1428,6 +1431,10 @@ module Settings
end
def value
+ unless (override = resolve_value_override).nil?
+ return cast(override)
+ end
+
cast(@value)
end
@@ -1444,6 +1451,8 @@ module Settings
end
def writable?
+ return false if value_override?
+
if writable.respond_to?(:call)
writable.call
else
@@ -1567,6 +1576,38 @@ module Settings
@all ||= {}
end
+ # Registers a value override block for a setting. The block is called
+ # whenever the setting's value or writability is evaluated.
+ #
+ # If the block returns a non-nil value, that value is used as the setting's
+ # value and the setting becomes non-writable. If the block returns nil,
+ # no override is applied.
+ #
+ # To override a setting with nil, return a callable: +-> { nil }+
+ #
+ # @param name [Symbol] The setting name to override.
+ # @yield A block that returns the override value, or nil to skip.
+ #
+ # @example Force a setting to true when a condition is met
+ # Settings::Definition.add_value_override(:capture_external_links) do
+ # true if MyPlugin.active?
+ # end
+ def add_value_override(name, &block)
+ (value_overrides[name.to_sym] ||= []) << block
+ end
+
+ def value_overrides
+ @value_overrides ||= {}
+ end
+
+ def clear_value_overrides(name = nil)
+ if name
+ value_overrides.delete(name.to_sym)
+ else
+ @value_overrides = {}
+ end
+ end
+
private
def file_config
@@ -1760,6 +1801,18 @@ module Settings
attr_accessor :serialized,
:writable
+ def value_override?
+ !resolve_value_override.nil?
+ end
+
+ def resolve_value_override
+ self.class.value_overrides[name.to_sym]&.each do |block|
+ result = block.call
+ return result unless result.nil?
+ end
+ nil
+ end
+
def cast(value)
return nil if value.nil?
diff --git a/config/initializers/feature_decisions.rb b/config/initializers/feature_decisions.rb
index e8101395c4a..da186951a1f 100644
--- a/config/initializers/feature_decisions.rb
+++ b/config/initializers/feature_decisions.rb
@@ -61,17 +61,15 @@ OpenProject::FeatureDecisions.add :jira_import,
description: "Enables Jira Migration Tool.",
force_active: false
-OpenProject::FeatureDecisions.add :scrum_projects,
- description: "Enables an overhauled version of the backlogs module to " \
- "support Scrum projects with a new sprint planning experience. ",
- force_active: true
-
OpenProject::FeatureDecisions.add :user_working_times,
description: "Enables tracking of user working hours and non-working days."
OpenProject::FeatureDecisions.add :wiki_enhancements,
description: "Enables Wiki enhancements, such as the Wikis tab and XWiki integration."
+OpenProject::FeatureDecisions.add :departments,
+ description: "Enables the management of departments within the organization."
+
OpenProject::FeatureDecisions.add :semantic_work_package_ids,
description: "Enables the use of semantic work package IDs, " \
"in the schema -. " \
diff --git a/config/initializers/homescreen.rb b/config/initializers/homescreen.rb
index 70b11bffdb9..932eca9cf78 100644
--- a/config/initializers/homescreen.rb
+++ b/config/initializers/homescreen.rb
@@ -45,8 +45,7 @@ OpenProject::Static::Homescreen.manage :blocks do |blocks|
if: Proc.new { OpenProject::Configuration.show_community_links? }
},
{
- name: "users",
- if: Proc.new { User.current.admin? }
+ name: "meetings"
},
{
name: "my_account",
diff --git a/config/initializers/menus.rb b/config/initializers/menus.rb
index 733be24b1cd..42425cb03e2 100644
--- a/config/initializers/menus.rb
+++ b/config/initializers/menus.rb
@@ -167,6 +167,7 @@ Redmine::MenuManager.map :account_menu do |menu|
menu.push :logout,
:signout_path,
icon: :"sign-out",
+ show_divider_before: true,
scheme: :danger,
if: ->(_) { User.current.logged? },
html: {
@@ -303,12 +304,8 @@ Redmine::MenuManager.map :my_menu do |menu|
icon: "devices"
menu.push :notifications,
{ controller: "/my", action: "notifications" },
- caption: I18n.t("js.notifications.settings.title"),
+ caption: I18n.t("my_account.notifications_and_email.title"),
icon: "bell"
- menu.push :reminders,
- { controller: "/my", action: "reminders" },
- caption: I18n.t("js.reminders.settings.title"),
- icon: "unread"
end
Redmine::MenuManager.map :admin_menu do |menu|
@@ -365,6 +362,12 @@ Redmine::MenuManager.map :admin_menu do |menu|
caption: :label_group_plural,
parent: :users_and_permissions
+ menu.push :departments,
+ { controller: "/admin/departments" },
+ if: ->(_) { User.current.admin? && OpenProject::FeatureDecisions.departments_active? },
+ caption: :label_departments,
+ parent: :users_and_permissions
+
menu.push :roles,
{ controller: "/roles" },
if: ->(_) { User.current.admin? },
@@ -629,6 +632,12 @@ Redmine::MenuManager.map :admin_menu do |menu|
caption: :label_announcement,
icon: "megaphone"
+ menu.push :admin_integrations,
+ { controller: "/github_integration/admin/settings", action: "show" },
+ if: ->(_) { User.current.admin? },
+ icon: :"git-compare",
+ caption: :label_integrations
+
menu.push :plugins,
{ controller: "/admin", action: "plugins" },
if: ->(_) { User.current.admin? },
@@ -668,12 +677,6 @@ Redmine::MenuManager.map :admin_menu do |menu|
icon: "op-enterprise-addons",
if: proc { User.current.admin? && OpenProject::Configuration.ee_manager_visible? }
- menu.push :admin_backlogs,
- { controller: "/backlogs_settings", action: :show },
- if: ->(_) { User.current.admin? },
- caption: :label_backlogs,
- icon: "op-backlogs"
-
menu.push :import,
{ controller: "/admin/import/jira/instances", action: :index },
if: ->(_) { User.current.admin? && OpenProject::FeatureDecisions.jira_import_active? },
diff --git a/config/initializers/meta_tags.rb b/config/initializers/meta_tags.rb
new file mode 100644
index 00000000000..6483cdbba9c
--- /dev/null
+++ b/config/initializers/meta_tags.rb
@@ -0,0 +1,33 @@
+# 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.
+#++
+
+MetaTags.configure do |config|
+ config.title_limit = nil
+end
diff --git a/config/initializers/permissions.rb b/config/initializers/permissions.rb
index 9d7eca42f1e..67b18ebc2fa 100644
--- a/config/initializers/permissions.rb
+++ b/config/initializers/permissions.rb
@@ -81,7 +81,11 @@ Rails.application.reloader.to_prepare do
map.permission :manage_user,
{
- users: %i[index show edit update change_status change_status_info],
+ users: %i[index show edit update change_status change_status_info
+ update_reminders update_email_alerts update_workdays
+ update_participating update_non_participating update_date_alerts
+ new_project_settings create_project_settings
+ edit_project_settings update_project_settings destroy_project_settings],
"users/memberships": %i[create update destroy],
admin: %i[index]
},
@@ -431,7 +435,7 @@ Rails.application.reloader.to_prepare do
wpt.permission :delete_work_packages,
{
work_packages: :destroy,
- "work_packages/bulk": %i[destroy reassign]
+ "work_packages/bulk": %i[delete_dialog destroy reassign]
},
permissible_on: :project,
require: :member,
diff --git a/app/workers/work_packages/identifier_autofix/apply_handles_job.rb b/config/initializers/text_formatting.rb
similarity index 73%
rename from app/workers/work_packages/identifier_autofix/apply_handles_job.rb
rename to config/initializers/text_formatting.rb
index ff2107b4a3e..e6a51576830 100644
--- a/app/workers/work_packages/identifier_autofix/apply_handles_job.rb
+++ b/config/initializers/text_formatting.rb
@@ -23,18 +23,17 @@
#
# 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.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
-class WorkPackages::IdentifierAutofix::ApplyHandlesJob < ApplicationJob
- # FIXME: The admin UI's job_in_progress? query and :change_in_progress state
- # assume at most one active instance of this job at any given time.
- # Enforce this with good_job_control_concurrency_with(perform_limit: 1)
- # when the real migration body is implemented.
- def perform
- # FIXME: replace with actual project handle migration
- sleep 5
+Rails.application.configure do |application|
+ application.config.to_prepare do
+ namespace = OpenProject::TextFormatting
+
+ namespace::Filters::PatternMatcherFilter.append_matcher namespace::Matchers::ResourceLinksMatcher
+ namespace::Filters::PatternMatcherFilter.append_matcher namespace::Matchers::WikiLinksMatcher
+ namespace::Filters::PatternMatcherFilter.append_matcher namespace::Matchers::AttributeMacros
end
end
diff --git a/config/locales/crowdin/af.yml b/config/locales/crowdin/af.yml
index eb42e744c61..ffa87615856 100644
--- a/config/locales/crowdin/af.yml
+++ b/config/locales/crowdin/af.yml
@@ -114,7 +114,7 @@ af:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ af:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ af:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ af:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ af:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ af:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ af:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ af:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ af:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ af:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ af:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Vertoon tot
attachment:
@@ -1800,6 +1853,7 @@ af:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ af:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ af:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ af:
avatar: Avatar
base: 'Algemene fout:'
body: Body
- blocks_ids: ID's van geblokkeerde werkspakkette
category: Kategorie
comment: Opmerking
comments: Opmerking
@@ -2922,6 +2977,7 @@ af:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ af:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ af:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Gedelegeerde
@@ -3484,6 +3611,7 @@ af:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Rekening
+ label_actions: Actions
label_active: Aktiewe
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ af:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Toegepaste status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ af:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Gebaseer op die gebruiker se taal
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ af:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Teken af
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Kant kieslys
@@ -4884,6 +5017,7 @@ af:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ af:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/ar.yml b/config/locales/crowdin/ar.yml
index 10ecf89720c..7ab6760119b 100644
--- a/config/locales/crowdin/ar.yml
+++ b/config/locales/crowdin/ar.yml
@@ -114,7 +114,7 @@ ar:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ar:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ar:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ar:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -411,9 +412,9 @@ ar:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -422,10 +423,14 @@ ar:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
zero: "... %{count} more projects"
one: "... 1 more project"
@@ -444,7 +449,7 @@ ar:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -714,6 +719,37 @@ ar:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1409,6 +1445,20 @@ ar:
index:
no_results_title_text: لا يوجد حالياً أي سير عمل.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1608,6 +1658,9 @@ ar:
dependencies: الاعتماديات
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1616,7 +1669,7 @@ ar:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: أظهِر حتّى
attachment:
@@ -1872,6 +1925,7 @@ ar:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1989,6 +2043,7 @@ ar:
confirmation: لا يتطابق مع %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2055,6 +2110,7 @@ ar:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2615,7 +2671,6 @@ ar:
avatar: الصورة الرمزية
base: 'خطأ عام:'
body: Body
- blocks_ids: مُعرِّفات مجموعات العمل المحظورة
category: الفئة
comment: التعليق
comments: تعليق
@@ -3152,6 +3207,7 @@ ar:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3625,6 +3681,11 @@ ar:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3687,6 +3748,72 @@ ar:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: المُسند إليه
@@ -3718,6 +3845,7 @@ ar:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: الحساب
+ label_actions: Actions
label_active: مفعّل
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3758,6 +3886,7 @@ ar:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: الحالة المطبقة
label_archive_project: Archive project
@@ -4008,7 +4137,7 @@ ar:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: الانتقال بسرعة إلى مشروع...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: استناداً إلى لغة المستخدم
label_last_activity: آخر نشاط
@@ -4046,6 +4175,10 @@ ar:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: تسجيل الخروج
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: القائمة الثانوية
@@ -5130,6 +5263,7 @@ ar:
'
setting_app_subtitle: العنوان الفرعي للتطبيق
setting_app_title: عنوان التطبيق
+ setting_organization_name: Organization name
setting_attachment_max_size: الحد الأقصى لحجم المرفقات
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5276,12 +5410,12 @@ ar:
setting_welcome_text: نص كتلة الترجيب
setting_welcome_title: عنوان كتلة الترحيب
setting_welcome_on_homescreen: كتلة الترحيب عرض على الشاشة الرئيسية
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/az.yml b/config/locales/crowdin/az.yml
index c416002675c..7ef033c2393 100644
--- a/config/locales/crowdin/az.yml
+++ b/config/locales/crowdin/az.yml
@@ -114,7 +114,7 @@ az:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ az:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ az:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ az:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ az:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ az:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ az:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ az:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ az:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ az:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ az:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ az:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ az:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ az:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ az:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ az:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ az:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ az:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ az:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ az:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ az:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ az:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ az:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ az:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/be.yml b/config/locales/crowdin/be.yml
index 48774b98d06..549d83b38f6 100644
--- a/config/locales/crowdin/be.yml
+++ b/config/locales/crowdin/be.yml
@@ -114,7 +114,7 @@ be:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ be:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ be:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ be:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -399,9 +400,9 @@ be:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -410,10 +411,14 @@ be:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -430,7 +435,7 @@ be:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -698,6 +703,37 @@ be:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1375,6 +1411,20 @@ be:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1572,6 +1622,9 @@ be:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1580,7 +1633,7 @@ be:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1836,6 +1889,7 @@ be:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1953,6 +2007,7 @@ be:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2019,6 +2074,7 @@ be:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2541,7 +2597,6 @@ be:
avatar: Аватар
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -3038,6 +3093,7 @@ be:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3509,6 +3565,11 @@ be:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3571,6 +3632,72 @@ be:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Прызначаная асоба
@@ -3602,6 +3729,7 @@ be:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3642,6 +3770,7 @@ be:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3892,7 +4021,7 @@ be:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3930,6 +4059,10 @@ be:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -5012,6 +5145,7 @@ be:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5158,12 +5292,12 @@ be:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/bg.yml b/config/locales/crowdin/bg.yml
index 9efe399f0d6..8b6a29190f0 100644
--- a/config/locales/crowdin/bg.yml
+++ b/config/locales/crowdin/bg.yml
@@ -114,7 +114,7 @@ bg:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ bg:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ bg:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ bg:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ bg:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ bg:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ bg:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ bg:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ bg:
index:
no_results_title_text: В момента няма работни потоци.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ bg:
dependencies: Зависимости
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ bg:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Показване до
attachment:
@@ -1800,6 +1853,7 @@ bg:
identity_url: URL адрес на идентичност
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ bg:
confirmation: не съвпада с %{attribute}.
could_not_be_copied: "%{dependency} не може да бъде (напълно) копирана."
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: направен е неуспешен опит за запис
@@ -1983,6 +2038,7 @@ bg:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2463,7 +2519,6 @@ bg:
avatar: Аватар
base: 'Обща грешка:'
body: Body
- blocks_ids: ИД на блокираните работни пакети
category: Категория
comment: Коментар
comments: Коментар
@@ -2920,6 +2975,7 @@ bg:
title: Добавка за големи предприятия
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3389,6 +3445,11 @@ bg:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3451,6 +3512,72 @@ bg:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Изпълнител
@@ -3482,6 +3609,7 @@ bg:
invalid_filter: Invalid notification filter
label_accessibility: Достъпност
label_account: Акаунт
+ label_actions: Действия
label_active: Активен
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3522,6 +3650,7 @@ bg:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Отмени
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Приложен статус
label_archive_project: Archive project
@@ -3772,7 +3901,7 @@ bg:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Отиди на проект...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Ключови думи
label_language_based: Въз основа на езика на потребителя
label_last_activity: Последна активност
@@ -3810,6 +3939,10 @@ bg:
label_custom_pdf_export_settings: Потребителски настройки за експортиране на PDF
label_custom_favicon: Персонализиран favicon
label_custom_touch_icon: Потребителска икона за докосване
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Изход
label_mapping_for: 'Картографиране за: %{attribute}'
label_main_menu: Главното меню
@@ -4878,6 +5011,7 @@ bg:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5024,12 +5158,12 @@ bg:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/ca.yml b/config/locales/crowdin/ca.yml
index eda8b90f7d2..76d2317774a 100644
--- a/config/locales/crowdin/ca.yml
+++ b/config/locales/crowdin/ca.yml
@@ -114,7 +114,7 @@ ca:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ca:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ca:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ca:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ ca:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ ca:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ ca:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -681,6 +686,37 @@ ca:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1340,6 +1376,20 @@ ca:
index:
no_results_title_text: Actualment no hi ha cap flux de treball.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1535,6 +1585,9 @@ ca:
dependencies: Dependències
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1543,7 +1596,7 @@ ca:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Mostrar fins
attachment:
@@ -1799,6 +1852,7 @@ ca:
identity_url: URL d'identitat
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1916,6 +1970,7 @@ ca:
confirmation: no coincideix amb el %{attribute}.
could_not_be_copied: "%{dependency} no s'ha pogut copiar (completament)."
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.
@@ -1982,6 +2037,7 @@ ca:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2462,7 +2518,6 @@ ca:
avatar: Avatar
base: 'Error General:'
body: Body
- blocks_ids: Identificadors dels paquets de treball bloquejats
category: Categoria
comment: Comentari
comments: Comentari
@@ -2919,6 +2974,7 @@ ca:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Il·limitat
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3388,6 +3444,11 @@ ca:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3450,6 +3511,72 @@ ca:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignat a
@@ -3481,6 +3608,7 @@ ca:
invalid_filter: Invalid notification filter
label_accessibility: Accessibilitat
label_account: Compte
+ label_actions: Accions
label_active: Actiu
label_activate_user: Activa usuari
label_active_in_new_projects: Activa a nous projectes
@@ -3521,6 +3649,7 @@ ca:
label_ical_access_key_generation_hint: Generat automàticament en subscriure't a un calendari.
label_ical_access_key_latest: úlitma
label_ical_access_key_revoke: Revoca
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Estat aplicat
label_archive_project: Arxiva el projecte
@@ -3771,7 +3900,7 @@ ca:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Anar al projecte...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Paraules clau
label_language_based: Basat en l'idioma de l'usuari
label_last_activity: Darrera activitat
@@ -3809,6 +3938,10 @@ ca:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Favicon personalitzat
label_custom_touch_icon: Icona "touch" personalitzada
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Tancar sessió
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Menú lateral
@@ -4871,6 +5004,7 @@ ca:
'
setting_app_subtitle: Subtítol de l'aplicació
setting_app_title: Títol de l'aplicació
+ setting_organization_name: Organization name
setting_attachment_max_size: Mida màxima dels fitxers adjunts
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5017,12 +5151,12 @@ ca:
setting_welcome_text: Bloc de text de benvinguda
setting_welcome_title: Títol del bloc de benvinguda
setting_welcome_on_homescreen: Mostrar el bloc de benvinguda a la pàgina d'inici
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Mètode de destacament per defecte
diff --git a/config/locales/crowdin/ckb-IR.yml b/config/locales/crowdin/ckb-IR.yml
index 953730cf1b2..c1fde31a195 100644
--- a/config/locales/crowdin/ckb-IR.yml
+++ b/config/locales/crowdin/ckb-IR.yml
@@ -114,7 +114,7 @@ ckb-IR:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ckb-IR:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ckb-IR:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ckb-IR:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ ckb-IR:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ ckb-IR:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ ckb-IR:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ ckb-IR:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ ckb-IR:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ ckb-IR:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ ckb-IR:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ ckb-IR:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ ckb-IR:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ ckb-IR:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ ckb-IR:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ ckb-IR:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ ckb-IR:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ ckb-IR:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ ckb-IR:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ ckb-IR:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ ckb-IR:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ ckb-IR:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ ckb-IR:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ ckb-IR:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/cs.yml b/config/locales/crowdin/cs.yml
index e58bd2eba08..397125be903 100644
--- a/config/locales/crowdin/cs.yml
+++ b/config/locales/crowdin/cs.yml
@@ -114,7 +114,7 @@ cs:
import:
title: Import
jira:
- title: Jira import
+ title: Jira Migrátor
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ cs:
title: Jira configuration
new: Nová konfigurace
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ cs:
connection_timeout: 'Připojení k serveru Jira vypršelo: %{message}'
parse_error: 'Nepodařilo se zpracovat odpověď z Jira API: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projekty
last_change: Poslední změna
@@ -162,7 +163,7 @@ cs:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -399,9 +400,9 @@ cs:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -410,10 +411,14 @@ cs:
label_autofixed_suggestion: Budoucí identifikátor
label_example_work_package_id: Příklad ID pracovního balíčku
autofix_preview:
- error_too_long: Musí mít méně než 5 znaků
+ error_too_long: Musí obsahovat maximálně 10 znaků
+ error_numerical: Nemůže být čistě číselný
+ error_starts_with_number: Nemůže začínat číslem
error_special_characters: Speciální znaky nejsou povoleny
+ error_not_fully_uppercased: Musí být napsán velkými písmeny
error_in_use: Již se používá jako identifikátor jiného projektu
error_reserved: Již se dříve používal jako identifikátor jiného projektu
+ error_unknown: Potřebuje ruční revizi
remaining_projects:
one: "... 1 další projekt"
few: "... %{count} more projects"
@@ -430,7 +435,7 @@ cs:
checkbox_label: Chápu, že se tím trvale změní všechny identifikátory pracovních balíčků
success_banner: Úspěšně aktualizován formát identifikátoru pracovního balíčku.
in_progress:
- banner_message: Identifikátory projektů jsou v současné době aktualizovány na alfanumerické projektové identifikátory. To může chvíli trvat.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -698,6 +703,37 @@ cs:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Stránkování
prev: Předchozí
@@ -1375,6 +1411,20 @@ cs:
index:
no_results_title_text: V současné době neexistují žádné pracovní postupy.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1572,6 +1622,9 @@ cs:
dependencies: Závislosti
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projekty
import/jira:
@@ -1580,7 +1633,7 @@ cs:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Zobrazit do
attachment:
@@ -1697,7 +1750,7 @@ cs:
enabled_modules: Povolené moduly
identifier: Identifikátor
latest_activity_at: Poslední aktivita
- parent: Nadřazený projekt
+ parent: Podprojekt
project_creation_wizard_enabled: Project initiation request
public_value:
title: Viditelnost
@@ -1838,6 +1891,7 @@ cs:
identity_url: Adresa URL identity
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1955,6 +2009,7 @@ cs:
confirmation: neshoduje se s %{attribute}.
could_not_be_copied: "%{dependency} nemůže být (zcela) zkopírován."
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ý.
@@ -2021,6 +2076,7 @@ cs:
attributes:
parent_id:
circular_dependency: by vytvořil kruhovou hierarchii skupin.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2102,7 +2158,7 @@ cs:
message:
cannot_move_message_to_forum_of_different_project: A message cannot be moved to a forum of a different project.
notifications:
- at_least_one_channel: Pro odesílání notifikací musí být specifikován alespoň jeden kanál
+ at_least_one_channel: Alespoň jeden kanál pro odesílání oznámení musí být specifikován.
attributes:
read_ian:
read_on_creation: 'nelze nastavit na pravdivé při vytváření oznámení '
@@ -2409,11 +2465,11 @@ cs:
member: Člen
news: Novinky
notification:
- one: Notifikace
- few: Notifikací
- many: Notifikací
- other: Notifikace
- placeholder_user: Placeholder uživatel
+ one: Oznámení
+ few: Oznámení
+ many: Oznámení
+ other: Oznámení
+ placeholder_user: placeholder uživatel
project:
one: Projekt
few: Projekty
@@ -2543,7 +2599,6 @@ cs:
avatar: Avatar
base: 'Obecná chyba:'
body: Body
- blocks_ids: ID blokovaných pracovních balíčků
category: Kategorie
comment: Komentář
comments: Komentář
@@ -3040,6 +3095,7 @@ cs:
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_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.
@@ -3505,12 +3561,17 @@ cs:
ai: Umělá Inteligence (AI)
aggregation: Agregace
api_and_webhooks: API & Webhooky
- mail_notification: E-mailové notifikace
+ mail_notification: E-mailová upozornění
mails_and_notifications: E-maily a oznámení
mcp_configurations: Protokol MCP (Model Context Protocol)
quick_add:
label: Přidat…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Poskytovatelské tokeny vydává OpenProject a umožňuje tím přístup ostatním aplikacím. Klientské tokeny jsou vydávány jinými aplikacemi a umožňují OpenProjectu přistup k nim.
no_results:
@@ -3573,6 +3634,72 @@ cs:
disabled_text: RSS tokeny nejsou administrátorem povoleny. Pro použití této funkce kontaktujte svého správce.
storages:
unknown_storage: Neznámé úložiště
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Řešitel
@@ -3591,7 +3718,7 @@ cs:
by_project: Nepřečteno dle projektu
by_reason: Důvod
inbox: Doručená pošta
- send_notifications: Pro tuto akci odeslat notifikaci
+ send_notifications: Odeslat oznámení pro tuto akci
work_packages:
subject:
created: Pracovní balíček byl vytvořen.
@@ -3604,6 +3731,7 @@ cs:
invalid_filter: Neplatný filtr oznámení
label_accessibility: Přístupnost
label_account: Účet
+ label_actions: Akce
label_active: Aktivní
label_activate_user: Aktivovat uživatele
label_active_in_new_projects: Aktivní v nových projektech
@@ -3644,6 +3772,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_add_column: Přidat sloupec
label_applied_status: Přiřazený stav
label_archive_project: Archivovat projekt
@@ -3894,7 +4023,7 @@ cs:
label_external_links: Externí odkazy
label_locale: Jazyk a region
label_jump_to_a_project: Přejít na projekt...
- label_jira_import: Jira import
+ label_jira_import: Jira Migrator
label_keyword_plural: Klíčová slova
label_language_based: Na základě jazyka uživatele
label_last_activity: Poslední aktivita
@@ -3932,6 +4061,10 @@ cs:
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_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).
+
+ '
label_logout: Odhlásit se
label_mapping_for: 'Mapování pro: %{attribute}'
label_main_menu: Boční Menu
@@ -4043,9 +4176,9 @@ cs:
label_permissions: Práva
label_permissions_report: Přehled oprávnění
label_personalize_page: Přizpůsobit tuto stránku
- label_placeholder_user: Placeholder uživatel
+ label_placeholder_user: placeholder uživatel
label_placeholder_user_new: ''
- label_placeholder_user_plural: Placeholder uživatelé
+ label_placeholder_user_plural: placeholder uživatelé
label_planning: Plánování
label_please_login: Přihlaste se prosím
label_plugins: Pluginy
@@ -4070,7 +4203,7 @@ cs:
label_project_attribute_plural: Atributy projektu
label_project_attribute_manage_link: Správa atributů produktu
label_project_count: Celkový počet projektů
- label_project_copy_notifications: Během kopírování projektu odeslat notifikace e-mailem
+ 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_latest: Nejnovější projekty
label_project_default_type: Povolit prázdný typ
@@ -4231,7 +4364,7 @@ cs:
label_version_new: Nová verze
label_version_edit: Upravit verzi
label_version_plural: Verze
- label_version_sharing_descendants: S podprojekty
+ label_version_sharing_descendants: S Podprojekty
label_version_sharing_hierarchy: S hierarchií projektu
label_version_sharing_none: Není sdíleno
label_version_sharing_system: Se všemi projekty
@@ -4369,28 +4502,28 @@ cs:
digests:
including_mention_singular: včetně zmínky
including_mention_plural: včetně %{number_mentioned} zmínění
- unread_notification_singular: 1 nepřečtená notifikace
- unread_notification_plural: "%{number_unread} nepřečtených notifikací"
+ unread_notification_singular: 1 nepřečtené oznámení
+ unread_notification_plural: "%{number_unread} nepřečtených oznámení"
you_have: Máte
logo_alt_text: Logo
mention:
subject: "%{user_name} vás zmínil v #%{id} - %{subject}"
notification:
- center: Centrum notifikací
+ center: Centrum oznámení
see_in_center: Zobrazit komentář v oznamovacím centru
settings: Změnit nastavení e-mailu
salutation: Dobrý den, %{user},
salutation_full_name: Jméno a příjmení
work_packages:
created_at: 'Vytvořeno v %{timestamp} uživatelem %{user} '
- login_to_see_all: Přihlaste se pro zobrazení všech notifikací.
+ login_to_see_all: Přihlaste se pro zobrazení všech oznámení.
mentioned: Byli jste zmíněni v komentáři
mentioned_by: "%{user} vás zmínil v komentáři OpenProject"
more_to_see:
- one: Existuje ještě 1 pracovní balíček s notifikací.
- few: Existuje ještě %{count} pracovních balíčků s notifikacema.
- many: Existuje ještě %{count} pracovních balíčků s notifikacema.
- other: Existuje ještě %{count} pracovních balíčků s notifikacema.
+ one: Máte ještě 1 pracovní balíček s notifikací.
+ few: Existuje ještě %{count} pracovních balíčků s oznámeními.
+ many: Máte ještě %{count} pracovních balíčků s notifikacemi.
+ other: Existuje ještě %{count} pracovních balíčků s oznámeními.
open_in_browser: Otevřít v prohlížeči
reason:
watched: Sledováno
@@ -4399,7 +4532,7 @@ cs:
mentioned: Zmíněné
shared: Sdílené
subscribed: vše
- prefix: 'Obdrženo z důvodu nastavení notifikací: %{reason}'
+ prefix: 'Obdrženo z důvodu nastavení oznámení: %{reason}'
date_alert_start_date: Upozornění na datum
date_alert_due_date: Upozornění na datum
reminder: Připomínka
@@ -4712,7 +4845,7 @@ cs:
permission_move_work_packages: Přesun pracovních balíčků
permission_protect_wiki_pages: Ochrana stránky wiki
permission_rename_wiki_pages: Přejmenovat stránky wiki
- permission_save_queries: Uložit zobrazení
+ permission_save_queries: Uložit pohled
permission_search_project: Hledat projekt
permission_select_custom_fields: Vybrat vlastní pole
permission_select_project_custom_fields: Vyberte atributy projektu
@@ -5014,6 +5147,7 @@ cs:
'
setting_app_subtitle: Podtitulek aplikace
setting_app_title: Název aplikace
+ setting_organization_name: Organization name
setting_attachment_max_size: Maximální velikost příloh
setting_show_work_package_attachments: Ve výchozím nastavení zobrazit přílohy na kartě souborů
setting_antivirus_scan_mode: Režim skenování
@@ -5160,12 +5294,12 @@ cs:
setting_welcome_text: Text uvítacího bloku
setting_welcome_title: Název uvítacího bloku
setting_welcome_on_homescreen: Zobrazit uvítací blok na domovské obrazovce
- setting_work_packages_identifier_numeric: Číselná posloupnost pro celou instanci (výchozí)
- setting_work_packages_identifier_numeric_caption: 'Každý pracovní balíček dostane pořadové číslo začínající číslem 1 a zvyšující se s každým novým. Čísla jsou v rámci této instance jedinečná, takže zůstávají stejná, i když se pracovní balíčky přesouvají mezi projekty.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Projektové alfanumerické identifikátory
- setting_work_packages_identifier_alphanumeric_caption: 'Každý projekt má jedinečný identifikátor, který je předřazen ID pracovního balíčku. Pokud se pracovní balíček přesune do jiného projektu, vygeneruje se nový identifikátor, ale starý zůstává funkční.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Výchozí režim zvýraznění
@@ -5240,7 +5374,7 @@ cs:
enable_subscriptions_text_html: Umožňuje uživatelům s nezbytnými oprávněními přihlásit se do OpenProject kalendářů a získat přístup k informacím o pracovním balíčku prostřednictvím externího klienta kalendáře. Poznámka: Před povolením si prosím přečtěte podrobnosti o odběru.
language_name_being_default: "%{language_name} (výchozí)"
notifications:
- events_explanation: Určuje, pro kterou událost je odeslán e-mail. Pracovní balíčky jsou z tohoto seznamu vyloučeny, protože notifikace pro ně mohou být nastavena speciálně pro každého uživatele.
+ events_explanation: Určuje, pro kterou událost je odeslán e-mail. Pracovní balíčky jsou z tohoto seznamu vyloučeny, protože oznámení pro ně mohou být nastavena speciálně pro každého uživatele.
delay_minutes_explanation: Odesílání e-mailu může být pozdrženo, aby bylo uživatelům s nakonfigurovaným v oznámení aplikace před odesláním pošty potvrzeno oznámení. Uživatelé, kteří si přečtou oznámení v aplikaci, nedostanou e-mail pro již přečtené oznámení.
other: Ostatní
passwords: Hesla
@@ -5445,7 +5579,7 @@ cs:
text_destroy_what_to_do: Co chcete udělat?
text_diff_truncated: "... Toto rozlišení bylo zkráceno, protože přesahuje maximální velikost, kterou lze zobrazit."
text_email_delivery_not_configured: |-
- Doručení e-mailu není nakonfigurováno a notifikace jsou zakázány.
+ Doručení e-mailu není nakonfigurováno a oznámení jsou zakázána.
Nakonfigurujte váš SMTP server pro jejich povolení.
text_enumeration_category_reassign_to: 'Přiřadit je k této hodnotě:'
text_enumeration_destroy_question: "%{count} objektů je přiřazeno k této hodnotě."
diff --git a/config/locales/crowdin/da.yml b/config/locales/crowdin/da.yml
index 6b11707ed26..3319f90ad8a 100644
--- a/config/locales/crowdin/da.yml
+++ b/config/locales/crowdin/da.yml
@@ -114,7 +114,7 @@ da:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ da:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ da:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ da:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ da:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ da:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ da:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -681,6 +686,37 @@ da:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1340,6 +1376,20 @@ da:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1535,6 +1585,9 @@ da:
dependencies: Aflæggere
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1543,7 +1596,7 @@ da:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1799,6 +1852,7 @@ da:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1916,6 +1970,7 @@ da:
confirmation: matcher ikke %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1982,6 +2037,7 @@ da:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2464,7 +2520,6 @@ da:
avatar: Avatar
base: 'Generel fejl:'
body: Body
- blocks_ids: ID'er for blokerede arbejdspakker
category: Kategori
comment: Kommentér
comments: Kommentér
@@ -2921,6 +2976,7 @@ da:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Ubegrænset
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3390,6 +3446,11 @@ da:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3452,6 +3513,72 @@ da:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Tildelt
@@ -3483,6 +3610,7 @@ da:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Konto
+ label_actions: Handlinger
label_active: Aktiv
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3523,6 +3651,7 @@ da:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Tildelt status
label_archive_project: Archive project
@@ -3773,7 +3902,7 @@ da:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Gå til et projekt...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Baseret på brugerens sprog
label_last_activity: Seneste aktivitet
@@ -3811,6 +3940,10 @@ da:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Log ud
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sidemenu
@@ -4877,6 +5010,7 @@ da:
'
setting_app_subtitle: Appens undertitel
setting_app_title: Appens titel
+ setting_organization_name: Organization name
setting_attachment_max_size: Maksimal størrelse for vedhæftning
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5023,12 +5157,12 @@ da:
setting_welcome_text: Velkomstblok-tekst
setting_welcome_title: Velkomstblok-titel
setting_welcome_on_homescreen: Vis velkomstblok på hjemmeskærm
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/de.yml b/config/locales/crowdin/de.yml
index 880955ff275..08b5ca7b483 100644
--- a/config/locales/crowdin/de.yml
+++ b/config/locales/crowdin/de.yml
@@ -87,11 +87,11 @@ de:
type_token_text: Ihr Enterprise-Token-Text
token_placeholder: Enterprise-Token Text hier einfügen
token_caption: Weitere Informationen über die Aktivierung der Enterprise Edition finden Sie in unserer [Dokumentation](docs_url).
- add_token: Enterprise-Edition Support Token hochladen
+ add_token: Enterprise edition Support Token hochladen
replace_token: Aktuellen Enterprise edition Support Token ersetzen
order: Enterprise on-premises bestellen
- paste: Enterprise-Edition Support Token hier einfügen
- required_for_feature: Dieses Add-on ist nur mit einem aktiven Enterprise-Edition Support-Token verfügbar.
+ paste: Enterprise edition Support Token hier einfügen
+ required_for_feature: Dieses Add-on ist nur mit einem aktiven Enterprise edition Support-Token verfügbar.
enterprise_link: Klicken Sie hier für weitere Informationen.
start_trial: Kostenlose Testversion starten
book_now: Jetzt buchen
@@ -114,7 +114,7 @@ de:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Verwenden Sie dieses Tool, um Daten aus Ihrer Jira-Instanz zu importieren. Sie können mehrere Jira-Hosts konfigurieren und auswählen, was bei jedem Importlauf importiert werden soll.
errors:
cannot_delete_with_imports: Jira-Hosts mit laufenden Importen können nicht gelöscht werden
@@ -125,8 +125,8 @@ de:
title: Jira-Konfiguration
new: Neue Konfiguration
banner:
- title: Begrenzter Import
- description: 'Dieses Importtool befindet sich derzeit in der Betaphase und kann nur grundlegende Daten importieren: Projekte, Tickets (Name, Titel, Beschreibung, Anhänge), Nutzer (Name, E-Mail, Projektmitgliedschaft), Status und Typen. Es kann keine Workflows, benutzerdefinierten Felder, Ticketbeziehungen oder Berechtigungen importieren. Wir unterstützen derzeit nur die Jira Server/Data Center Versionen 10.x und 11.x. Cloud-Instanzen werden derzeit nicht unterstützt.'
+ title: Eingeschränkte Importfähigkeiten
+ description: 'Der Jira-Migrator befindet sich derzeit in der Betaphase und kann nur grundlegende Daten importieren: Projekte, Tickets (Name, Titel, Beschreibung, Anhänge), Nutzer (Name, E-Mail, Projektmitgliedschaft), Status und Typen. Es kann keine Workflows, benutzerdefinierten Felder, Ticketbeziehungen oder Berechtigungen importieren. Wir unterstützen derzeit nur die Jira Server/Data Center Versionen 10.x und 11.x. Cloud-Instanzen werden derzeit nicht unterstützt.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ de:
connection_timeout: 'Die Verbindung zum Jira-Server wurde unterbrochen: %{message}'
parse_error: 'Die Jira API-Antwort konnte nicht gelesen werden: %{message}'
api_error: Jira API hat den Fehlerstatus %{status} zurückgegeben
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projekte
last_change: Letzte Änderung
@@ -387,7 +388,7 @@ de:
notification_text_default: "
Hallo,
Ein neues Projekt wurde erstellt: projectValue:name
Vielen Dank
\n"
work_packages_identifier:
page_header:
- description: Wählen Sie zwischen einfachen numerischen Arbeitspaket-IDs oder projektspezifischen IDs, bei denen die Projektkennung der Arbeitspaket-ID vorangestellt wird.
+ description: Wählen Sie zwischen einfachen numerischen Arbeitspaket- oder projektspezifischen Kennungen, bei denen die Projektkennung der Arbeitspaket-ID vorangestellt wird.
banner:
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 ''Beheben und speichern'', um die Kennungen für alle Projekte auf diese Weise zu aktualisieren und projektbasierte alphanumerische Bezeichner zu aktivieren.
@@ -398,10 +399,14 @@ de:
label_autofixed_suggestion: Zukünftige Kennung
label_example_work_package_id: Beispielhafte Arbeitspaket-Kennung
autofix_preview:
- error_too_long: Muss weniger als 5 Zeichen haben
+ error_too_long: Muss 10 Zeichen oder weniger sein
+ error_numerical: Kann nicht rein numerisch sein
+ error_starts_with_number: Kann nicht mit einer Zahl beginnen
error_special_characters: Sonderzeichen sind nicht erlaubt
+ error_not_fully_uppercased: Muss in Großbuchstaben sein
error_in_use: Bereits als aktive Kennung für ein anderes Projekt verwendet
error_reserved: Reserviert durch eine frühere Kennung eines anderen Projekts
+ error_unknown: Benötigt manuelle Überprüfung
remaining_projects:
one: "... 1 weiteres Projekt"
other: "... %{count} weitere Projekte"
@@ -416,7 +421,7 @@ de:
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:
- banner_message: Die Projektkennungen werden derzeit auf projektbasierte alphanumerische Identifikatoren aktualisiert. Dies kann einige Zeit in Anspruch nehmen.
+ banner_message: Die Projektkennungen werden derzeit auf projektbasierte semantische Kennungen aktualisiert. Dies kann einige Zeit in Anspruch nehmen.
workflows:
tabs:
default_transitions: Standard-Übergänge
@@ -681,6 +686,37 @@ de:
danger_dialog:
confirmation_live_message_checked: Die Schaltfläche zum Fortfahren ist nun aktiv.
confirmation_live_message_unchecked: Die Schaltfläche zum Fortfahren ist inaktiv. Sie müssen das Kontrollkästchen ankreuzen, um fortzufahren.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginierung
prev: Zurück
@@ -1293,10 +1329,10 @@ de:
tab: Titel konfigurieren
manually_editable_subjects:
label: Manuell bearbeitbare Titel
- caption: Nutzer:innen können die Titel der Arbeitspakete ohne Einschränkungen manuell eingeben und bearbeiten.
+ caption: Benutzer können die Titel der Arbeitspakete ohne Einschränkungen manuell eingeben und bearbeiten.
automatically_generated_subjects:
label: Automatisch generierte Titel
- caption: Definieren Sie ein Schema aus referenzierten Attributen und Freitext für die automatische Generierung von Arbeitspakettiteln. Nutzer:innen können diese nicht manuell editieren.
+ caption: Definieren Sie ein Schema aus referenzierten Attributen und Freitext für die automatische Generierung von Arbeitspakettiteln. Nutzer können diese nicht manuell editieren.
token:
label_with_context: "%{attribute_context}: %{attribute_label}"
context:
@@ -1339,6 +1375,20 @@ de:
index:
no_results_title_text: Derzeit gibt es keine Workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1350,7 +1400,7 @@ de:
manual_with_children: Hat Unteraufgaben aber ihre Startdaten werden ignoriert.
title:
automatic_mobile: Automatisch geplant.
- automatic_with_children: Unteraufgaben bestimmen Termine.
+ automatic_with_children: Die Termine sind durch untergeordnete Arbeitspakete bestimmt.
automatic_with_predecessor: Der Anfangstermin wird von einem Vorgänger festgelegt.
manual_mobile: Manuell geplant.
manually_scheduled: Manuell geplant – Daten unabhängig von Beziehungen.
@@ -1453,7 +1503,7 @@ de:
label_child_plural: Unteraufgaben
new_child: Neue Unteraufgabe
new_child_description: Erstellt ein zugehöriges Arbeitspaket als Unteraufgabe des aktuellen (übergeordneten) Arbeitspakets
- child: Unteraufgabe
+ child: Kind
child_description: Macht das zugehörige Arbeitspaket zu einer Unteraufgabe des aktuellen (übergeordneten) Arbeitspakets
parent: Übergeordnetes Arbeitspaket
parent_description: Wandelt das verknüpfte in ein übergeordnetes Arbeitspaket dieses Arbeitspakets um
@@ -1532,6 +1582,9 @@ de:
dependencies: Abhängigkeiten
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Kennung
+ work_package: Arbeitspaket
jira_import:
projects: Projekte
import/jira:
@@ -1540,7 +1593,7 @@ de:
personal_access_token: Persönlicher Zugangs-Token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira Import
+ jira_import: Jira-Migrator
announcements:
show_until: Anzeigen bis
attachment:
@@ -1710,7 +1763,7 @@ de:
column_names: Spalten
relations_to_type_column: Beziehungen zu %{type}
relations_of_type_column: 'Beziehungen der Art: %{type}'
- child_work_packages: Unteraufgaben
+ child_work_packages: Kinder
group_by: Gruppiere Ergebnisse nach
sort_by: Ergebnisse sortieren nach
filters: Filter
@@ -1796,6 +1849,7 @@ de:
identity_url: Identity URL
parent: Übergeordnete Gruppe
organizational_unit: Organisationseinheit
+ group_users: Group users
group_detail:
parent: Übergeordnete Gruppe
organizational_unit: Organisationseinheit
@@ -1913,6 +1967,7 @@ de:
confirmation: stimmt nicht mit %{attribute} überein.
could_not_be_copied: "%{dependency} konnte nicht (vollständig) kopiert werden."
does_not_exist: existiert nicht.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1979,6 +2034,7 @@ de:
attributes:
parent_id:
circular_dependency: würde eine zirkuläre Gruppenhierarchie erstellen.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2246,7 +2302,7 @@ de:
status_transition_invalid: ist ungültig, da kein valider Übergang vom alten zum neuen Status für die aktuelle Rolle des Nutzers existiert.
status_invalid_in_type: ist ungültig, da der aktuelle Status nicht in diesem Typ vorhanden ist.
type:
- cannot_be_milestone_due_to_children: kann kein Meilenstein werden, da dieses Arbeitspaket Unteraufgaben besitzt.
+ cannot_be_milestone_due_to_children: kann kein Meilenstein werden, da dieses Arbeitspaket Unterelemente besitzt.
priority_id:
only_active_priorities_allowed: muss aktiv sein.
category:
@@ -2459,7 +2515,6 @@ de:
avatar: Profilfoto
base: 'Allgemeiner Fehler:'
body: Body
- blocks_ids: IDs der blockierten Arbeitspakete
category: Kategorie
comment: Kommentar
comments: Kommentar
@@ -2916,6 +2971,7 @@ de:
title: Enterprise Add-on
plan_title: Enterprise %{plan} Add-on
plan_name: "%{plan} Enterprise Plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Beginnend mit dem %{plan_name} verfügbar.
unlimited: Unbegrenzt
already_have_token: 'Haben Sie bereits ein Token? Fügen Sie es über den Button unten hinzu, um zum gebuchten Enterprise-Plan zu wechseln.
@@ -3065,7 +3121,7 @@ de:
error_custom_option_not_found: Option ist nicht vorhanden.
error_enterprise_plan_needed: Sie benötigen den Enterprise-Plan %{plan}, um diese Aktion durchzuführen.
error_enterprise_activation_user_limit: Ihr Konto konnte nicht aktiviert werden (Nutzerlimit erreicht). Bitte kontaktieren Sie Ihren Administrator um Zugriff zu erhalten.
- error_enterprise_token_invalid_domain: Die Enterprise-Edition ist nicht aktiv. Die aktuelle Domain (%{actual}) entspricht nicht dem erwarteten Hostnamen (%{expected}).
+ error_enterprise_token_invalid_domain: Die Enterprise edition ist nicht aktiv. Die aktuelle Domain (%{actual}) entspricht nicht dem erwarteten Hostnamen (%{expected}).
error_failed_to_delete_entry: Fehler beim Löschen dieses Eintrags.
error_in_dependent: 'Fehler beim Versuch, abhängiges Objekt zu ändern: %{dependent_class} #%{related_id} - %{related_subject}: %{error}'
error_in_new_dependent: 'Fehler beim Versuch, abhängiges Objekt zu erstellen: %{dependent_class} - %{related_subject}: %{error}'
@@ -3353,7 +3409,7 @@ de:
dates:
working: "%{date} ist jetzt ein Arbeitstag"
non_working: "%{date} ist jetzt ein arbeitsfreier Tag"
- progress_mode_changed_to_status_based: Fortschrittberechnung wurde auf Status-bezogen gesetzt
+ progress_mode_changed_to_status_based: Fortschrittberechnung wurde auf Status-basiert gesetzt
status_excluded_from_totals_set_to_false_message: jetzt in den Gesamtwerten der Hierarchie enthalten
status_excluded_from_totals_set_to_true_message: jetzt von den Hierarchie-Gesamtwerten ausgeschlossen
status_percent_complete_changed: "% abgeschlossen von %{old_value}% auf %{new_value} % geändert"
@@ -3385,6 +3441,11 @@ de:
quick_add:
label: Hinzufügen…
my_account:
+ notifications_and_email:
+ title: Benachrichtigungen und E-Mail
+ tabs:
+ notifications: Benachrichtigungseinstellungen
+ email_reminders: E-Mail-Erinnerungen
access_tokens:
description: Provider-Tokens werden von OpenProject ausgestellt und ermöglichen anderen Anwendungen den Zugriff darauf. Client-Tokens werden von anderen Anwendungen ausgestellt und ermöglichen OpenProject den Zugriff auf sie.
no_results:
@@ -3447,6 +3508,72 @@ de:
disabled_text: RSS-Token sind vom Administrator nicht aktiviert. Bitte kontaktieren Sie Ihren Administrator, um diese Funktion zu nutzen.
storages:
unknown_storage: Unbekannter Speicher
+ email_reminders:
+ immediate_reminders:
+ title: Eine E-Mail Erinnerung an mich senden
+ mentioned: Benachrichtige mich, wenn ich erwähnt werde
+ personal_reminder: Bei persönlichen Erinnerungen benachrichtigen
+ daily_reminders:
+ title: Tägliche E-Mail-Erinnerungen für ungelesene Benachrichtigungen zusenden
+ caption: Sie erhalten diese Erinnerungen nur für ungelesene Benachrichtigungen und nur zu den von Ihnen angegebenen Zeiten. Solange Sie keine Zeitzone für Ihr Konto konfigurieren, werden die Zeiten in UTC interpretiert.
+ enabled: Tägliche E-Mail-Erinnerungen aktivieren
+ add_time: Zeit hinzufügen
+ remove_time: Zeit entfernen
+ time_slot_label: Erinnerungszeit (UTC)
+ workdays:
+ title: E-Mail-Erinnerungen an diesen Tagen erhalten
+ submit_button: Erinnerungstage aktualisieren
+ pause_reminders:
+ title: E-Mail-Benachrichtigungen pausieren
+ enabled: Tägliche E-Mail-Erinnerungen vorübergehend pausieren
+ date_range: Pausenzeiten
+ email_alerts:
+ title: E-Mail-Benachrichtigungen für andere Objekte (die keine Arbeitspakete sind)
+ news_added: Neuigkeit hinzugefügt
+ news_commented: Kommentar zu einer Neuigkeit
+ document_added: Dokument hinzugefügt
+ forum_messages: Forumsnachricht erstellt
+ wiki_page_added: Wiki-Seite hinzugefügt
+ wiki_page_updated: Wiki-Seite aktualisiert
+ membership_added: Mitgliedschaft hinzugefügt
+ membership_updated: Mitgliedschaft aktualisiert
+ submit_button: Erinnerungen aktualisieren
+ notifications:
+ participating:
+ title: Beteiligt
+ submit_button: Einstellungen aktualisieren
+ mentioned: Erwähnt
+ watched: Beobachtet
+ assignee: Zugewiesen
+ responsible: Verantwortlich
+ shared: Mit mir geteilt
+ date_alerts:
+ title: Datums-Erinnerungen
+ submit_button: Datums-Erinnerungen aktualisieren
+ start_date: Anfangstermin
+ due_date: Endtermin
+ overdue: Überfällig
+ times:
+ same_day: Am selben Tag
+ one_day_before: 1 Tag vorher
+ three_days_before: 3 Tage vorher
+ seven_days_before: 7 Tage vor
+ one_day_after: 1 Tag danach
+ three_days_after: 3 Tage danach
+ seven_days_after: 7 Tage danach
+ non_participating:
+ title: Nicht beteiligt
+ submit_button: Einstellungen aktualisieren
+ work_package_created: Neue Arbeitspakete
+ work_package_commented: Alle neuen Kommentare
+ work_package_processed: Alle Statusänderungen
+ work_package_prioritized: Alle Prioritätsänderungen
+ work_package_scheduled: Alle Datumsänderungen
+ project_specific_settings:
+ title: Projektspezifische Benachrichtigungen
+ add_button: Projektspezifische Benachrichtigungen hinzufügen
+ dialog_title: Projektspezifische Benachrichtigungen hinzufügen
+ list_header: Projekte mit spezifischen Benachrichtigungen
notifications:
reasons:
assigned: Zugewiesen an
@@ -3478,6 +3605,7 @@ de:
invalid_filter: Ungültiger Benachrichtigungsfilter
label_accessibility: Barrierefreiheit
label_account: Konto
+ label_actions: Aktionen
label_active: Aktiv
label_activate_user: Benutzer aktivieren
label_active_in_new_projects: Aktiv in neuen Projekten
@@ -3518,6 +3646,7 @@ de:
label_ical_access_key_generation_hint: Wird automatisch generiert, wenn ein Kalender abonniert wird.
label_ical_access_key_latest: neueste
label_ical_access_key_revoke: Widerrufen
+ label_integrations: Integrationen
label_add_column: Spalte hinzufügen
label_applied_status: Zugewiesener Status
label_archive_project: Projekt archivieren
@@ -3675,7 +3804,7 @@ de:
label_enumerations: Aufzählungen
label_enterprise: Enterprise
label_enterprise_active_users: "%{current}/%{limit} gebuchte aktive Nutzer"
- label_enterprise_edition: Enterprise Edition
+ label_enterprise_edition: Enterprise edition
label_enterprise_support: Enterprise Support
label_environment: Umgebung
label_estimates_and_progress: Schätzungen und Fortschritt
@@ -3768,7 +3897,7 @@ de:
label_external_links: Externe Links
label_locale: Sprache und Region
label_jump_to_a_project: Zu einem Projekt springen...
- label_jira_import: Jira Import
+ label_jira_import: Jira-Migrator
label_keyword_plural: Schlüsselwörter
label_language_based: Sprachabhängig
label_last_activity: Letzte Aktivität
@@ -3806,6 +3935,10 @@ de:
label_custom_pdf_export_settings: Benutzerdefinierte PDF-Export-Einstellungen
label_custom_favicon: Benutzerdefiniertes Favicon
label_custom_touch_icon: Benutzerdefiniertes Touch-Icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Abmelden
label_mapping_for: 'Zuordnung für: %{attribute}'
label_main_menu: Nebenmenü
@@ -4785,7 +4918,7 @@ de:
Erhöhen Sie diesen Wert zur Verbesserung der Performance, da die Erfassung des genutzten Festplattenspeichers Ressourcen-intensiv ist.
oauth_application_details_html: 'Der Client Geheimcode wird nach dem Schließen dieses Fensters nicht mehr zugänglich sein. Bitte kopieren Sie diese Werte in die Nextcloud OpenProject Integrationseinstellungen:'
oauth_application_details_link_text: Zu den Einstellungen gehen
- setup_documentation_details: 'Wenn Sie Hilfe bei der Konfiguration eines neuen Dateispeichers benötigen, konsultieren Sie bitte die Dokumentation: '
+ setup_documentation_details: 'Wenn Sie Hilfe bei der Konfiguration eines neuen Datei-Speichers benötigen, konsultieren Sie bitte die Dokumentation: '
setup_documentation_details_link_text: Dateispeicher einrichten
show_warning_details: Um diesen Dateispeicher nutzen zu können, müssen Sie das Modul und den spezifischen Speicher in den Projekteinstellungen jedes gewünschten Projekts aktivieren.
subversion:
@@ -4880,6 +5013,7 @@ de:
'
setting_app_subtitle: Applikations-Untertitel
setting_app_title: Applikations-Titel
+ setting_organization_name: Organization name
setting_attachment_max_size: Max. Dateigröße
setting_show_work_package_attachments: Anhänge standardmäßig auf dem Tab Dateien anzeigen
setting_antivirus_scan_mode: Scanmodus
@@ -5026,12 +5160,12 @@ de:
setting_welcome_text: Text für Willkommens-Block
setting_welcome_title: Titel des Willkommens-Block
setting_welcome_on_homescreen: Willkommens-Block auf Startseite anzeigen
- setting_work_packages_identifier_numeric: Instanzweite numerische Sequenz (Standard)
- setting_work_packages_identifier_numeric_caption: 'Jedes Arbeitspaket erhält eine fortlaufende Nummer, die mit 1 beginnt und mit jedem neuen Objekt erhöht wird. Die Nummern sind innerhalb dieser Instanz eindeutig. Sie bleiben also gleich, auch wenn Arbeitspakete zwischen Projekten verschoben werden.
+ setting_work_packages_identifier_classic: Instanzweite numerische Sequenz (Standard)
+ setting_work_packages_identifier_classic_caption: 'Jedes Arbeitspaket erhält eine fortlaufende Nummer, die mit 1 beginnt und mit jedem neuen Objekt erhöht wird. Die Nummern sind innerhalb dieser Instanz eindeutig. Sie bleiben also gleich, auch wenn Arbeitspakete zwischen Projekten verschoben werden.
'
- setting_work_packages_identifier_alphanumeric: Projektspezifische alphanumerische Kennungen
- setting_work_packages_identifier_alphanumeric_caption: 'Jedes Projekt hat eine eindeutige Kennung, die der Arbeitspaket-ID vorangestellt ist. Wenn ein Arbeitspaket in ein anderes Projekt verschoben wird, wird eine neue Kennung generiert, aber die alte funktioniert weiter.
+ setting_work_packages_identifier_semantic: Projektspezifische semantische Kennungen
+ setting_work_packages_identifier_semantic_caption: 'Jedes Projekt hat eine eindeutige Kennung, die der Arbeitspaket-ID vorangestellt ist. Wenn ein Arbeitspaket in ein anderes Projekt verschoben wird, wird eine neue Kennung generiert, aber die alte funktioniert weiter.
'
setting_work_package_list_default_highlighting_mode: Standard Hervorhebung
@@ -5495,7 +5629,7 @@ de:
warning_user_limit_reached_admin_html: 'Das Hinzufügen zusätzlicher Benutzer überschreitet das aktuelle Benutzerlimit. Bitte [aktualisieren Sie Ihr Abonnement](upgrade_url) um sicherzustellen, dass externe Benutzer auf diese Instanz zugreifen können.
'
- warning_user_limit_reached_instructions: 'Du hast dein Nutzerlimit erreicht (%{current}/%{max} active users). Bitte kontaktiere sales@openproject.com um deinen Enterprise Edition Plan upzugraden und weitere Nutzer hinzuzufügen.
+ warning_user_limit_reached_instructions: 'Du hast dein Nutzerlimit erreicht (%{current}/%{max} active users). Bitte kontaktiere sales@openproject.com um deinen Enterprise edition Plan upzugraden und weitere Nutzer hinzuzufügen.
'
warning_protocol_mismatch_html: ''
diff --git a/config/locales/crowdin/el.yml b/config/locales/crowdin/el.yml
index 011c6b862ea..97b4c4d6c38 100644
--- a/config/locales/crowdin/el.yml
+++ b/config/locales/crowdin/el.yml
@@ -114,7 +114,7 @@ el:
import:
title: Import
jira:
- title: Εισαγωγή από Jira
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ el:
title: Jira configuration
new: New configuration
banner:
- title: Περιορισμένη εισαγωγή
- description: 'Αυτό το εργαλείο εισαγωγής βρίσκεται επί του παρόντος σε beta έκδοση και μπορεί να εισάγει μόνο βασικά δεδομένα: έργα, ζητήματα (όνομα, τίτλος, περιγραφή, συνημμένα), χρήστες (όνομα, email, συμμετοχή σε έργα), καταστάσεις και τύπους. Δεν μπορεί να εισαγάγει ροές εργασίας, προσαρμοσμένα πεδία, σχέσεις ζητημάτων ή δικαιώματα. Προς το παρόν υποστηρίζουμε μόνο τις εκδόσεις 10.x και 11.x του Jira Server/Data Center. Προς το παρόν δεν υποστηρίζονται περιπτώσεις cloud.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ el:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ el:
run:
title: Import run
history: History
- remove_error: Μια εισαγωγή Jira δεν μπορεί να αφαιρεθεί ενώ εκτελείται
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ el:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ el:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ el:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -681,6 +686,37 @@ el:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1340,6 +1376,20 @@ el:
index:
no_results_title_text: Δεν υπάρχουν ροές εργασίας αυτήν τη στιγμή.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1535,6 +1585,9 @@ el:
dependencies: Εξαρτήσεις
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1543,7 +1596,7 @@ el:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Εμφάνιση μέχρι
attachment:
@@ -1799,6 +1852,7 @@ el:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1916,6 +1970,7 @@ el:
confirmation: δεν ταιριάζει με %{attribute}.
could_not_be_copied: "%{dependency} δεν μπόρεσε να αντιγραφεί (πλήρως)."
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: επιχειρήθηκε να εγγραφεί αλλά δεν ήταν εγγράψιμο.
@@ -1982,6 +2037,7 @@ el:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2464,7 +2520,6 @@ el:
avatar: Άβαταρ
base: 'Γενικό σφάλμα:'
body: Body
- blocks_ids: Ταυτότητες μπλοκαρισμένων πακέτων εργασίας
category: Κατηγορία
comment: Σχόλιο
comments: Σχόλιο
@@ -2921,6 +2976,7 @@ el:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Απεριόριστα
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3390,6 +3446,11 @@ el:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3452,6 +3513,72 @@ el:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Ανάθεση σε
@@ -3483,6 +3610,7 @@ el:
invalid_filter: Invalid notification filter
label_accessibility: Προσβασιμότητα
label_account: Λογαριασμός
+ label_actions: Ενέργειες
label_active: Ενεργό
label_activate_user: Ενεργοποίηση χρήστη
label_active_in_new_projects: Ενεργό σε καινούργια έργα
@@ -3523,6 +3651,7 @@ el:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Ανάκληση
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Εφαρμόστηκε η κατάσταση
label_archive_project: Αρχειοθέτηση έργου
@@ -3773,7 +3902,7 @@ el:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Μεταβείτε σε ένα έργο...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Λέξεις-κλειδιά
label_language_based: Με βάση τη γλώσσα του χρήστη
label_last_activity: Τελευταία δραστηριότητα
@@ -3811,6 +3940,10 @@ el:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Προσαρμοσμένο favicon
label_custom_touch_icon: Προσαρμοσμένο εικονίδιο αφής
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Αποσύνδεση
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Πλευρικό Μενού
@@ -4879,6 +5012,7 @@ el:
'
setting_app_subtitle: Υπότιτλος εφαρμογής
setting_app_title: Τίτλος εφαρμογής
+ setting_organization_name: Organization name
setting_attachment_max_size: Μέγιστο μέγεθος συνημμένων
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5025,12 +5159,12 @@ el:
setting_welcome_text: Μπλοκ κειμένου καλωσορίσματος
setting_welcome_title: Μπλοκ τίτλου καλωσορίσματος
setting_welcome_on_homescreen: Εμφάνιση μπλοκ καλωσορίσματος στην αρχική σελίδα
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Προεπιλεγμένη λειτουργία επισήμανσης
diff --git a/config/locales/crowdin/eo.yml b/config/locales/crowdin/eo.yml
index aa66f2747ff..17f3ace6a5e 100644
--- a/config/locales/crowdin/eo.yml
+++ b/config/locales/crowdin/eo.yml
@@ -114,7 +114,7 @@ eo:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ eo:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ eo:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ eo:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ eo:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ eo:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ eo:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ eo:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ eo:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ eo:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ eo:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Montri ĝis
attachment:
@@ -1800,6 +1853,7 @@ eo:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ eo:
confirmation: ne kongruas kun %{attribute}
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ eo:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ eo:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: ID de baritaj laborpakaĵoj
category: Kategorio
comment: Komento
comments: Komento
@@ -2922,6 +2977,7 @@ eo:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ eo:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ eo:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Asignita al
@@ -3484,6 +3611,7 @@ eo:
invalid_filter: Invalid notification filter
label_accessibility: Alirebleco
label_account: Konto
+ label_actions: Agoj
label_active: Aktiva
label_activate_user: Aktivigi uzanton
label_active_in_new_projects: Aktiva en novaj projektoj
@@ -3524,6 +3652,7 @@ eo:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Eksvalidigi
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Aplikita stato
label_archive_project: Aktivi projekton
@@ -3774,7 +3903,7 @@ eo:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Iri al la projekto...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Ŝlosilvortoj
label_language_based: Bazita sur la lingvo de la uzanto
label_last_activity: Lasta aktiveco
@@ -3812,6 +3941,10 @@ eo:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Adaptita retpaĝsimbolo
label_custom_touch_icon: Adaptita tuŝikono
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Elsaluti
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Flanka menuo
@@ -4884,6 +5017,7 @@ eo:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ eo:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/es.yml b/config/locales/crowdin/es.yml
index 377b6a64e53..12afa7ac77a 100644
--- a/config/locales/crowdin/es.yml
+++ b/config/locales/crowdin/es.yml
@@ -114,7 +114,7 @@ es:
import:
title: Importar
jira:
- title: Importación desde Jira
+ title: Migrador Jira
description: Utilice esta herramienta para importar datos desde su instancia de Jira. Puede configurar varios hosts de Jira y elegir qué importar en cada ejecución de importación.
errors:
cannot_delete_with_imports: No se puede eliminar el host de Jira con importaciones existentes
@@ -125,8 +125,8 @@ es:
title: Configuración de Jira
new: Nueva configuración
banner:
- title: Importación limitada
- description: 'Esta herramienta de importación se encuentra actualmente en fase beta y solo puede importar datos básicos: proyectos, incidencias (nombre, título, descripción, archivos adjuntos), usuarios (nombre, correo electrónico, pertenencia a proyectos), estados y tipos. No puede importar flujos de trabajo, campos personalizados, relaciones entre incidencias ni permisos. Actualmente solo es compatible con las versiones 10.x y 11.x de Jira Server/Data Center. Por el momento, no es compatible con instancias en la nube.'
+ title: Capacidades de importación limitadas
+ description: 'Este Migrador de Jira se encuentra actualmente en fase beta y solo puede importar datos básicos: proyectos, incidencias (nombre, título, descripción, archivos adjuntos), usuarios (nombre, correo electrónico, pertenencia a proyectos), estados y tipos. No puede importar flujos de trabajo, campos personalizados, relaciones entre incidencias ni permisos. Actualmente solo es compatible con las versiones 10.x y 11.x de Jira Server/Data Center. Por el momento, no es compatible con instancias en la nube.'
form:
fields:
name: Nombre
@@ -154,6 +154,7 @@ es:
connection_timeout: 'La conexión con el servidor de Jira ha expirado: %{message}'
parse_error: 'Error al analizar la respuesta de la API de Jira: %{message}'
api_error: La API de Jira ha devuelto el estado de error %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Proyectos
last_change: Última modificación
@@ -387,9 +388,9 @@ es:
notification_text_default: "
Hola,
Se ha creado un nuevo proyecto: projectValue:name
Muchas gracias
\n"
work_packages_identifier:
page_header:
- description: Elige entre identificadores numéricos básicos para los paquetes de trabajo o identificadores específicos del proyecto, en los que el identificador del proyecto se antepone al identificador del paquete de trabajo.
+ description: Elige entre los ID numéricos clásicos de los paquetes de trabajo o los ID semánticos específicos del proyecto, que añaden el identificador del proyecto al principio del ID del paquete de trabajo.
banner:
- existing_identifiers_notice: 'Los identificadores actuales de %{project_count} proyectos no cumplen los requisitos para ser identificadores alfanuméricos basados en proyectos. OpenProject puede actualizarlos automáticamente para que sean válidos, tal y como se muestra en los ejemplos siguientes. Haz clic en «Corregir automáticamente y guardar» para actualizar los identificadores de todos los proyectos de esta manera y habilitar los identificadores alfanuméricos basados en proyectos.
+ existing_identifiers_notice: 'Los identificadores actuales de %{project_count} proyectos no cumplen los requisitos para ser identificadores semánticos basados en proyectos. OpenProject puede actualizarlos automáticamente para que sean válidos, tal y como se muestra en los ejemplos siguientes. Haz clic en «Corregir automáticamente y guardar» para actualizar los identificadores de todos los proyectos de esta manera y habilitar los identificadores semánticos basados en proyectos.
'
box_header:
@@ -398,10 +399,14 @@ es:
label_autofixed_suggestion: Identificador futuro
label_example_work_package_id: Ejemplo de ID del paquete de trabajo
autofix_preview:
- error_too_long: Debe tener menos de 5 caracteres
+ error_too_long: Debe tener 10 caracteres o menos
+ error_numerical: No puede ser puramente numérico
+ error_starts_with_number: No puede comenzar con un número
error_special_characters: No se permiten caracteres especiales
+ error_not_fully_uppercased: Debe estar en mayúsculas
error_in_use: Ya está en uso como identificador activo de otro proyecto
error_reserved: Reservado por el historial de identificadores de otro proyecto
+ error_unknown: Necesita revisión manual
remaining_projects:
one: "... 1 proyecto más"
other: "... %{count} proyectos más"
@@ -416,7 +421,7 @@ es:
checkbox_label: Entiendo que esto cambiará de forma permanente todos los ID de los paquetes de trabajo
success_banner: Se ha actualizado correctamente el formato del identificador del paquete de trabajo.
in_progress:
- banner_message: Actualmente se están actualizando los identificadores de proyectos para convertirlos en identificadores alfanuméricos basados en proyectos. Esto puede llevar algún tiempo.
+ banner_message: Actualmente se están actualizando los identificadores de proyectos para convertirlos en identificadores semánticos basados en proyectos. Esto puede llevar algún tiempo.
workflows:
tabs:
default_transitions: Transiciones predeterminadas
@@ -679,6 +684,37 @@ es:
danger_dialog:
confirmation_live_message_checked: El botón para continuar ya está activo.
confirmation_live_message_unchecked: El botón para continuar ya está inactivo. Debe marcar la casilla para continuar.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginación
prev: Anterior
@@ -1338,6 +1374,20 @@ es:
index:
no_results_title_text: Actualmente no existen flujos de trabajo.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1352,7 +1402,7 @@ es:
automatic_with_children: Fechas determinadas por paquetes de trabajo secundarios.
automatic_with_predecessor: La fecha de inicio la fija un predecesor.
manual_mobile: Programado manualmente.
- manually_scheduled: Programado manualmente. No afectadas por relaciones.
+ manually_scheduled: Programado manualmente. Fechas no afectadas por relaciones.
blankslate:
title: Sin predecesores
description: Para activar la programación automática, este paquete de trabajo debe tener al menos un predecesor. Entonces se programará automáticamente para que comience después del predecesor más cercano.
@@ -1531,6 +1581,9 @@ es:
dependencies: Dependencias
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identificador
+ work_package: Paquete de trabajo
jira_import:
projects: Proyectos
import/jira:
@@ -1539,7 +1592,7 @@ es:
personal_access_token: Token de acceso personal
import/jira_open_project_reference:
jira: Jira
- jira_import: Importación desde Jira
+ jira_import: Migrador Jira
announcements:
show_until: Mostrar hasta
attachment:
@@ -1795,6 +1848,7 @@ es:
identity_url: URL de identidad
parent: Grupo principal
organizational_unit: Unidad organizativa
+ group_users: Group users
group_detail:
parent: Grupo principal
organizational_unit: Unidad organizativa
@@ -1912,6 +1966,7 @@ es:
confirmation: no coincide con %{attribute}.
could_not_be_copied: "%{dependency} no se pudo copiar (en su totalidad)."
does_not_exist: no existe.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1978,6 +2033,7 @@ es:
attributes:
parent_id:
circular_dependency: crearía una jerarquía de grupos circular.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2458,7 +2514,6 @@ es:
avatar: Avatar
base: 'Error general:'
body: Cuerpo
- blocks_ids: Identificadores de paquetes bloqueados
category: Categoría
comment: Comentario
comments: Comentario
@@ -2915,6 +2970,7 @@ es:
title: Extensión Enterprise
plan_title: Extensión Enterprise de %{plan}
plan_name: Plan Enterprise %{plan}
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Disponible a partir del %{plan_name}.
unlimited: Ilimitado
already_have_token: "¿Ya tiene un token? Añádalo utilizando el botón de abajo para actualizar al plan Enterprise reservado.\n"
@@ -3382,6 +3438,11 @@ es:
quick_add:
label: Añadir…
my_account:
+ notifications_and_email:
+ title: Notificación y correo electrónico
+ tabs:
+ notifications: Ajustes de notificación
+ email_reminders: Recordatorios por correo electrónico
access_tokens:
description: Los tokens de proveedor son emitidos por OpenProject y permiten a otras aplicaciones acceder a él. Los tokens de cliente son emitidos por otras aplicaciones y permiten a OpenProject acceder a ellos.
no_results:
@@ -3444,6 +3505,72 @@ es:
disabled_text: Los tokens RSS no están habilitados por el administrador. Póngase en contacto con su administrador para utilizar esta función.
storages:
unknown_storage: Almacenamiento desconocido
+ email_reminders:
+ immediate_reminders:
+ title: Enviarme un recordatorio por correo electrónico
+ mentioned: Notificarme cuando me mencionen
+ personal_reminder: Notificarme para recibir recordatorios personales
+ daily_reminders:
+ title: Enviarme recordatorios por correo electrónico diarios con las notificaciones sin leer
+ caption: Recibirás estos recordatorios solo para las notificaciones no leídas y únicamente a las horas que indiques. Hasta que configures una zona horaria para tu cuenta, se considerará que las horas están en UTC.
+ enabled: Habilitar recordatorios por correo electrónico diarios
+ add_time: Añadir tiempo
+ remove_time: Eliminar el tiempo
+ time_slot_label: Hora del recordatorio (UTC)
+ workdays:
+ title: Recibir recordatorios por correo electrónico en estos días
+ submit_button: Días de recordatorio de actualización
+ pause_reminders:
+ title: Pausar notificaciones por correo electrónico
+ enabled: Pausar temporalmente los recordatorios por correo electrónico diarios
+ date_range: Período de pausa
+ email_alerts:
+ title: Alertas por correo electrónico de otros elementos que no sean paquetes de trabajo
+ news_added: Noticias añadidas
+ news_commented: Comentarios en un elemento de noticias
+ document_added: Documento agregado
+ forum_messages: Mensaje publicado en el foro
+ wiki_page_added: Página wiki añadida
+ wiki_page_updated: Página wiki actualizada
+ membership_added: Subscripción añadida
+ membership_updated: Subscripción actualizada
+ submit_button: Actualizar alertas
+ notifications:
+ participating:
+ title: Participando
+ submit_button: Actualizar preferencias
+ mentioned: Mencionado
+ watched: Observando
+ assignee: Asignado
+ responsible: Responsable
+ shared: Compartido conmigo
+ date_alerts:
+ title: Alertas de fecha
+ submit_button: Alertas de fecha de actualización
+ start_date: Fecha de inicio
+ due_date: Fecha de finalización
+ overdue: Vencido
+ times:
+ same_day: El mismo día
+ one_day_before: 1 día antes
+ three_days_before: 3 días antes
+ seven_days_before: 7 días antes
+ one_day_after: 1 día después
+ three_days_after: 3 días después
+ seven_days_after: 7 días después
+ non_participating:
+ title: No participando
+ submit_button: Actualizar preferencias
+ work_package_created: Nuevos paquetes de trabajo
+ work_package_commented: Todos los nuevos comentarios
+ work_package_processed: Todos los cambios de estado
+ work_package_prioritized: Todos los cambios de prioridad
+ work_package_scheduled: Todos los cambios de fecha
+ project_specific_settings:
+ title: Configuración de notificaciones específicas de proyectos
+ add_button: Añadir notificaciones específicas del proyecto
+ dialog_title: Añadir notificaciones específicas del proyecto
+ list_header: Proyectos con notificaciones específicas
notifications:
reasons:
assigned: Asignado a
@@ -3475,6 +3602,7 @@ es:
invalid_filter: Filtro de notificación no válido
label_accessibility: Accesibilidad
label_account: Cuenta
+ label_actions: Comportamiento
label_active: Activo
label_activate_user: Activar usuario
label_active_in_new_projects: Activo en nuevos proyectos
@@ -3515,6 +3643,7 @@ es:
label_ical_access_key_generation_hint: Se genera automáticamente al suscribirse a un calendario.
label_ical_access_key_latest: último
label_ical_access_key_revoke: Revocar
+ label_integrations: Integraciones
label_add_column: Añadir columna
label_applied_status: Estado aplicado
label_archive_project: Archivar proyecto
@@ -3765,7 +3894,7 @@ es:
label_external_links: Enlaces externos
label_locale: Idioma y región
label_jump_to_a_project: Saltar a un proyecto...
- label_jira_import: Importación desde Jira
+ label_jira_import: Migrador Jira
label_keyword_plural: Palabras clave
label_language_based: Basado en el idioma del usuario
label_last_activity: Última actividad
@@ -3803,6 +3932,10 @@ es:
label_custom_pdf_export_settings: Ajustes personalizados de exportación PDF
label_custom_favicon: Icono de página personalizado
label_custom_touch_icon: Icono táctil personalizado
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Cerrar sesión
label_mapping_for: 'Asignación para: %{attribute}'
label_main_menu: Menú lateral
@@ -4869,6 +5002,7 @@ es:
'
setting_app_subtitle: Subtítulo de aplicación
setting_app_title: Título de aplicación
+ setting_organization_name: Organization name
setting_attachment_max_size: Tamaño máximo de adjunto
setting_show_work_package_attachments: Mostrar archivos adjuntos en la pestaña de archivos por defecto
setting_antivirus_scan_mode: Modo de escaneo
@@ -5015,12 +5149,12 @@ es:
setting_welcome_text: Bloque de texto de bienvenida
setting_welcome_title: Título del bloque de bienvenida
setting_welcome_on_homescreen: Mostrar bloque de bienvenida en la pagina de inicio
- setting_work_packages_identifier_numeric: Secuencia numérica para toda la instancia (predeterminada)
- setting_work_packages_identifier_numeric_caption: 'Cada paquete de trabajo recibe un número secuencial que empieza por 1 y se incrementa con cada nuevo paquete. Los números son únicos dentro de esta instancia, por lo que siguen siendo los mismos aunque los paquetes de trabajo se trasladen de un proyecto a otro.
+ setting_work_packages_identifier_classic: Secuencia numérica para toda la instancia (predeterminada)
+ setting_work_packages_identifier_classic_caption: 'Cada paquete de trabajo recibe un número secuencial que empieza por 1 y se incrementa con cada nuevo paquete. Los números son únicos dentro de esta instancia, por lo que siguen siendo los mismos aunque los paquetes de trabajo se trasladen de un proyecto a otro.
'
- setting_work_packages_identifier_alphanumeric: Identificadores alfanuméricos basados en proyectos
- setting_work_packages_identifier_alphanumeric_caption: 'Cada proyecto tiene un identificador único que se añade al principio del ID del paquete de trabajo. Si un paquete de trabajo se traslada a otro proyecto, se genera un nuevo identificador, pero el antiguo sigue funcionando.
+ setting_work_packages_identifier_semantic: Identificadores semánticos basados en proyectos
+ setting_work_packages_identifier_semantic_caption: 'Cada proyecto tiene un identificador único que se añade al principio del ID del paquete de trabajo. Si un paquete de trabajo se traslada a otro proyecto, se genera un nuevo identificador, pero el antiguo sigue funcionando.
'
setting_work_package_list_default_highlighting_mode: Modo de resaltado predeterminado
diff --git a/config/locales/crowdin/et.yml b/config/locales/crowdin/et.yml
index 6b4c80645d8..801bf891ecf 100644
--- a/config/locales/crowdin/et.yml
+++ b/config/locales/crowdin/et.yml
@@ -114,7 +114,7 @@ et:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ et:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ et:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ et:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ et:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ et:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ et:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ et:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ et:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ et:
dependencies: Sõltuvused
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ et:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ et:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ et:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ et:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ et:
avatar: Profiilipilt
base: 'Üldine tõrge:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Kategooria
comment: Kommentaar
comments: Kommentaar
@@ -2922,6 +2977,7 @@ et:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ et:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ et:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Määratud tegija
@@ -3484,6 +3611,7 @@ et:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Konto
+ label_actions: Tegevused
label_active: Aktiivne
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ et:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: viimased
label_ical_access_key_revoke: Võta tagasi
+ label_integrations: Integrations
label_add_column: Lisa veerg
label_applied_status: Rakendatud olek
label_archive_project: Arhiveeri projekt
@@ -3774,7 +3903,7 @@ et:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Mine projekti...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Märksõnad
label_language_based: Põhineb kasutaja keelel
label_last_activity: Viimane tegevus
@@ -3812,6 +3941,10 @@ et:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Logi välja
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Ääremenüü
@@ -4882,6 +5015,7 @@ et:
'
setting_app_subtitle: Rakenduse alamnimetus
setting_app_title: Rakenduse nimetus
+ setting_organization_name: Organization name
setting_attachment_max_size: Manuste suurim lubatud suurus
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5028,12 +5162,12 @@ et:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/eu.yml b/config/locales/crowdin/eu.yml
index c720818a989..1018de889c1 100644
--- a/config/locales/crowdin/eu.yml
+++ b/config/locales/crowdin/eu.yml
@@ -114,7 +114,7 @@ eu:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ eu:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ eu:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ eu:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ eu:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ eu:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ eu:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ eu:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ eu:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ eu:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ eu:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ eu:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ eu:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ eu:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ eu:
avatar: Abatarra
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ eu:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ eu:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ eu:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ eu:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ eu:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ eu:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ eu:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ eu:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ eu:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/fa.yml b/config/locales/crowdin/fa.yml
index c9e7039680f..7564579e0ad 100644
--- a/config/locales/crowdin/fa.yml
+++ b/config/locales/crowdin/fa.yml
@@ -114,7 +114,7 @@ fa:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ fa:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ fa:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ fa:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ fa:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ fa:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ fa:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ fa:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ fa:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ fa:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ fa:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ fa:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ fa:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ fa:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ fa:
avatar: چهرک
base: 'General Error:'
body: Body
- blocks_ids: شناسههای مسدود کاربستهها
category: Category
comment: نظر
comments: نظر
@@ -2922,6 +2977,7 @@ fa:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ fa:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ fa:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: نماینده
@@ -3484,6 +3611,7 @@ fa:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: حساب کاربری
+ label_actions: اقدامات
label_active: Active
label_activate_user: کاربر فعال
label_active_in_new_projects: فعال در پروژه های جدید
@@ -3524,6 +3652,7 @@ fa:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ fa:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ fa:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'نگاشت مرتبط با: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ fa:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ fa:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/fi.yml b/config/locales/crowdin/fi.yml
index f7ad960ff5d..2ed3aa6aa87 100644
--- a/config/locales/crowdin/fi.yml
+++ b/config/locales/crowdin/fi.yml
@@ -114,7 +114,7 @@ fi:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ fi:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ fi:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ fi:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ fi:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ fi:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ fi:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ fi:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ fi:
index:
no_results_title_text: Tällä hetkellä ei ole olemassa työnkulkuja.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ fi:
dependencies: Riippuvuudet
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ fi:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Näytä tähän päivään asti
attachment:
@@ -1800,6 +1853,7 @@ fi:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ fi:
confirmation: ei vastaa %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ fi:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2463,7 +2519,6 @@ fi:
avatar: Avatar
base: 'Yleinen virhe:'
body: Body
- blocks_ids: Estettyjen työpakettien tunnukset
category: Kategoria
comment: Kommentti
comments: Kommentti
@@ -2920,6 +2975,7 @@ fi:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Rajoittamaton
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3389,6 +3445,11 @@ fi:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3451,6 +3512,72 @@ fi:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Työn suorittaja
@@ -3482,6 +3609,7 @@ fi:
invalid_filter: Invalid notification filter
label_accessibility: Helppokäyttötoiminnot
label_account: Käyttäjätili
+ label_actions: Toiminnot
label_active: Aktiivinen
label_activate_user: Aktivoi käyttäjä
label_active_in_new_projects: Active in new projects
@@ -3522,6 +3650,7 @@ fi:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Käytetty tila
label_archive_project: Arkisto projekti
@@ -3772,7 +3901,7 @@ fi:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Siirry projektiin...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Pohjautuen käyttäjän kieleen
label_last_activity: Viimeinen toiminta
@@ -3810,6 +3939,10 @@ fi:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Mukautettu kuvake
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Kirjaudu ulos
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sivuvalikko
@@ -4882,6 +5015,7 @@ fi:
'
setting_app_subtitle: Ohjelman alaotsikko
setting_app_title: Ohjelman otsikko
+ setting_organization_name: Organization name
setting_attachment_max_size: Liitteen maksimikoko
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5028,12 +5162,12 @@ fi:
setting_welcome_text: Tervehdysteksti
setting_welcome_title: Tervehdyspalkki
setting_welcome_on_homescreen: Näytä tervehdyspalkki kotinäkymässä
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/fil.yml b/config/locales/crowdin/fil.yml
index 5c3dede20f2..a62b3d4fd2a 100644
--- a/config/locales/crowdin/fil.yml
+++ b/config/locales/crowdin/fil.yml
@@ -114,7 +114,7 @@ fil:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ fil:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ fil:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ fil:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ fil:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ fil:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ fil:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ fil:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ fil:
index:
no_results_title_text: Sa kasalukuyan ay walang mga workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ fil:
dependencies: Dependencia
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ fil:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: I-displey hanggang
attachment:
@@ -1800,6 +1853,7 @@ fil:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ fil:
confirmation: hindi tugma %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ fil:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ fil:
avatar: Avatar
base: 'Pangkalahatang Mali:'
body: Body
- blocks_ids: Mga ID ng naka-block na mga pakete sa gumagawa
category: Kategorya
comment: Komento
comments: Komento
@@ -2922,6 +2977,7 @@ fil:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ fil:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ fil:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Naitalaga
@@ -3484,6 +3611,7 @@ fil:
invalid_filter: Invalid notification filter
label_accessibility: Aksibilidad
label_account: Akawnt
+ label_actions: Mga Aksyon
label_active: Aktibo
label_activate_user: Aktibong gumagamit
label_active_in_new_projects: Aktibo sa bagong proyekto
@@ -3524,6 +3652,7 @@ fil:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Estadong nilapat
label_archive_project: I-archive ang proyekto
@@ -3774,7 +3903,7 @@ fil:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Tumalon sa isang proyekto...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Naka-base sa linggwahe ng gumagamit
label_last_activity: Huling aktibidad
@@ -3812,6 +3941,10 @@ fil:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Ang icon ng kustom pindutan
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Mag-sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Slide menu
@@ -4880,6 +5013,7 @@ fil:
'
setting_app_subtitle: Aplikasyong subtitle
setting_app_title: Aplikasyong pamagat
+ setting_organization_name: Organization name
setting_attachment_max_size: Paglalakip ng mataas na laki
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5026,12 +5160,12 @@ fil:
setting_welcome_text: Teskstong welcome block
setting_welcome_title: Titulo ng welcome back
setting_welcome_on_homescreen: I-display ang welcome block sa homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/fr.yml b/config/locales/crowdin/fr.yml
index 33f7d6da7d2..f354a9de73c 100644
--- a/config/locales/crowdin/fr.yml
+++ b/config/locales/crowdin/fr.yml
@@ -114,7 +114,7 @@ fr:
import:
title: Importation
jira:
- title: Importation de Jira
+ title: Migrateur Jira
description: Utilisez cet outil pour importer des données à partir de votre instance Jira. Vous pouvez configurer plusieurs hôtes Jira et choisir les données à importer à chaque cycle d'importation.
errors:
cannot_delete_with_imports: Impossible de supprimer un hôte Jira avec des importations existantes
@@ -125,8 +125,8 @@ fr:
title: Configuration de Jira
new: Nouvelle configuration
banner:
- title: Importation limitée
- description: 'Cet outil d''importation est actuellement en version bêta et ne peut importer que des données de base : projets, tickets (nom, titre, description, pièces jointes), utilisateurs (nom, e-mail, appartenance à un projet), statuts et types. Il ne peut pas importer les flux de travail, les champs personnalisés, les relations entre les tickets ou les autorisations. Nous ne prenons actuellement en charge que les versions 10.x et 11.x de Jira Server/Data Center. Les instances cloud ne sont pas prises en charge pour le moment.'
+ title: Capacités d'importation limitées
+ description: 'Cet outil Jora Migrator est actuellement en version bêta et ne peut importer que des données de base : projets, tickets (nom, titre, description, pièces jointes), utilisateurs (nom, e-mail, appartenance à un projet), statuts et types. Il ne peut pas importer les flux de travail, les champs personnalisés, les relations entre les tickets ou les autorisations. Nous ne prenons actuellement en charge que les versions 10.x et 11.x de Jira Server/Data Center. Les instances cloud ne sont pas prises en charge pour le moment.'
form:
fields:
name: Nom
@@ -154,6 +154,7 @@ fr:
connection_timeout: 'La connexion au serveur Jira a expiré : %{message}'
parse_error: 'Échec de l''analyse de la réponse de l''API Jira : %{message}'
api_error: L'API Jira a renvoyé le statut d'erreur %{status}
+ 401_error: L'API Jira a renvoyé une erreur 401. Votre jeton d'authentification peut avoir expiré ou ne pas avoir les autorisations requises. Veuillez vous assurer que le jeton appartient à un administrateur Jira.
columns:
projects: Projets
last_change: Dernière modification
@@ -162,7 +163,7 @@ fr:
run:
title: Cycle d'importation
history: Historique
- remove_error: Une importation Jira ne peut pas être supprimée lorsqu'elle est en cours d'exécution
+ remove_error: Une exécution d'importation Jira ne peut pas être supprimée lorsqu'elle est en cours d'exécution
import_blocked_error: Un autre cycle d'importation Jira est actuellement en cours ou en attente de révision. Veuillez le terminer ou l'annuler avant de commencer une nouvelle importation.
project_identifier_taken: 'Vous essayez d''importer un projet avec un identifiant déjà utilisé : %{taken_identifier}. Veuillez mettre à jour l''identifiant du projet dans Jira, puis cliquez sur Réessayer.'
blank:
@@ -387,9 +388,9 @@ fr:
notification_text_default: "
Bonjour,
Un nouveau projet a été créé : projectValue:name
Nous vous remercions de votre attention et vous prions d'agréer nos salutations distinguées.
\n"
work_packages_identifier:
page_header:
- description: Vous avez le choix entre des identifiants numériques de base pour les lots de travail et des identifiants spécifiques aux projets qui ajoutent l'identifiant du projet à l'identifiant du lot de travail.
+ description: Vous avez le choix entre des identifiants numériques classiques pour les lots de travaux et des identifiants sémantiques spécifiques aux projets, qui ajoutent l'identifiant du projet à l'identifiant du lot de travaux.
banner:
- existing_identifiers_notice: 'Les identifiants existants de %{project_count} projets ne répondent pas aux exigences des identifiants alphanumériques basés sur les projets. OpenProject peut les mettre à jour automatiquement pour qu''ils soient valides, comme dans les exemples ci-dessous. Cliquez sur "Autofixer et sauvegarder" pour mettre à jour les identifiants de tous les projets de cette manière et activer les identifiants alphanumériques basés sur le projet.
+ existing_identifiers_notice: 'Les identifiants existants de %{project_count} projets ne répondent pas aux exigences des identifiants sémantiques basés sur les projets. OpenProject peut les mettre à jour automatiquement pour qu''ils soient valides, comme dans les exemples ci-dessous. Cliquez sur « Corriger automatiquement et enregistrer » pour mettre à jour les identifiants de tous les projets de cette manière et activer les identifiants sémantiques basés sur les projets.
'
box_header:
@@ -398,10 +399,14 @@ fr:
label_autofixed_suggestion: Futur identifiant
label_example_work_package_id: Exemple d'identifiant de lot de travaux
autofix_preview:
- error_too_long: Doit avoir moins de 5 caractères
+ error_too_long: Doit être composé de 10 caractères ou moins
+ error_numerical: Ne peut être purement numérique
+ error_starts_with_number: Ne peut pas commencer par un chiffre
error_special_characters: Caractères spéciaux non autorisés
+ error_not_fully_uppercased: Doit être en majuscules
error_in_use: Déjà utilisé comme alias actif d'un autre projet
error_reserved: Réservé par l'historique des alias d'un autre projet
+ error_unknown: Nécessite une vérification manuelle
remaining_projects:
one: "... 1 projet supplémentaire"
other: "... %{count} projets supplémentaires"
@@ -416,7 +421,7 @@ fr:
checkbox_label: Je comprends que cela changera définitivement tous les identifiants du lot de travaux
success_banner: Le format de l'identifiant du lot de travaux a été mis à jour.
in_progress:
- banner_message: Les identifiants de projet sont actuellement mis à jour pour devenir des identifiants alphanumériques basés sur les projets. Cela peut prendre un certain temps.
+ banner_message: Les identifiants de projet sont actuellement mis à jour pour devenir des identifiants sémantiques basés sur les projets. Cela peut prendre un certain temps.
workflows:
tabs:
default_transitions: Transitions par défaut
@@ -682,6 +687,37 @@ fr:
danger_dialog:
confirmation_live_message_checked: Le bouton pour continuer est maintenant actif.
confirmation_live_message_unchecked: Le bouton pour continuer est maintenant inactif. Vous devez cocher la case pour continuer.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Précédent
@@ -1334,6 +1370,20 @@ fr:
index:
no_results_title_text: Il n'y a actuellement aucun flux de travail.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1529,6 +1579,9 @@ fr:
dependencies: Dépendances
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifiant
+ work_package: Lot de travaux
jira_import:
projects: Projets
import/jira:
@@ -1537,7 +1590,7 @@ fr:
personal_access_token: Jeton d'accès personnel
import/jira_open_project_reference:
jira: Jira
- jira_import: Importation de Jira
+ jira_import: Migrateur Jira
announcements:
show_until: Afficher jusqu'à
attachment:
@@ -1793,6 +1846,7 @@ fr:
identity_url: URL d'identité
parent: Groupe parent
organizational_unit: Unité organisationnelle
+ group_users: Group users
group_detail:
parent: Groupe parent
organizational_unit: Unité organisationnelle
@@ -1910,6 +1964,7 @@ fr:
confirmation: ne correspond pas à %{attribute}.
could_not_be_copied: "%{dependency} n'a pas pu être copié (entièrement)."
does_not_exist: n'existe pas.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1976,6 +2031,7 @@ fr:
attributes:
parent_id:
circular_dependency: créerait une hiérarchie de groupe circulaire.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2458,7 +2514,6 @@ fr:
avatar: Avatar
base: 'Erreur générale :'
body: Corps
- blocks_ids: IDs des lots de travaux bloqués
category: Catégorie
comment: Commentaire
comments: Commentaire
@@ -2915,6 +2970,7 @@ fr:
title: Module Enterprise
plan_title: Add-on Enterprise %{plan}
plan_name: Abonnement Enterprise %{plan}
+ trial_text: Cette fonctionnalité est incluse dans votre essai en cours d'entreprise.
plan_text_html: Disponible à partir de l'abonnement %{plan_name}.
unlimited: Illimité
already_have_token: 'Vous avez déjà un jeton ? Ajoutez-le en utilisant le bouton ci-dessous pour passer à l''abonnement Enterprise réservé.
@@ -3384,6 +3440,11 @@ fr:
quick_add:
label: Ajouter…
my_account:
+ notifications_and_email:
+ title: Notification et e-mail
+ tabs:
+ notifications: Paramètres de notifications
+ email_reminders: Rappels par e-mail
access_tokens:
description: Les jetons de fournisseur sont émis par OpenProject, ce qui permet à d'autres applications d'y accéder. Les jetons clients sont émis par d'autres applications, permettant à OpenProject d'y accéder.
no_results:
@@ -3446,6 +3507,72 @@ fr:
disabled_text: Les jetons RSS ne sont pas activés par l'administrateur. Veuillez contacter votre administrateur pour utiliser cette fonctionnalité.
storages:
unknown_storage: Espace de stockage inconnu
+ email_reminders:
+ immediate_reminders:
+ title: M'envoyer un rappel par e-mail
+ mentioned: M'avertir lorsque je suis mentionné(e)
+ personal_reminder: M'avertir pour les rappels personnels
+ daily_reminders:
+ title: M'envoyer des rappels quotidiens par e-mail pour les notifications non lues
+ caption: Vous ne recevrez ces rappels que pour les notifications non lues et seulement aux heures que vous aurez spécifiées. Tant que vous n'aurez pas configuré un fuseau horaire pour votre compte, les heures seront interprétées comme étant en UTC.
+ enabled: Activer les rappels quotidiens par e-mail
+ add_time: Ajouter une heure
+ remove_time: Supprimer l'heure
+ time_slot_label: Heure de rappel (UTC)
+ workdays:
+ title: Recevoir des rappels par e-mail aux jours spécifiés
+ submit_button: Mettre à jour les jours de rappel
+ pause_reminders:
+ title: Suspendre les notifications par e-mail
+ enabled: Suspendre temporairement les rappels quotidiens par e-mail
+ date_range: Période de pause
+ email_alerts:
+ title: Alertes par e-mail pour les autres éléments qui ne sont pas des lots de travaux
+ news_added: Actualités ajoutées
+ news_commented: Commenter un article d'actualité
+ document_added: Document ajouté
+ forum_messages: Message de forum publié
+ wiki_page_added: Page wiki ajoutée
+ wiki_page_updated: Page wiki mise à jour
+ membership_added: Adhésion ajoutée
+ membership_updated: Adhésion mise à jour
+ submit_button: Mettre à jour les alertes
+ notifications:
+ participating:
+ title: Participant
+ submit_button: Mettre à jour les préférences
+ mentioned: Mentionné
+ watched: En cours
+ assignee: Personne assignée
+ responsible: Responsable
+ shared: Partagé avec moi
+ date_alerts:
+ title: Alertes de date
+ submit_button: Mettre à jour les alertes de date
+ start_date: Date de début
+ due_date: Date de fin
+ overdue: En retard
+ times:
+ same_day: Le même jour
+ one_day_before: 1 jour avant
+ three_days_before: 3 jours avant
+ seven_days_before: 7 jours avant
+ one_day_after: 1 jour après
+ three_days_after: 3 jours après
+ seven_days_after: 7 jours après
+ non_participating:
+ title: Non participant
+ submit_button: Mettre à jour les préférences
+ work_package_created: Nouveaux lots de travaux
+ work_package_commented: Tous les nouveaux commentaires
+ work_package_processed: Tous les changements de statut
+ work_package_prioritized: Tous les changements de priorité
+ work_package_scheduled: Tous les changements de date
+ project_specific_settings:
+ title: Paramètres de notification spécifiques au projet
+ add_button: Ajouter des notifications spécifiques au projet
+ dialog_title: Ajouter des notifications spécifiques au projet
+ list_header: Projets avec notifications spécifiques
notifications:
reasons:
assigned: Personne assignée
@@ -3477,6 +3604,7 @@ fr:
invalid_filter: Filtre de notification invalide
label_accessibility: Accessibilité
label_account: Compte
+ label_actions: Actions
label_active: Actif
label_activate_user: Activer l’utilisateur
label_active_in_new_projects: Activer dans de nouveaux projets
@@ -3517,6 +3645,7 @@ fr:
label_ical_access_key_generation_hint: Généré automatiquement lors de l'abonnement à un calendrier.
label_ical_access_key_latest: Dernier
label_ical_access_key_revoke: Révoquer
+ label_integrations: Intégrations
label_add_column: Ajouter une colonne
label_applied_status: Statut appliqué
label_archive_project: Archiver le projet
@@ -3767,7 +3896,7 @@ fr:
label_external_links: Liens externes
label_locale: Langue et région
label_jump_to_a_project: Aller à un projet…
- label_jira_import: Importation de Jira
+ label_jira_import: Jira Migrator
label_keyword_plural: Mots clés
label_language_based: Basé sur la langue de l'utilisateur
label_last_activity: Dernière activité
@@ -3805,6 +3934,10 @@ fr:
label_custom_pdf_export_settings: Paramètres d'exportation PDF personnalisés
label_custom_favicon: Favicon personnalisé
label_custom_touch_icon: Icône de contact personnalisé
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Déconnexion
label_mapping_for: 'Mapping pour : %{attribute}'
label_main_menu: Menu principal
@@ -4875,6 +5008,7 @@ fr:
'
setting_app_subtitle: Sous-titre de l'Application
setting_app_title: Titre de l'Application
+ setting_organization_name: Organization name
setting_attachment_max_size: Taille maximale de la pièce jointe
setting_show_work_package_attachments: Afficher les pièces jointes dans l'onglet des fichiers par défaut
setting_antivirus_scan_mode: Mode analyse
@@ -5021,12 +5155,12 @@ fr:
setting_welcome_text: Bloc de texte de bienvenue
setting_welcome_title: Bloc de titre de bienvenue
setting_welcome_on_homescreen: Afficher le bloc de bienvenue sur l'écran d'accueil
- setting_work_packages_identifier_numeric: Séquence numérique à l'échelle de l'instance (par défaut)
- setting_work_packages_identifier_numeric_caption: 'Chaque lot de travaux obtient un numéro séquentiel commençant par 1 et incrémenté à chaque nouveau. Les nombres sont uniques dans cette instance, donc ils restent les mêmes même si les lots de travaux sont déplacés entre les projets.
+ setting_work_packages_identifier_classic: Séquence numérique à l'échelle de l'instance (par défaut)
+ setting_work_packages_identifier_classic_caption: 'Chaque lot de travaux obtient un numéro séquentiel commençant par 1 et incrémenté à chaque nouveau. Les nombres sont uniques dans cette instance, donc ils restent les mêmes même si les lots de travaux sont déplacés entre les projets.
'
- setting_work_packages_identifier_alphanumeric: Identifiants alphanumériques basés sur le projet
- setting_work_packages_identifier_alphanumeric_caption: 'Chaque projet a un identifiant unique qui est préfixé à l''ID du lot de travaux. Si un lot de travaux a été déplacé vers un autre projet, un nouvel identifiant est généré, mais l''ancien continue de fonctionner.
+ setting_work_packages_identifier_semantic: Identifiants sémantiques basés sur le projet
+ setting_work_packages_identifier_semantic_caption: 'Chaque projet a un identifiant unique qui est préfixé à l''ID du lot de travaux. Si un lot de travaux a été déplacé vers un autre projet, un nouvel identifiant est généré, mais l''ancien continue de fonctionner.
'
setting_work_package_list_default_highlighting_mode: Mode de surbrillance par défaut
diff --git a/config/locales/crowdin/he.yml b/config/locales/crowdin/he.yml
index 78cc43c89f3..ec32b9c80cd 100644
--- a/config/locales/crowdin/he.yml
+++ b/config/locales/crowdin/he.yml
@@ -114,7 +114,7 @@ he:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ he:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ he:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ he:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -399,9 +400,9 @@ he:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -410,10 +411,14 @@ he:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
two: "... %{count} more projects"
@@ -430,7 +435,7 @@ he:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -698,6 +703,37 @@ he:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1375,6 +1411,20 @@ he:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1572,6 +1622,9 @@ he:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1580,7 +1633,7 @@ he:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1836,6 +1889,7 @@ he:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1953,6 +2007,7 @@ he:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2019,6 +2074,7 @@ he:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2541,7 +2597,6 @@ he:
avatar: Avatar
base: 'שגיאה כללית:'
body: Body
- blocks_ids: המזהים של חבילות עבודה חסומים
category: קטגוריה
comment: תגובה
comments: תגובה
@@ -3038,6 +3093,7 @@ he:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3509,6 +3565,11 @@ he:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3571,6 +3632,72 @@ he:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: משויך אל
@@ -3602,6 +3729,7 @@ he:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: חשבון
+ label_actions: Actions
label_active: פעיל
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3642,6 +3770,7 @@ he:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: מצב יישומית
label_archive_project: Archive project
@@ -3892,7 +4021,7 @@ he:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: קפוץ אל פרוייקט...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3930,6 +4059,10 @@ he:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: התנתק
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: תפריט צד
@@ -5012,6 +5145,7 @@ he:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5158,12 +5292,12 @@ he:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/hi.yml b/config/locales/crowdin/hi.yml
index b2a678ee29f..98538de2d33 100644
--- a/config/locales/crowdin/hi.yml
+++ b/config/locales/crowdin/hi.yml
@@ -114,7 +114,7 @@ hi:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ hi:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ hi:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ hi:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ hi:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ hi:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ hi:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ hi:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ hi:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ hi:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ hi:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ hi:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ hi:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ hi:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ hi:
avatar: अवतार
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: श्रेणी
comment: टिप्पणी
comments: टिप्पणी
@@ -2922,6 +2977,7 @@ hi:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ hi:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ hi:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: अनुदिष्ट
@@ -3484,6 +3611,7 @@ hi:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: खाता
+ label_actions: क्रियाएँ
label_active: सक्रिय
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ hi:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: लागू की गई स्थिति
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ hi:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: किसी प्रोजेक्ट पर जंप करें...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ hi:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: विशेष या कस्टम favicon
label_custom_touch_icon: कस्टम प्रतीक चिह्न
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ hi:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ hi:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: डिफ़ॉल्ट हाइलाइटिंग तरीका
diff --git a/config/locales/crowdin/hr.yml b/config/locales/crowdin/hr.yml
index 1524d801db2..52700e5be2a 100644
--- a/config/locales/crowdin/hr.yml
+++ b/config/locales/crowdin/hr.yml
@@ -114,7 +114,7 @@ hr:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ hr:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ hr:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ hr:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -393,9 +394,9 @@ hr:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -404,10 +405,14 @@ hr:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -423,7 +428,7 @@ hr:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -690,6 +695,37 @@ hr:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1358,6 +1394,20 @@ hr:
index:
no_results_title_text: Trenutno ne postoji niti jedan workflow.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1554,6 +1604,9 @@ hr:
dependencies: Ovisnosti
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1562,7 +1615,7 @@ hr:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Prikaži do
attachment:
@@ -1818,6 +1871,7 @@ hr:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1935,6 +1989,7 @@ hr:
confirmation: ne odgovara %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2001,6 +2056,7 @@ hr:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2501,7 +2557,6 @@ hr:
avatar: Avatar
base: 'Opća greška:'
body: Body
- blocks_ids: ID-ovi onemogućenih radnih paketa
category: Kategorija
comment: Komentar
comments: Komentar
@@ -2978,6 +3033,7 @@ hr:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3448,6 +3504,11 @@ hr:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3510,6 +3571,72 @@ hr:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Opunomoćeno
@@ -3541,6 +3668,7 @@ hr:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Korisnički račun
+ label_actions: Actions
label_active: Aktivno
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3581,6 +3709,7 @@ hr:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Dodijeljeni status
label_archive_project: Archive project
@@ -3831,7 +3960,7 @@ hr:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Pređi na projekt...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Na osnovi jezika korisnika
label_last_activity: Zadnja aktivnost
@@ -3869,6 +3998,10 @@ hr:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Odjavi se
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Izbornik sa strane
@@ -4944,6 +5077,7 @@ hr:
'
setting_app_subtitle: Podnaslov aplikacije
setting_app_title: Naslov aplikacije
+ setting_organization_name: Organization name
setting_attachment_max_size: Max. veličina privitka
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5090,12 +5224,12 @@ hr:
setting_welcome_text: Tekst dobrodošlice
setting_welcome_title: Naslov dobrodošlice
setting_welcome_on_homescreen: Prikaži tekst dobrodošlice na početnoj stranici
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/hu.yml b/config/locales/crowdin/hu.yml
index 651df1ab955..18e2f3ea738 100644
--- a/config/locales/crowdin/hu.yml
+++ b/config/locales/crowdin/hu.yml
@@ -114,7 +114,7 @@ hu:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ hu:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ hu:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ hu:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ hu:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ hu:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ hu:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -684,6 +689,37 @@ hu:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1361,6 +1397,20 @@ hu:
index:
no_results_title_text: Jelenleg nincsenek munkafolyamatok.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1556,6 +1606,9 @@ hu:
dependencies: Szükséges összetevők
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1564,7 +1617,7 @@ hu:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Megjelenít eddig
attachment:
@@ -1822,6 +1875,7 @@ hu:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1943,6 +1997,7 @@ hu:
confirmation: "%{attribute} nem egyezik."
could_not_be_copied: A (z) %{dependency} nem másolható (teljesen).
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ó.
@@ -2013,6 +2068,7 @@ hu:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2517,7 +2573,6 @@ hu:
avatar: Profilkép
base: 'Általános hiba:'
body: Body
- blocks_ids: Lezárt munkacsomagok azonosítója
category: Kategória
comment: Komment
comments: Vélemény
@@ -2976,6 +3031,7 @@ hu:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Korlátlan
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3453,6 +3509,11 @@ hu:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3515,6 +3576,72 @@ hu:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Megbízott
@@ -3548,6 +3675,7 @@ hu:
invalid_filter: Invalid notification filter
label_accessibility: Kisegítő lehetőségek
label_account: Felhasználói fiók
+ label_actions: Műveletek
label_active: aktív
label_activate_user: Felhasználó aktiválása
label_active_in_new_projects: Új projektekben aktív
@@ -3588,6 +3716,7 @@ hu:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Visszavonás
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Alkalmazott státusz
label_archive_project: Projekt archiválása
@@ -3838,7 +3967,7 @@ hu:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Ugrás a projekthez
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Kulcsszavak
label_language_based: A felhasználói nyelv alapján
label_last_activity: Utolsó aktivitás
@@ -3876,6 +4005,10 @@ hu:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Egyedi favicon
label_custom_touch_icon: Egyedi "touch-icon"
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Kijelentkezés
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Oldalsó menü
@@ -4970,6 +5103,7 @@ hu:
'
setting_app_subtitle: Alkalmazás felirat
setting_app_title: Alkalmazás címe
+ setting_organization_name: Organization name
setting_attachment_max_size: Melléklet max. méret
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5120,12 +5254,12 @@ hu:
setting_welcome_text: Üdvözlő blokk szöveg
setting_welcome_title: Üdvözlő blokk címe
setting_welcome_on_homescreen: Üdvözlő blokk megjelenítése a kezdőképernyőn
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Alapértelmezett kiemelési mód
diff --git a/config/locales/crowdin/id.yml b/config/locales/crowdin/id.yml
index a8339b34b6f..af46bb0b12a 100644
--- a/config/locales/crowdin/id.yml
+++ b/config/locales/crowdin/id.yml
@@ -114,7 +114,7 @@ id:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ id:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ id:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ id:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -381,9 +382,9 @@ id:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ id:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ id:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -673,6 +678,37 @@ id:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1323,6 +1359,20 @@ id:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1522,6 +1572,9 @@ id:
dependencies: Dependensi
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1530,7 +1583,7 @@ id:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1786,6 +1839,7 @@ id:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1903,6 +1957,7 @@ id:
confirmation: tidak sesuai dengan %{attribute}.
could_not_be_copied: "%{dependency} tidak dapat (sepenuhnya) disalin."
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.
@@ -1969,6 +2024,7 @@ id:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2436,7 +2492,6 @@ id:
avatar: Avatar
base: 'Error :'
body: Body
- blocks_ids: List ID dari work package yang diblokir
category: Kategori
comment: Komentar
comments: Komentar
@@ -2875,6 +2930,7 @@ id:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3343,6 +3399,11 @@ id:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3405,6 +3466,72 @@ id:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Pelimpahan
@@ -3436,6 +3563,7 @@ id:
invalid_filter: Invalid notification filter
label_accessibility: Kemampuan akses
label_account: Akun
+ label_actions: Tindakan
label_active: Aktif
label_activate_user: Pengguna diaktifkan
label_active_in_new_projects: Aktif dalam proyek-proyek baru
@@ -3476,6 +3604,7 @@ id:
label_ical_access_key_generation_hint: Dibuat secara otomatis saat berlangganan kalender.
label_ical_access_key_latest: terbaru
label_ical_access_key_revoke: Menarik kembali
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Status berjalan
label_archive_project: Proyek arsip
@@ -3726,7 +3855,7 @@ id:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Lompat ke Project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Kata kunci
label_language_based: Berdasarkan bahasa user
label_last_activity: Aktivitas terakhir
@@ -3764,6 +3893,10 @@ id:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Favicon sesuai keinginan
label_custom_touch_icon: Ikon sentuh sesuai keinginan
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Logout
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sidemenu
@@ -4821,6 +4954,7 @@ id:
'
setting_app_subtitle: Subjudul aplikasi
setting_app_title: Judul aplikasi
+ setting_organization_name: Organization name
setting_attachment_max_size: Ukuran lampiran maks.
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -4967,12 +5101,12 @@ id:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/it.yml b/config/locales/crowdin/it.yml
index 30d79da22dc..20a6b262c6e 100644
--- a/config/locales/crowdin/it.yml
+++ b/config/locales/crowdin/it.yml
@@ -114,7 +114,7 @@ it:
import:
title: Importa
jira:
- title: Importazione di Jira
+ title: Jira Migrator
description: Utilizza questo strumento per importare dati dalla tua istanza Jira. Puoi configurare più host Jira e scegliere cosa importare a ogni importazione.
errors:
cannot_delete_with_imports: Impossibile eliminare l'host Jira con importazioni esistenti
@@ -125,8 +125,8 @@ it:
title: Configurazione Jira
new: Nuova configurazione
banner:
- title: Importazione limitata
- description: 'Questo strumento di importazione è attualmente in versione beta e può importare solo dati di base: progetti, issue (nome, titolo, descrizione, allegati), utenti (nome, email, appartenenza al progetto), stati e tipi. Non può importare flussi di lavoro, campi personalizzati, relazioni tra issue o autorizzazioni. Al momento supportiamo solo le versioni 10.x e 11.x di Jira Server/Data Center. Le istanze cloud non sono supportate al momento.'
+ title: Funzionalità di importazione limitate
+ description: 'Jira Migrator è attualmente in versione beta e può importare solo dati di base: progetti, issue (nome, titolo, descrizione, allegati), utenti (nome, email, appartenenza al progetto), stati e tipi. Non può importare flussi di lavoro, campi personalizzati, relazioni tra issue o autorizzazioni. Al momento supportiamo solo le versioni 10.x e 11.x di Jira Server/Data Center. Le istanze cloud non sono supportate al momento.'
form:
fields:
name: Nome
@@ -154,6 +154,7 @@ it:
connection_timeout: 'La connessione al server Jira è scaduta: %{message}'
parse_error: 'Impossibile analizzare la risposta dell''API Jira: %{message}'
api_error: Jira API ha restituito lo stato di errore %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Progetti
last_change: Ultima modifica
@@ -387,9 +388,9 @@ it:
notification_text_default: "
Ciao,
È stato creato un nuovo progetto: projectValue:name
Grazie
\n"
work_packages_identifier:
page_header:
- description: Scegli tra ID numerici di base delle macro-attività oppure ID specifici del progetto che antepongono l'identificatore del progetto all'ID della macro-attività.
+ description: Scegli tra ID numerici classici delle macro-attività oppure ID semantici specifici del progetto che antepongono l'identificatore del progetto all'ID della macro-attività.
banner:
- existing_identifiers_notice: 'Gli identificatori esistenti per %{project_count} progetti non soddisfano i requisiti per gli identificatori alfanumerici basati sul progetto. OpenProject può aggiornarli automaticamente per renderli validi, come negli esempi sotto. Fai clic su "Correggi automaticamente e salva" per aggiornare gli identificatori di tutti i progetti in questo modo e abilitare gli identificatori alfanumerici basati sul progetto.
+ existing_identifiers_notice: 'Gli identificatori esistenti per %{project_count} progetti non soddisfano i requisiti per gli identificatori semantici basati sul progetto. OpenProject può aggiornarli automaticamente per renderli validi, come negli esempi sotto. Fai clic su "Correggi automaticamente e salva" per aggiornare gli identificatori di tutti i progetti in questo modo e abilitare gli identificatori semantici basati sul progetto.
'
box_header:
@@ -398,10 +399,14 @@ it:
label_autofixed_suggestion: Identificativo futuro
label_example_work_package_id: Esempio di ID macro-attività
autofix_preview:
- error_too_long: Deve contenere meno di 5 caratteri
+ error_too_long: Deve essere di 10 caratteri o meno
+ error_numerical: Non può essere puramente numerico
+ error_starts_with_number: Non può iniziare con un numero
error_special_characters: I caratteri speciali non sono consentiti
+ error_not_fully_uppercased: Deve essere maiuscolo
error_in_use: Già in uso come identificatore attivo di un altro progetto
error_reserved: Riservato dalla cronologia degli identificatori di un altro progetto
+ error_unknown: Necessita di controllo manuale
remaining_projects:
one: "... 1 altro progetto"
other: "... altri %{count} progetti"
@@ -416,7 +421,7 @@ it:
checkbox_label: Comprendo che questa operazione modificherà in modo permanente tutti gli ID delle macro-attività
success_banner: Formato degli identificatori delle macro-attività aggiornato correttamente.
in_progress:
- banner_message: Gli identificatori dei progetti sono attualmente in fase di aggiornamento agli identificatori alfanumerici basati sul progetto. Questa operazione potrebbe richiedere un po' di tempo.
+ banner_message: Gli identificatori dei progetti sono attualmente in fase di aggiornamento agli identificatori semantici basati sul progetto. Questa operazione potrebbe richiedere un po' di tempo.
workflows:
tabs:
default_transitions: Transizioni predefinite
@@ -681,6 +686,37 @@ it:
danger_dialog:
confirmation_live_message_checked: Il pulsante per procedere è ora attivo.
confirmation_live_message_unchecked: Il pulsante per procedere è ora inattivo. Devi spuntare la casella per continuare.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginazione
prev: Precedente
@@ -1339,6 +1375,20 @@ it:
index:
no_results_title_text: Al momento non vi sono flussi di lavoro.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1534,6 +1584,9 @@ it:
dependencies: Dipendenze
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identificatore
+ work_package: Macro-attività
jira_import:
projects: Progetti
import/jira:
@@ -1542,7 +1595,7 @@ it:
personal_access_token: Token di accesso personale
import/jira_open_project_reference:
jira: Jira
- jira_import: Importazione di Jira
+ jira_import: Jira Migrator
announcements:
show_until: Visualizza fino a
attachment:
@@ -1798,6 +1851,7 @@ it:
identity_url: URL identificativo
parent: Gruppo padre
organizational_unit: Unità organizzativa
+ group_users: Group users
group_detail:
parent: Gruppo padre
organizational_unit: Unità organizzativa
@@ -1915,6 +1969,7 @@ it:
confirmation: non coincide con %{attribute}.
could_not_be_copied: "%{dependency} non può essere (completamente) copiato."
does_not_exist: non esiste.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1981,6 +2036,7 @@ it:
attributes:
parent_id:
circular_dependency: creerebbe una gerarchia circolare dei gruppi.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ it:
avatar: Avatar
base: 'Errore Generale:'
body: Corpo
- blocks_ids: ID delle macro-attività bloccate
category: Categoria
comment: Commento
comments: Commento
@@ -2922,6 +2977,7 @@ it:
title: Componente aggiuntivo Enterprise
plan_title: Addon del %{plan} Enterprise
plan_name: "%{plan} piano Enterprise"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Disponibile a partire dal %{plan_name}.
unlimited: Illimitato
already_have_token: 'Hai già un token? Aggiungilo usando il pulsante qui sotto per aggiornare al piano Enterprise prenotato.
@@ -3391,6 +3447,11 @@ it:
quick_add:
label: Aggiungi…
my_account:
+ notifications_and_email:
+ title: Notifiche ed email
+ tabs:
+ notifications: Impostazioni delle notifiche
+ email_reminders: Promemoria email
access_tokens:
description: I token provider vengono emessi da OpenProject, consentendo ad altre applicazioni di accedervi. I token client vengono emessi da altre applicazioni, consentendo a OpenProject di accedervi.
no_results:
@@ -3453,6 +3514,72 @@ it:
disabled_text: I token RSS non sono abilitati dall'amministratore. Contatta il tuo amministratore per utilizzare questa funzione.
storages:
unknown_storage: Archivio sconosciuto
+ email_reminders:
+ immediate_reminders:
+ title: Inviami un promemoria email
+ mentioned: Avvisami quando qualcuno mi menziona
+ personal_reminder: Notificami i promemoria personali
+ daily_reminders:
+ title: Inviami promemoria email giornalieri per le notifiche non lette
+ caption: Riceverai questi promemoria solo per le notifiche non lette e solo negli orari che specifichi. Finché non configuri un fuso orario per il tuo account, gli orari saranno interpretati come UTC.
+ enabled: Abilita promemoria email giornalieri
+ add_time: Aggiungi orario
+ remove_time: Rimuovi orario
+ time_slot_label: Ora del promemoria (UTC)
+ workdays:
+ title: Ricevi promemoria email in questi giorni
+ submit_button: Aggiorna i giorni di promemoria
+ pause_reminders:
+ title: Sospendi le notifiche email
+ enabled: Sospendi temporaneamente i promemoria email giornalieri
+ date_range: Periodo di sospensione
+ email_alerts:
+ title: Avvisi email per altri elementi che non sono macro-attività
+ news_added: Notizie aggiunte
+ news_commented: Commento su un articolo di notizie
+ document_added: Documento aggiunto
+ forum_messages: Messaggio del forum pubblicato
+ wiki_page_added: Pagina wiki aggiunta
+ wiki_page_updated: Pagina wiki aggiornata
+ membership_added: Iscrizione aggiunta
+ membership_updated: Iscrizione aggiornata
+ submit_button: Aggiorna gli avvisi
+ notifications:
+ participating:
+ title: Partecipazione
+ submit_button: Aggiorna impostazioni
+ mentioned: Menzionato
+ watched: Osservazione
+ assignee: Assegnatario
+ responsible: Responsabile
+ shared: Condivisi con me
+ date_alerts:
+ title: Avvisi sulle date
+ submit_button: Aggiorna gli avvisi sulle date
+ start_date: Data di inizio
+ due_date: Data di fine
+ overdue: In ritardo
+ times:
+ same_day: Lo stesso giorno
+ one_day_before: 1 giorno prima
+ three_days_before: 3 giorni prima
+ seven_days_before: 7 giorni prima
+ one_day_after: 1 giorno dopo
+ three_days_after: 3 giorni dopo
+ seven_days_after: 7 giorni dopo
+ non_participating:
+ title: Non partecipante
+ submit_button: Aggiorna impostazioni
+ work_package_created: Nuove macro-attività
+ work_package_commented: Tutti i nuovi commenti
+ work_package_processed: Tutte le modifiche di stato
+ work_package_prioritized: Tutte le modifiche prioritarie
+ work_package_scheduled: Tutte le modifiche della data
+ project_specific_settings:
+ title: Impostazioni di notifica specifiche del progetto
+ add_button: Aggiungi notifiche specifiche al progetto
+ dialog_title: Aggiungi notifiche specifiche al progetto
+ list_header: Progetti con notifiche specifiche
notifications:
reasons:
assigned: Assegnatario
@@ -3484,6 +3611,7 @@ it:
invalid_filter: Filtro notifica non valido
label_accessibility: Accessibilità
label_account: Account
+ label_actions: Azioni
label_active: Attivo
label_activate_user: Attiva utente
label_active_in_new_projects: Attivo nei nuovi progetti
@@ -3524,6 +3652,7 @@ it:
label_ical_access_key_generation_hint: Generato automaticamente all'iscrizione a un calendario.
label_ical_access_key_latest: più recente
label_ical_access_key_revoke: Revoca
+ label_integrations: Integrazioni
label_add_column: Aggiungi colonna
label_applied_status: Stato applicato
label_archive_project: Archivia progetto
@@ -3774,7 +3903,7 @@ it:
label_external_links: Link esterni
label_locale: Lingua e paese
label_jump_to_a_project: Salta ad altro progetto...
- label_jira_import: Importazione di Jira
+ label_jira_import: Jira Migrator
label_keyword_plural: Parole chiave
label_language_based: Basato sulla lingua dell'utente
label_last_activity: Ultima attività
@@ -3812,6 +3941,10 @@ it:
label_custom_pdf_export_settings: Impostazioni di esportazione PDF personalizzate
label_custom_favicon: Favicon personalizzata
label_custom_touch_icon: Icona del touch personalizzata
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Disconnetti
label_mapping_for: 'Mappatura per: %{attribute}'
label_main_menu: Menu laterale
@@ -4882,6 +5015,7 @@ it:
'
setting_app_subtitle: Sottotitolo applicazione
setting_app_title: Titolo applicazione
+ setting_organization_name: Organization name
setting_attachment_max_size: Dimensione max. dell'allegato
setting_show_work_package_attachments: Mostra gli allegati nella scheda File per impostazione predefinita
setting_antivirus_scan_mode: Modalità di scansione
@@ -5028,12 +5162,12 @@ it:
setting_welcome_text: Blocco di testo di benvenuto
setting_welcome_title: Blocco di testo del titolo
setting_welcome_on_homescreen: Mostra il blocco testo di benvenuto nella pagina home
- setting_work_packages_identifier_numeric: Sequenza numerica a livello di istanza (predefinita)
- setting_work_packages_identifier_numeric_caption: 'Ogni macro-attività riceve un numero sequenziale a partire da 1, incrementato a ogni nuova creazione. I numeri sono univoci all''interno di questa istanza, quindi restano invariati anche se le macro-attività vengono spostate tra progetti.
+ setting_work_packages_identifier_classic: Sequenza numerica a livello di istanza (predefinita)
+ setting_work_packages_identifier_classic_caption: 'Ogni macro-attività riceve un numero sequenziale a partire da 1, incrementato a ogni nuova creazione. I numeri sono univoci all''interno di questa istanza, quindi restano invariati anche se le macro-attività vengono spostate tra progetti.
'
- setting_work_packages_identifier_alphanumeric: Identificatori alfanumerici basati su progetti
- setting_work_packages_identifier_alphanumeric_caption: 'Ogni progetto ha un identificatore univoco che viene anteposto all''ID della macro-attività. Se una macro-attività viene spostata in un altro progetto, viene generato un nuovo identificatore, ma quello precedente continua a funzionare.
+ setting_work_packages_identifier_semantic: Identificatori semantici basati su progetti
+ setting_work_packages_identifier_semantic_caption: 'Ogni progetto ha un identificatore univoco che viene anteposto all''ID della macro-attività. Se una macro-attività viene spostata in un altro progetto, viene generato un nuovo identificatore, ma quello precedente continua a funzionare.
'
setting_work_package_list_default_highlighting_mode: Modalità evidenziazione predefinita
diff --git a/config/locales/crowdin/ja.yml b/config/locales/crowdin/ja.yml
index 08fda701046..49694b2a9ad 100644
--- a/config/locales/crowdin/ja.yml
+++ b/config/locales/crowdin/ja.yml
@@ -114,7 +114,7 @@ ja:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ja:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: 名前
@@ -154,6 +154,7 @@ ja:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: プロジェクト
last_change: Last change
@@ -162,7 +163,7 @@ ja:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -324,13 +325,13 @@ ja:
success: MCP configuration was updated successfully.
scim_clients:
authentication_methods:
- sso: IDプロバイダーからのJWT
- oauth2_client: OAuth 2.0クライアント認証情報
+ sso: アイデンティティプロバイダからのJWT
+ oauth2_client: OAuth 2.0 クライアント資格情報
oauth2_token: 静的アクセストークン
created_client_credentials_dialog_component:
- title: クライアント認証情報の作成
- heading: クライアント認証情報が生成されました
- one_time_hint: クライアント・シークレットが表示されるのはこの時だけです。必ずコピーしてください。
+ title: クライアントの資格情報が作成されました
+ heading: クライアントの資格情報が生成されました
+ one_time_hint: クライアントのシークレットが表示される唯一の時間です。今すぐコピーしてください。
created_token_dialog_component:
title: トークンを作成しました
heading: トークンが生成されました
@@ -343,21 +344,21 @@ ja:
edit:
label_delete_scim_client: SCIM クライアントを削除
form:
- auth_provider_description: これは、SCIM プロバイダによって追加されたユーザが OpenProject で認証するために使用するサービスです。
- authentication_method_description_html: これは SCIM クライアントが OpenProject で認証する方法です。OAuth トークンにscim_v2スコープが含まれていることを確認してください。
- description: これらの設定オプションの詳細については、[SCIMクライアントの設定に関する文書](docs_url)を参照してください。
+ auth_provider_description: これは、SCIMプロバイダが追加したユーザーがOpenProjectでの認証に使用するサービスです。
+ authentication_method_description_html: これは SCIM クライアントが OpenProject で認証する方法です。OAuth トークンに scim_v2 スコープが含まれていることを確認してください。
+ description: 設定オプションの詳細については、[SCIM クライアントの設定に関するドキュメント](docs_url)を参照してください。
jwt_sub_description: 例えば、Keycloakの場合、これはSCIMクライアントに関連付けられたサービスアカウントのUUIDです。あなたのユースケースにあった Subject claim を見つける方法については [ドキュメント](docs_url) を参照してください。
- name_description: このクライアントが設定された理由を他の管理者が理解しやすい名前を選んでください。
+ name_description: 他の管理者がこのクライアントが設定された理由を理解するのに役立つ名前を選択してください。
index:
- description: ここで設定された SCIM クライアントは、OpenProject SCIM サーバ API と対話し、ユーザアカウントやグループのプロビジョニング、更新、デプロビジョニングを行うことができます。
- label_create_button: SCIMクライアントの追加
+ description: ここで設定されたSCIMクライアントは、OpenProjectのSCIMサーバー APIと相互作用して、ユーザーアカウントとグループのプロビジョニング、更新、およびデプロビジョニングを行うことができます。
+ label_create_button: SCIMクライアントを追加
new:
title: 新しいSCIMクライアント
revoke_static_token_dialog_component:
confirm_button: 取り消す
- title: 静的トークンの失効
- heading: このトークンを本当に取り消しますか?
- description: このトークンを使っている SCIM クライアントは、OpenProject の SCIM サーバ API にアクセスできなくなります。
+ title: 静的トークンを取り消す
+ heading: このトークンを取り消してもよろしいですか?
+ description: このトークンを使用する SCIM クライアントは、OpenProject の SCIM サーバ API にアクセスできなくなります。
table_component:
blank_slate:
title: SCIMクライアントがまだ設定されていません
@@ -381,9 +382,9 @@ ja:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ ja:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ ja:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -674,6 +679,37 @@ ja:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -996,26 +1032,26 @@ ja:
other: また、 %{shared_work_packages_link} はこのユーザーと共有されています。
remove_project_membership_or_work_package_shares_too: 直接のメンバーとしてのユーザーだけを削除したい(および共有を維持したい)、またはワークパッケージの共有も削除しますか?
will_remove_all_user_access_priveleges: このメンバーを削除すると、プロジェクトへのユーザーのすべてのアクセス権が削除されます。ユーザーはまだサイトの一部として存在します。
- will_remove_all_group_access_priveleges: このメンバを削除すると、プロジェクトに対するグループのすべてのアクセス権が削除されます。グループはサイトの一部としてまだ存在します。
- cannot_delete_inherited_membership: このプロジェクトのメンバーであるグループに所属しているため、このメンバーを削除することはできません。
- cannot_delete_inherited_membership_note_admin_html: "%{administration_settings_link}で、プロジェクトのメンバーとしてグループを削除することも、特定のメンバーをグループから削除することもできます。"
- cannot_delete_inherited_membership_note_non_admin: プロジェクトのメンバーとしてグループを削除するか、管理者に連絡してこの特定のメンバーをグループから削除することができます。
+ will_remove_all_group_access_priveleges: このメンバーを削除すると、グループのすべてのアクセス権がプロジェクトに削除されます。グループはサイトの一部として存在します。
+ cannot_delete_inherited_membership: このメンバーはこのプロジェクトのメンバーであるグループに属しているため、削除できません。
+ cannot_delete_inherited_membership_note_admin_html: プロジェクトのメンバーとしてグループを削除するか、 %{administration_settings_link} のグループからこの特定のメンバーを削除することができます。
+ cannot_delete_inherited_membership_note_non_admin: プロジェクトのメンバーとしてグループを削除するか、管理者に問い合わせてグループから特定のメンバーを削除することができます。
delete_work_package_shares_dialog:
- title: ワーク・パッケージ・シェアの破棄
+ title: ワークパッケージの共有の取り消し
shared_with_this_user_html:
other: "%{all_shared_work_packages_link} はこのユーザーと共有されています。"
shared_with_this_group_html:
other: "%{all_shared_work_packages_link} はこのグループと共有されています。"
shared_with_permission_html:
other: "%{shared_work_packages_link} のみが %{shared_role_name} 権限と共有されています。"
- revoke_all_or_with_role: すべての共有ワークパッケージ、または %{shared_role_name} 権限を持つワークパッケージのみへのアクセス権を剥奪しますか?
- will_not_affect_inherited_shares: "(これは、そのグループと共有しているワークパッケージには影響しません)。"
- cannot_remove_inherited: グループで共有されたワークパッケージの共有は削除できません。
- cannot_remove_inherited_with_role: ロール %{shared_role_name} で共有されるワークパッケージは、グループを介して共有され、削除することはできません。
- cannot_remove_inherited_note_admin_html: "%{administration_settings_link}、グループへの共有を取り消すか、グループからこの特定のメンバーを削除することができます。"
- cannot_remove_inherited_note_non_admin: グループへの共有を取り消すか、管理者に連絡して特定のメンバーをグループから削除することができます。
- will_revoke_directly_granted_access: このアクションは、グループと共有されているワークパッケージ以外の、すべてのワークパッケージへのアクセス権を剥奪する。
- will_revoke_access_to_all: このアクションは、すべてのアクセス権を剥奪する。
+ revoke_all_or_with_role: 共有されたワークパッケージ、または %{shared_role_name} 権限を持つワークパッケージのみへのアクセスを取り消しますか?
+ will_not_affect_inherited_shares: "(これはグループと共有されているワークパッケージには影響しません)。"
+ cannot_remove_inherited: グループ間で共有されるワークパッケージは削除できません。
+ cannot_remove_inherited_with_role: ワークパッケージとロール %{shared_role_name} が共有されているため、削除できません。
+ cannot_remove_inherited_note_admin_html: あなたは、グループへの共有を取り消すか、 %{administration_settings_link} のグループからこの特定のメンバーを削除することができます。
+ cannot_remove_inherited_note_non_admin: 共有をグループに取り消すか、管理者に問い合わせてグループから特定のメンバーを削除することができます。
+ will_revoke_directly_granted_access: このアクションは、すべてのユーザーへのアクセスを取り消しますが、グループと共有されているワークパッケージです。
+ will_revoke_access_to_all: このアクションは、すべてのユーザーへのアクセスを取り消します。
my:
access_token:
dialog:
@@ -1039,7 +1075,7 @@ ja:
no_results_title_text: 現在、有効なアクセス トークンはありません。
notice_api_token_revoked: APIトークンが削除されました。新しいトークンを作成するには、APIセクションの作成ボタンを使用してください。
notice_rss_token_revoked: RSSトークンが削除されました。新しいトークンを作成するには、RSSセクションのリンクを使用してください。
- notice_ical_token_revoked: プロジェクト "%{project_name}" のカレンダー "%{calendar_name}" の iCalendar トークン "%{token_name}" が失効しました。このトークンを持つiCalendar URLは無効になりました。
+ notice_ical_token_revoked: プロジェクト "%{token_name}" のカレンダー "%{calendar_name}" の iCalendar トークン "%{project_name}" が取り消されました。 このトークンのiCalendar URLは無効です。
password_confirmation_dialog:
confirmation_required: You need to enter your account password to confirm this change.
title: Confirm your password to continue
@@ -1060,7 +1096,7 @@ ja:
matrix_check_uncheck_all_in_col_label_html: Toggle all %{module} permissions for %{role} role
users:
autologins:
- prompt: ログインしたまま %{num_days}
+ prompt: "%{num_days} のログインを維持"
sessions:
session_name: "%{browser_name} %{browser_version} の %{os_name}"
browser: ブラウザ
@@ -1074,17 +1110,17 @@ ja:
current: Current (this device)
title: セッション管理
instructions: You are logged in to your account through the following devices. Revoke sessions that you do not recognise or from devices you do not control.
- may_not_delete_current: 現在のセッションを削除することはできません。
+ may_not_delete_current: 現在のセッションは削除できません。
deletion_warning: Are you sure you want to revoke this session? You will be logged out on this device.
groups:
member_in_these_groups: このユーザーは現在以下のグループのメンバーです:
no_results_title_text: このユーザーは現在どのグループのメンバーでもありません。
summary_with_more_html: Member of %{names} and %{count_link}.
- more: "%{count} もっと見る"
+ more: "%{count} 以上"
summary_html: Member of %{names}.
memberships:
no_results_title_text: このユーザは現在プロジェクトのメンバーではありません。
- open_profile: プロフィール
+ open_profile: プロファイルを開く
invite_user_modal:
invite: 招待
title:
@@ -1201,7 +1237,7 @@ ja:
right_to_manage_members_missing: 'プレースホルダーユーザを削除する権限がありません。 プレースホルダー ユーザーがメンバーであるすべてのプロジェクトのメンバーを管理する権利はありません。
'
- delete_tooltip: プレースホルダー・ユーザーの削除
+ delete_tooltip: プレースホルダー ユーザーを削除
deletion_info:
heading_html: Delete placeholder user %{name}
data_consequences: 'プレースホルダー ユーザのすべての発生(担当者、担当者、その他のユーザ値など)は、「削除されたユーザー」というアカウントに再割り当てられます。 削除されたすべてのアカウントのデータがこのアカウントに再割り当てられるため、ユーザーが作成したデータと別の削除されたアカウントのデータを区別することはできません。
@@ -1220,11 +1256,11 @@ ja:
reactions:
action_title: リアクト
add_reaction: リアクションを追加
- react_with: "%{reaction} と リアクト"
- and_user: および %{user}
+ react_with: "%{reaction} で反応する"
+ and_user: と %{user}
and_others:
other: と %{count} その他
- reaction_by: "%{reaction} によって"
+ reaction_by: "%{reaction} による"
reportings:
index:
no_results_title_text: 現在、ステータス報告はありません。
@@ -1234,19 +1270,20 @@ ja:
status_color_text: |
このステータスの色を割り当てたり変更する場合にクリックします。
ステータスボタンに表示され、テーブル内のワークパッケージを強調表示するために使用できます。
- status_default_text: 新しいワークパッケージは、デフォルトでこのタイプに設定される。読み取り専用にはできない。
+ status_default_text: 新しいワークパッケージはデフォルトでこのタイプに設定されています。読み取り専用にすることはできません。
status_excluded_from_totals_text: |-
- このステータスを持つワークパッケージを、階層内の「作業」、「
- 残作業」、「完了率」の合計から除外するには、このオプションをオンにします。
+ このオプションをオンにすると、このステータスのワークパッケージを合計作業量、
+ 残作業量、および階層構造で完了させることができます。
status_percent_complete_text_html: |-
In [status-based progress calculation mode](setting_url), the % Complete of a work
package is automatically set to this value when this status is selected.
Ignored in work-based mode.
status_readonly_html: |
- このステータスを持つワークパッケージを読み取り専用としてマークするには、このオプションをチェックする。
- ステータス以外の属性は変更できません。
+ ワークパッケージを読み取り専用としてマークするには、このオプションをオンにしてください。
+ ステータスを除いて変更することはできません。
+
- 注意: 継承された値 (子やリレーションなど) は適用されます。
+ メモ: 継承された値 (例えば、子や関連) が適用されます。
index:
no_results_title_text: 現在、ワークパッケージのステータスはありません。
no_results_content_text: 新しいステータスを追加
@@ -1256,7 +1293,7 @@ ja:
is_readonly: 読み取り専用
excluded_from_totals: 合計から除外
themes:
- dark: 暗い
+ dark: ダーク
light: ライト
sync_with_os: 自動(OSのテーマ設定に追従)
types:
@@ -1324,6 +1361,20 @@ ja:
index:
no_results_title_text: 現在、ワークフローはありません。
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1374,15 +1425,15 @@ ja:
could_not_be_saved: '次のワークパッケージを保存できませんでした:'
none_could_be_saved: "%{total} ワークパッケージのどれも更新できませんでした。"
x_out_of_y_could_be_saved: "%{failing} の %{total} ワークパッケージのうち、 %{success} を更新できませんでした。"
- selected_because_descendants: "%{selected} のワークパッケージが選択されたが、合計 %{total} のワークパッケージが影響を受け、その中には子孫も含まれる。"
- descendant: 選択された子孫
+ selected_because_descendants: "%{selected} ワークパッケージが選択されている間、合計で %{total} ワークパッケージが子孫を含む影響を受けます。"
+ descendant: 選択された子孫です
move:
no_common_statuses_exists: 選択されたすべてのワークパッケージに利用できるステータスはありません。 それらの状態は変更できません。
unsupported_for_multiple_projects: 複数のプロジェクトからのワークパッケージの一括移動 / コピーはサポートされていません
- current_type_not_available_in_target_project: 'ワークパッケージの現在のタイプがターゲットプロジェクトで有効になっていません。変更しない場合は、ターゲットプロジェクトでタイプを有効にしてください。そうでない場合は、リストからターゲットプロジェクトで使用可能なタイプを選択してください。
+ current_type_not_available_in_target_project: 'ターゲット プロジェクトで現在のワークパッケージのタイプが有効になっていません。 変更を行わないようにしたい場合は、対象プロジェクトのタイプを有効にしてください。 それ以外の場合は、リストからターゲット プロジェクトで使用可能なタイプを選択します。
'
- bulk_current_type_not_available_in_target_project: 'ワークパッケージの現在のタイプがターゲットプロジェクトで有効になっていません。変更しない場合は、ターゲットプロジェクトでタイプを有効にしてください。そうでない場合は、リストからターゲットプロジェクトで使用可能なタイプを選択してください。
+ bulk_current_type_not_available_in_target_project: '現在のタイプのワークパッケージはターゲット プロジェクトで有効になっていません。 変更を行わないようにしたい場合は、対象プロジェクトのタイプを有効にしてください。 それ以外の場合は、リストからターゲット プロジェクトで使用可能なタイプを選択します。
'
sharing:
@@ -1408,9 +1459,9 @@ ja:
no_results_title_text: 現在、有効なバージョンはありません。
work_package_relations_tab:
index:
- action_bar_title: 他のワークパッケージとのリレーションを追加して、それらの間にリンクを作成する。
- no_results_title_text: 現在、利用可能な関係はない。
- blankslate_heading: 関係なし
+ action_bar_title: 他のワークパッケージにリレーションを追加して、その間にリンクを作成します。
+ no_results_title_text: 現在利用可能なリレーションはありません。
+ blankslate_heading: リレーションなし
blankslate_description: このワークパッケージにはまだリレーションがありません。
label_add_child_button: 子要素
label_add_x: "%{x} を追加"
@@ -1518,6 +1569,9 @@ ja:
dependencies: 依存関係
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1526,7 +1580,7 @@ ja:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: までを表示
attachment:
@@ -1782,6 +1836,7 @@ ja:
identity_url: アイデンティティ URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1901,6 +1956,7 @@ ja:
confirmation: は%{attribute} と一致しません。
could_not_be_copied: "%{dependency} を(完全に)コピーできませんでした。"
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: 書けませんでした。
@@ -1967,6 +2023,7 @@ ja:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2429,7 +2486,6 @@ ja:
avatar: アバター
base: '一般的なエラー:'
body: 本文
- blocks_ids: ブロックされているワークパッケージのID
category: カテゴリ
comment: コメント
comments: コメント
@@ -2866,6 +2922,7 @@ ja:
title: エンタープライズアドオン
plan_title: エンタープライズ%{plan}アドオン
plan_name: "%{plan}のエンタープライズプラン"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: "%{plan_name} から利用できます。"
unlimited: 無制限です
already_have_token: 'すでにトークンをお持ちですか?予約済みのエンタープライズプランにアップグレードするには、下のボタンを使用して追加してください。
@@ -3334,6 +3391,11 @@ ja:
quick_add:
label: 追加
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3396,6 +3458,72 @@ ja:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: 不明なストレージ
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: 担当者
@@ -3427,6 +3555,7 @@ ja:
invalid_filter: 無効な通知フィルター
label_accessibility: アクセシビリティ
label_account: アカウント
+ label_actions: 操作
label_active: アクティブ
label_activate_user: ユーザーのアクティベート
label_active_in_new_projects: 新しいプロジェクトでアクティブ
@@ -3467,6 +3596,7 @@ ja:
label_ical_access_key_generation_hint: カレンダーを購読するときに自動的に生成されます。
label_ical_access_key_latest: 最新
label_ical_access_key_revoke: 取り消し
+ label_integrations: Integrations
label_add_column: カラムを追加
label_applied_status: 適用されるステータス
label_archive_project: プロジェクトをアーカイブ
@@ -3717,7 +3847,7 @@ ja:
label_external_links: External links
label_locale: 言語と地域
label_jump_to_a_project: プロジェクトへ移動...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: キーワード
label_language_based: ユーザの言語設定に基づく
label_last_activity: 最新の活動
@@ -3755,6 +3885,10 @@ ja:
label_custom_pdf_export_settings: PDF エクスポートの設定
label_custom_favicon: カスタムの favicon
label_custom_touch_icon: カスタムのタッチアイコン
+ label_departments: Organization
+ 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).
+
+ '
label_logout: ログアウト
label_mapping_for: 'マッピング: %{attribute}'
label_main_menu: サイドメニュー
@@ -4818,6 +4952,7 @@ ja:
'
setting_app_subtitle: アプリケーションのサブタイトル
setting_app_title: アプリケーションのタイトル
+ setting_organization_name: Organization name
setting_attachment_max_size: 添付ファイルの最大サイズ
setting_show_work_package_attachments: デフォルトで添付ファイルをファイルタブに表示
setting_antivirus_scan_mode: スキャンモード
@@ -4962,12 +5097,12 @@ ja:
setting_welcome_text: ようこそブロックのテキスト
setting_welcome_title: ようこそブロックのタイトル
setting_welcome_on_homescreen: ホーム画面にようこそブロックを表示
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: デフォルトの強調表示モード
diff --git a/config/locales/crowdin/js-af.yml b/config/locales/crowdin/js-af.yml
index f7b34cc5e9a..39be3096870 100644
--- a/config/locales/crowdin/js-af.yml
+++ b/config/locales/crowdin/js-af.yml
@@ -515,12 +515,6 @@ af:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ af:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Gedelegeerde
- responsible: Accountable
- shared: Shared
- watched: Dophouer
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ af:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Nuus bygevoeg
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ af:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-ar.yml b/config/locales/crowdin/js-ar.yml
index 3eebc12b88a..7bca67352c4 100644
--- a/config/locales/crowdin/js-ar.yml
+++ b/config/locales/crowdin/js-ar.yml
@@ -515,12 +515,6 @@ ar:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "... وحدد إدخال لوحة المهام ."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -596,49 +590,6 @@ ar:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: المُسند إليه
- responsible: Accountable
- shared: Shared
- watched: المشاهد
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: أنت في الصفحة فقط.
pages_skipped: Pages skipped.
@@ -662,39 +613,6 @@ ar:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: تم إضافة أحداث
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: تم إضافة صفحة wiki
- wiki_page_updated: تم تحديث صفحة wiki
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: هل أنت متأكد؟
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1067,13 +985,6 @@ ar:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-az.yml b/config/locales/crowdin/js-az.yml
index 76c557aa86b..4079c5005f6 100644
--- a/config/locales/crowdin/js-az.yml
+++ b/config/locales/crowdin/js-az.yml
@@ -515,12 +515,6 @@ az:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ az:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ az:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ az:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-be.yml b/config/locales/crowdin/js-be.yml
index 34de2459891..715f8014922 100644
--- a/config/locales/crowdin/js-be.yml
+++ b/config/locales/crowdin/js-be.yml
@@ -515,12 +515,6 @@ be:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -594,49 +588,6 @@ be:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Прызначаная асоба
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Паведамленні аб актыўнасці ў працоўных пакетах, у якіх вы ўдзельнічаеце (адказны, падсправаздачны або назіральнік).
- delayed:
- title: Non-participating
- description: Дадатковыя паведамленні аб актыўнасці ва ўсіх праектах.
- date_alerts:
- title: Date alerts
- description: Аўтаматычныя паведамленні аб важных падыходзячых датах у адчыняннях працоўных пакетах, у якіх вы ўдзельнічаеце (адказны, падсправаздачны або назіральнік).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: Гэтыя спецыфічныя налады праекта перапісваюць налады па ўмаўчанні вышэй.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -660,39 +611,6 @@ be:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1065,13 +983,6 @@ be:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-bg.yml b/config/locales/crowdin/js-bg.yml
index f890525f205..7a84a3882b6 100644
--- a/config/locales/crowdin/js-bg.yml
+++ b/config/locales/crowdin/js-bg.yml
@@ -515,12 +515,6 @@ bg:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ bg:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Изпълнител
- responsible: Accountable
- shared: Shared
- watched: Наблюдател
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ bg:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Добавени новини
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki страница добавена
- wiki_page_updated: Wiki страница обновена
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Сигурни ли сте?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ bg:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-ca.yml b/config/locales/crowdin/js-ca.yml
index 28b3fb06363..a8234eddcfa 100644
--- a/config/locales/crowdin/js-ca.yml
+++ b/config/locales/crowdin/js-ca.yml
@@ -109,7 +109,7 @@ ca:
button_save: Desa
button_settings: Configuració
button_uncheck_all: Desmarca-ho tot
- button_update: Actualitzar
+ button_update: Actualitza
button_export-atom: Descarregar Atom
button_generate_pdf: Generate PDF
button_create: Crear
@@ -515,12 +515,6 @@ ca:
sidebar_arrow: Utilitza la fletxa de retorn a la cantonada esquerra per tornar al menú principal del projecte.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Dintre de la wiki pots documentar i compartir el coneixement conjuntament amb el teu equip.
- backlogs:
- overview: Administra la teva feina en vistes de treballs pendents.
- sprints: A la dreta hi tens els treballs pendents del producte i errors, a l'esquerra hi tens els "sprint" respectius. Aquí pots crear èpiques, històries d'usuari i errors, prioritza'ls arrossegant-los i afegeix-los a un "sprint".
- task_board_arrow: Per veure el teu Tauler de tasques, obri el desplegable "sprint"...
- task_board_select: "... i seleccioni l'entrada del tauler de tasca."
- task_board: En el tauler de tasques es pot visualitzar el progrés d'aquest "sprint". Fes clic a la icona més (+) al costat d'una història d'usuari per afegir noves tasques o impediments. L'estat es pot actualitzar arrossegant.
boards:
overview: Selecciona els taulers per canviar la vista i administra el teu projecte utilitza la vista de taulers "agile".
lists_kanban: Aquí pots crear múltiples llistes (columnes) en el teu taulell. Aquesta funció, per exemple, permet crear un taulell Kanban.
@@ -592,49 +586,6 @@ ca:
settings:
change_notification_settings: Pots modificar la teva configuració de notificacions per assegurar-te que mai et perds informació important.
title: Configuració de notificacions
- notify_me: Notifica’m
- reminders:
- no_notification: Sense notificació
- timeframes:
- normal:
- PT0S: el mateix dia
- P1D: 1 dia abans
- P3D: 3 dies abans
- P7D: una setmana abans
- overdue:
- P1D: cada dia
- P3D: cada 3 dies
- P7D: cada setmana
- reasons:
- mentioned:
- title: Mencionat
- description: Rep una notificació cada vegada que algú em menciona a qualsevol lloc
- assignee: Assignat a
- responsible: Responsable
- shared: Compartida
- watched: Observador
- work_package_commented: Tots els nous comentaris
- work_package_created: Paquets de treball nou
- work_package_processed: Tots els canvis d'estat
- work_package_prioritized: Tots els canvis de prioritat
- work_package_scheduled: Tots els canvis de data
- global:
- immediately:
- title: Participant
- description: Notificacions per a totes les activitats en els paquets de treball en els que estàs involucrat (assignat, responsable o observador).
- delayed:
- title: No participant
- description: Notificacions addicionals per activitats en tots els projectes.
- date_alerts:
- title: Alertes per dates
- description: Notificacions automàtiques quan dates importants s'aproximen per a paquets de treball oberts en els quals estàs involucrat (assignat, responsable o observador).
- overdue: Quan vençut
- project_specific:
- title: Configuracions de notificacions específiques del projecte
- description: Aquestes configuracions específiques de projecte anul·len les configuracions per defecte especificades a sobre.
- add: Afegeix configuracions pel projecte
- already_selected: Aquest projecte ja està seleccionat
- remove: Elimina les configuracions del projecte
pagination:
no_other_page: Estàs en la pàgina única.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ ca:
required_outside_context: 'Si us plau, selecciona un projecte on crear el paquet de treball per a veure tots els atributs. Només pots seleccionar projectes que tinguin activat la classe indicada anteriorment.
'
- reminders:
- settings:
- daily:
- add_time: Afegeix temps
- enable: Activa els correus electrònics recordatori diaris
- explanation: Rebràs aquests recordatoris per a notificacions no llegides a les hores que especifiquis. %{no_time_zone}
- no_time_zone: Fins que no configuris una zona horària per al teu compte, els temps seran interpretats en UTC.
- time_label: 'Temps %{counter}:'
- title: Envia'm correus electrònics recordatori diaris per a notificacions no llegides.
- workdays:
- title: Rep recordatoris de correus electrònics recordatori aquests dies
- immediate:
- title: Envia'm un correu electrònic recordatori
- mentioned: Immediatament quan algú em @menciona
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Alertes en correu electrònic per altres elements (que no són paquets de treball)
- explanation: 'Ara mateix les notificacions estan limitades als paquets de treball. Pots seleccionar continuar rebent alertes en correus electrònics per aquells esdeveniments fins que s''incloguin a les notificacions:
-
- '
- news_added: Notícies afegides
- news_commented: Comenta a un element de notícia
- document_added: Documents afegits
- forum_messages: Nou missatges de fòrum
- wiki_page_added: S'ha afegit la pàgina wiki
- wiki_page_updated: S'ha actualitzat la pàgina wiki
- membership_added: Afiliació afegida
- membership_updated: Afiliació actualitzada
- title: Correus electrònics recordatori
- pause:
- label: Pausa els correu electrònic recordatori temporalment
- first_day: Primer dia
- last_day: Últim dia
text_are_you_sure: N'esteu segur?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ ca:
form_submit:
title: Confirma per continuar
text: Estàs segur que vols realitzar aquesta acció?
- destroy_work_package:
- title: Confirma l'eliminació de %{label}
- single_text: Estàs segur que vols eliminar aquest paquet de treball
- bulk_text: Estàs segur que vols eliminar el següent %{label}?
- has_children: 'Aquest paquet de treball té %{childUnits}:'
- confirm_deletion_children: Entenc que TOTS els descendents dels paquets de treball llistats seran eliminats recursivament.
- deletes_children: Tots els paquets de treball fills i els seus descendents també seran eliminats recursivament.
destroy_time_entry:
title: Confirma l'eliminació de l'entrada temporal
text: Estàs segur que vols eliminar la següent l'entrada temporal?
diff --git a/config/locales/crowdin/js-ckb-IR.yml b/config/locales/crowdin/js-ckb-IR.yml
index dd8da879f22..79a003cdf4c 100644
--- a/config/locales/crowdin/js-ckb-IR.yml
+++ b/config/locales/crowdin/js-ckb-IR.yml
@@ -515,12 +515,6 @@ ckb-IR:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ ckb-IR:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ ckb-IR:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ ckb-IR:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-cs.yml b/config/locales/crowdin/js-cs.yml
index 6b8e5cd449d..576c363463a 100644
--- a/config/locales/crowdin/js-cs.yml
+++ b/config/locales/crowdin/js-cs.yml
@@ -515,12 +515,6 @@ cs:
sidebar_arrow: Pomocí šipky zpět v levém horním rohu se vrátíte do hlavního menu projektu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: V rámci Wiki můžete dokumentovat a sdílet znalosti společně se svým týmem.
- backlogs:
- overview: Spravujte svou práci v backlogs zobrazení.
- sprints: Napravo máte nevyřízené produkty a nevyřízené chyby, vlevo máte příslušné sprinty. Zde můžete vytvořit epiky, uživatelské příběhy a chyby, upřednostnit přetažením a přidat je do sprintu.
- task_board_arrow: Chcete-li vidět Váš seznam úkolů, otevřete Sprint drop-down menu...
- task_board_select: "...a vyberte vstup do tabule."
- task_board: Pracovní panel vizualizuje postup pro tento sprint. Kliknutím na ikonu plus (+) vedle uživatelského příběhu přidáte nové úkoly nebo překážky. Stav lze aktualizovat přetažením.
boards:
overview: Vyberte tabule pro posun zobrazení a správu vašeho projektu pomocí agilního zobrazení desek.
lists_kanban: Zde si můžete vytvořit více seznamů (sloupce) ve vaší tabuli. Tato funkce vám umožní například vytvořit Kanban desku.
@@ -598,51 +592,6 @@ cs:
settings:
change_notification_settings: Můžete změnit nastavení oznámení , abyste se ujistili, že nikdy nezmeškáte důležitou aktualizaci.
title: Nastavení oznámení
- notify_me: Upozornit mě
- reminders:
- no_notification: Žádné oznámení
- timeframes:
- normal:
- PT0S: Týž den
- P1D: před 1 dnem
- P3D: 3 dny před
- P7D: před týdnem
- overdue:
- P1D: každý den
- P3D: Každé 3 dny
- P7D: každý týden
- reasons:
- mentioned:
- title: Zmíněné
- description: Dostat upozornění, kdykoli mě někdo kdekoli zmíní
- assignee: Řešitel
- responsible: Odpovědný
- shared: Sdílené
- watched: Sledující
- work_package_commented: Všechny nové komentáře
- work_package_created: Nový pracovní balíček
- work_package_processed: Všechny změny stavu
- work_package_prioritized: Všechny prioritní změny
- work_package_scheduled: Všechny změny data
- global:
- immediately:
- title: Participace
- description: Upozornění pro všechny aktivity v pracovních balíčcích, do kterých jste zapojeni (Řešitel, odpovědný nebo sledující).
- delayed:
- title: Neúčast
- description: Další oznámení pro činnosti ve všech projektech.
- date_alerts:
- title: Upozornění na datum
- description: Automatická oznámení, pokud se blíží důležitá data pro otevřené pracovní balíčky, které jste zapojeni (přiřazený, zodpovědný nebo sledovaný).
- overdue: Po termínu
- project_specific:
- title: 'Nastavení upozornění pro konkrétní projekt
-
- '
- description: Toto specifické nastavení projektu přepíše výchozí nastavení výše.
- add: Přidat nastavení pro projekt
- already_selected: Tento projekt je již vybrán
- remove: Odstranit nastavení projektu
pagination:
no_other_page: Jste na jediné stránce.
pages_skipped: Stránky přeskočeny.
@@ -666,39 +615,6 @@ cs:
required_outside_context: 'Vyberte projekt pro vytvoření pracovního balíčku, abyste viděli všechny atributy. Můžete vybrat pouze projekty, které mají výše uvedený typ aktivován.
'
- reminders:
- settings:
- daily:
- add_time: Přidat čas
- enable: Zapnout denní posílání oznámení e-mailem
- explanation: Tyto připomínky obdržíte pouze pro nepřečtená oznámení a pouze v hodinách, které zadáte. %{no_time_zone}
- no_time_zone: Dokud nenastavíte časové pásmo pro svůj účet, budou časy interpretovány v UTC.
- time_label: 'Čas %{counter}:'
- title: 'Posílat mi denní souhrn nepřečtených oznámení e-mailem '
- workdays:
- title: posílat e-mailem v těchto dnech
- immediate:
- title: Pošlete mi připomenutí e-mailem
- mentioned: V momente když mě někdo @zmiňuje
- personal_reminder: Okamžitě po osobní připomenutí
- alerts:
- title: E-mailová upozornění pro ostatní položky (které nejsou pracovní balíčky)
- explanation: 'Oznámení jsou dnes omezena na pracovní balíčky. Můžete se rozhodnout nadále dostávat e-mailová upozornění pro tyto události, dokud nebudou zahrnuta do oznámení:
-
- '
- news_added: Přidané novinky
- news_commented: Komentář k novince
- document_added: Dokumenty přidány
- forum_messages: Nové zprávy o fóru
- wiki_page_added: Přidána stránka wiki
- wiki_page_updated: Wiki stránka aktualizována
- membership_added: Členství přidáno
- membership_updated: Členství bylo aktualizováno
- title: E-mailová upozornění
- pause:
- label: Dočasně pozastavit denní připomenutí e-mailem
- first_day: První den
- last_day: Poslední den
text_are_you_sure: Jste si jisti?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Navigační lišta
@@ -1071,13 +987,6 @@ cs:
form_submit:
title: Potvrdit a pokračovat
text: Opravdu chcete provést tuto akci?
- destroy_work_package:
- title: Potvrdit smazání %{label}
- single_text: Opravdu chcete odstranit tento balíček?
- bulk_text: Opravdu chcete odstranit %{label}?
- has_children: 'Pracovní balíček má %{childUnits}:'
- confirm_deletion_children: Jsem si vědom, že všechny potomky uvedených pracovních balíčků budou rekurzivně odstraněny.
- deletes_children: Všechny podřízené pracovní balíčky a jejich potomci budou také rekurzivně odstraněny.
destroy_time_entry:
title: Potvrdit odstranění záznamu času
text: Opravdu chcete odstranit následující časovou položku?
diff --git a/config/locales/crowdin/js-da.yml b/config/locales/crowdin/js-da.yml
index edb28721551..6337f9f4311 100644
--- a/config/locales/crowdin/js-da.yml
+++ b/config/locales/crowdin/js-da.yml
@@ -515,12 +515,6 @@ da:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ da:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Tildelt
- responsible: Accountable
- shared: Shared
- watched: Tilsynsførende
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ da:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Nyheder tilføjet
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wikiside tilføjet
- wiki_page_updated: Wikiside opdateret
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Sikker?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ da:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-de.yml b/config/locales/crowdin/js-de.yml
index 3e151196b1a..86a946bc6f1 100644
--- a/config/locales/crowdin/js-de.yml
+++ b/config/locales/crowdin/js-de.yml
@@ -143,7 +143,7 @@ de:
description_available_columns: Verfügbare Spalten
description_current_position: 'Sie sind hier: '
description_select_work_package: 'Arbeitspaket #%{id} auswählen'
- description_subwork_package: 'Unteraufgabe von Arbeitspaket #%{id}'
+ description_subwork_package: 'Kind von Arbeitspaket #%{id}'
editor:
revisions: Lokale Änderungen anzeigen
no_revisions: Keine lokalen Änderungen gefunden
@@ -460,7 +460,7 @@ de:
label_total_progress: "%{percent}% Gesamtfortschritt"
label_total_amount: 'Gesamt: %{amount}'
label_updated_on: aktualisiert am
- label_value_derived_from_children: "(aggregierter Wert von Unteraufgaben)"
+ label_value_derived_from_children: "(aggregierter Wert von Kindelementen)"
label_children_derived_duration: Aggregierte Dauer der Unteraufgaben
label_warning: Warnung
label_work_package: Arbeitspaket
@@ -515,12 +515,6 @@ de:
sidebar_arrow: Benutzen Sie den Pfeil in der oberen linken Ecke um zum Hauptmenü des Projekts zurückzukehren.
welcome: Lernen Sie in drei Minuten die wichtigen Funktionen kennen. Wir empfehlen Ihnen, die Tour vollständig abzuschließen. Sie können diese jederzeit wieder neu starten.
wiki: Im Wiki können Sie gemeinsam mit dem Team Informationen dokumentieren und eine Wissensdatenbank aufbauen.
- backlogs:
- overview: Verwalten Sie Ihre Arbeit in der -Backlogs Ansicht.
- sprints: Rechts befinden sich das Product Backlog und das Bug Backlog, links die jeweiligen Sprints. Hier können Sie Epics, User Stories und Bugs (Fehler) anlegen, mit Drag and Drop priorisieren und einem Sprint zuweisen.
- task_board_arrow: Um das Taskboard zu sehen, öffnen Sie das Sprint Drop-down Menü...
- task_board_select: "… und wählen Sie den Menüpunkt Taskboard."
- task_board: Das Aufgabenfeld visualisiert den Fortschritt für diesen Sprint. Klicken Sie auf das Plus (+) Symbol neben einer User Story, um neue Aufgaben oder Hindernisse hinzuzufügen. Der Status kann per Drag & Drop aktualisiert werden.
boards:
overview: Wählen Sie Boards aus, um eine andere Sicht auf Ihr Projekt zu erhalten und es in der agilen Board-Ansicht zu verwalten.
lists_kanban: Hier können Sie mehrere Listen (Spalten) innerhalb Ihres Boards erstellen. Mit dieser Funktion können Sie zum Beispiel ein Kanban Board erstellen.
@@ -594,49 +588,6 @@ de:
settings:
change_notification_settings: Sie können Ihre Benachrichtigungseinstellungen ändern, um sicherzustellen, dass Sie keine wichtige Aktualisierung verpassen.
title: Benachrichtigungseinstellungen
- notify_me: Benachrichtige mich
- reminders:
- no_notification: Keine Benachrichtigung
- timeframes:
- normal:
- PT0S: am selben Tag
- P1D: 1 Tag vorher
- P3D: 3 Tage vorher
- P7D: eine Woche vorher
- overdue:
- P1D: jeden Tag
- P3D: alle 3 Tage
- P7D: jede Woche
- reasons:
- mentioned:
- title: Erwähnt
- description: Jedes Mal eine Benachrichtigung erhalten, wenn ich irgendwo erwähnt werde
- assignee: Zugewiesen an
- responsible: Verantwortlich
- shared: Geteilt
- watched: Beobachter
- work_package_commented: Alle neuen Kommentare
- work_package_created: Neue Arbeitspakete
- work_package_processed: Änderungen am Status
- work_package_prioritized: Änderungen der Priorität
- work_package_scheduled: Alle Datumsänderungen
- global:
- immediately:
- title: Beteiligt
- description: Benachrichtigungen für alle Aktivitäten in Arbeitspaketen, an denen Sie beteiligt sind (Zugewiesen an, Verantwortlicher oder Beobachter).
- delayed:
- title: Nicht beteiligt
- description: Zusätzliche Benachrichtigungen für Aktivitäten in allen Projekten.
- date_alerts:
- title: Datums-Erinnerungen
- description: Automatische Benachrichtigungen, wenn wichtige Termine für offene Arbeitspakete bevorstehen, an denen Sie beteiligt (z. B. zugewiesen, verantwortlich oder Beobachter) sind.
- overdue: Wenn überfällig
- project_specific:
- title: Projektspezifische Benachrichtigungseinstellungen
- description: Diese projektspezifischen Einstellungen überschreiben die Standardeinstellungen oben
- add: Einstellung für Projekt hinzufügen
- already_selected: Dieses Projekt ist bereits ausgewählt
- remove: Projektspezifische Einstellungen entfernen
pagination:
no_other_page: Sie befinden sich auf der einzigen Seite.
pages_skipped: Seiten übersprungen.
@@ -660,39 +611,6 @@ de:
required_outside_context: 'Bitte wählen Sie ein Projekt für das Arbeitspaket, um alle Attribute anzuzeigen. Sie können nur Projekte auswählen, für die der ausgewählte Typ oben aktiviert ist.
'
- reminders:
- settings:
- daily:
- add_time: Zeit hinzufügen
- enable: Tägliche E-Mail-Erinnerungen aktivieren
- explanation: Sie erhalten diese Erinnerungen nur für ungelesene Benachrichtigungen und nur zu Uhrzeiten, die Sie angegeben haben. %{no_time_zone}
- no_time_zone: Bis Sie eine Zeitzone für Ihr Konto konfigurieren, sind diese Zeiten als UTC (GMT+0) zu verstehen.
- time_label: 'Zeit %{counter}:'
- title: Tägliche E-Mail-Erinnerungen für ungelesene Benachrichtigungen zusenden
- workdays:
- title: E-Mail-Erinnerungen an diesen Tagen erhalten
- immediate:
- title: Eine E-Mail Erinnerung an mich senden
- mentioned: Sofort, wenn mich jemand @erwähnt
- personal_reminder: Sofort, wenn ich eine persönliche Erinnerung erhalte
- alerts:
- title: E-Mail-Benachrichtigungen für andere Objekte (die keine Arbeitspakete sind)
- explanation: 'Die Benachrichtigungen sind aktuell auf Arbeitspakete beschränkt. Sie können die E-Mail-Benachrichtigungen für diese Ereignisse so lange erhalten, bis sie in den Benachrichtigungen enthalten sind:
-
- '
- news_added: Neuigkeiten hinzugefügt
- news_commented: Kommentar zu einer Neuigkeit
- document_added: Dokumente hinzugefügt
- forum_messages: Neue Nachrichten im Forum
- wiki_page_added: Wiki-Seite hinzugefügt
- wiki_page_updated: Wiki-Seite aktualisiert
- membership_added: Mitgliedschaft hinzugefügt
- membership_updated: Mitgliedschaft aktualisiert
- title: E-Mail-Erinnerungen
- pause:
- label: Tägliche E-Mail-Erinnerungen vorübergehend pausieren
- first_day: Erster Tag
- last_day: Letzter Tag
text_are_you_sure: Sind Sie sicher?
text_are_you_sure_to_cancel: Sie haben ungespeicherte Änderungen auf dieser Seite. Sind Sie sicher, dass Sie diese verwerfen möchten?
breadcrumb: Navigationspfad
@@ -872,7 +790,7 @@ de:
title: Neues Arbeitspaket
header: 'Neu: %{type}'
header_no_type: Neues Arbeitspaket (Typ noch nicht gesetzt)
- header_with_parent: 'Neu: %{type} (Unteraufgabe von %{parent_type} #%{id})'
+ header_with_parent: 'Neu: %{type} (Kind von %{parent_type} #%{id})'
button: Erstellen
duplicate:
title: Arbeitspaket duplizieren
@@ -1065,13 +983,6 @@ de:
form_submit:
title: Bestätigen, um fortzufahren
text: Sind Sie sicher, dass Sie diese Aktion durchführen möchten?
- destroy_work_package:
- title: Löschen von %{label} bestätigen
- single_text: Sind Sie sicher, dass Sie das Arbeitspaket löschen möchten?
- bulk_text: Sind Sie sicher, dass Sie die folgenden %{label} löschen möchten?
- has_children: 'Dieses Arbeitspaket hat %{childUnits}:'
- confirm_deletion_children: Ich bestätige, dass alle Unteraufgaben der hier aufgeführten Arbeitspakete rekursiv entfernt werden.
- deletes_children: Alle Unteraufgaben und deren Nachkommen werden auch rekursiv gelöscht.
destroy_time_entry:
title: Löschen der Zeitbuchung bestätigen
text: Sind Sie sicher, dass Sie die folgende Zeitbuchung löschen möchten?
diff --git a/config/locales/crowdin/js-el.yml b/config/locales/crowdin/js-el.yml
index b0d35cfaa7a..47e4b8f2af0 100644
--- a/config/locales/crowdin/js-el.yml
+++ b/config/locales/crowdin/js-el.yml
@@ -515,12 +515,6 @@ el:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ el:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Ανάθεση σε
- responsible: Υπόλογος
- shared: Shared
- watched: Παρατηρητής
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: Βρίσκεστε στη μοναδική σελίδα.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ el:
required_outside_context: 'Παρακαλούμε επιλέξτε ένα έργο μέσα στο οποίο θα δημιουργήσετε το πακέτο εργασίας για να δείτε όλα τα χαρακτηριστικά. Μπορείτε να επιλέξετε μόνο έργα που έχουν τον παραπάνω τύπο ενεργό.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Νέα προστέθηκαν
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Η σελίδα Wiki προστέθηκε
- wiki_page_updated: Η σελίδα Wiki ενημερώθηκε
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Είστε σίγουρος/η;
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ el:
form_submit:
title: Επιβεβαιώστε για να συνεχίσετε
text: Είστε βέβαιοι ότι θέλετε να προβείτε αυτήν την ενέργεια;
- destroy_work_package:
- title: Επιβεβαίωση διαγραφής του %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Το πακέτο εργασίας έχει %{childUnits}:'
- confirm_deletion_children: Αναγνωρίζω ότι ΌΛΟΙ οι απόγονοι από τα αναφερόμενα πακέτα εργασίας θα αφαιρεθούν αναδρομικά.
- deletes_children: Όλα τα παιδιά πακέτα εργασίας και οι απόγονοι τους επίσης θα διαγραφούν αναδρομικά.
destroy_time_entry:
title: Επιβεβαίωση διαγραφής καταχώρησης χρόνου
text: Είστε βέβαιοι ότι θέλετε να διαγράψετε την ακόλουθη καταχώρηση χρόνου
diff --git a/config/locales/crowdin/js-eo.yml b/config/locales/crowdin/js-eo.yml
index 0dbf981dd45..aa809a8f2b6 100644
--- a/config/locales/crowdin/js-eo.yml
+++ b/config/locales/crowdin/js-eo.yml
@@ -515,12 +515,6 @@ eo:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ eo:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Asignita al
- responsible: Respondeculo
- shared: Shared
- watched: Atentanto
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ eo:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Novaĵoj aldonitaj
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ eo:
form_submit:
title: Konfirmi por daŭrigi
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Konfirmu forigon de %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'La laborpakaĵo estis %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-es.yml b/config/locales/crowdin/js-es.yml
index bdde5c5579f..06e82c44b0a 100644
--- a/config/locales/crowdin/js-es.yml
+++ b/config/locales/crowdin/js-es.yml
@@ -513,12 +513,6 @@ es:
sidebar_arrow: Usa la flecha de retorno en la esquina superior izquierda para regresar al menú principal del proyecto.
welcome: Realice un recorrido de introducción de tres minutos para conocer las funciones más importantes. Le recomendamos que complete todos los pasos. Puede volver a iniciar el paseo en cualquier momento.
wiki: En la wiki, puede elaborar documentos y compartir conocimientos con su equipo.
- backlogs:
- overview: Administre su trabajo en la vista de trabajos pendientes.
- sprints: A la derecha verá los trabajos pendientes de productos y errores de código, y a la izquierda se muestran los sprints correspondientes. Aquí puede crear épicas, historias de usuario y errores de código, asignar prioridades mediante funciones de arrastrar y colocar, y añadir elementos a un sprint.
- task_board_arrow: Para ver el tablero de tareas, abra el menú desplegable sprint…
- task_board_select: "… y seleccione la entrada del tablero de tareas."
- task_board: En el tablero de tareas, se muestra el progreso de este sprint. Haga clic en el icono del signo más (+) junto a una historia de usuario para añadir nuevas tareas o impedimentos. Puede actualizar el estado mediante las funciones de arrastrar y colocar.
boards:
overview: Seleccione los tableros para cambiar la vista y gestione su proyecto con la vista de tableros Agile.
lists_kanban: Aquí puede crear varias listas (columnas) en el tablero. Por ejemplo, esta función le permite crear un tablero Kanban.
@@ -590,49 +584,6 @@ es:
settings:
change_notification_settings: Puede modificar su configuración de notificaciones para asegurarse que nunca se pierda una actualización importante.
title: Ajustes de notificación
- notify_me: Notifícame
- reminders:
- no_notification: Sin notificación
- timeframes:
- normal:
- PT0S: mismo día
- P1D: 1 día antes
- P3D: 3 días antes
- P7D: una semana antes
- overdue:
- P1D: todos los días
- P3D: cada 3 días
- P7D: todas las semanas
- reasons:
- mentioned:
- title: Mencionado
- description: Recibir una notificación cada vez que un usuario me mencione
- assignee: Asignado a
- responsible: Responsable
- shared: Compartido
- watched: Observador
- work_package_commented: Todos los nuevos comentarios
- work_package_created: Nuevos paquetes de trabajo
- work_package_processed: Todos los cambios de estado
- work_package_prioritized: Todos los cambios de prioridad
- work_package_scheduled: Todos los cambios de fecha
- global:
- immediately:
- title: Participado
- description: Notificaciones para todas las actividades en paquetes de trabajo en los que usted está involucrado (asignado, responsable u observador).
- delayed:
- title: No participando
- description: Notificaciones adicionales para actividades en todos los proyectos.
- date_alerts:
- title: Alertas de fecha
- description: Notificaciones automáticas cuando se acercan fechas importantes para paquetes de trabajo abiertos en los que está involucrado (asignado, responsable u observador).
- overdue: Cuando vencido
- project_specific:
- title: Configuración de notificaciones específicas de proyectos
- description: Esta configuración específica de proyectos reemplaza los ajustes predeterminados anteriores.
- add: Añadir configuración para el proyecto
- already_selected: Este proyecto ya está seleccionado
- remove: Eliminar configuración del proyecto
pagination:
no_other_page: Usted está en la única página.
pages_skipped: Páginas omitidas.
@@ -656,39 +607,6 @@ es:
required_outside_context: 'Seleccione el proyecto donde quiere crear el paquete de trabajo para ver todos los atributos. Solo puede seleccionar proyectos que tengan activado el tipo de paquete utilizado.
'
- reminders:
- settings:
- daily:
- add_time: Añadir tiempo
- enable: Habilitar recordatorios por correo electrónico diarios
- explanation: Solo recibirá estos recordatorios para las notificaciones sin leer y en las horas que especifique. %{no_time_zone}
- no_time_zone: Hasta que configure una zona horaria para su cuenta, las horas se interpretarán en UTC.
- time_label: 'Tiempo %{counter}:'
- title: Enviarme recordatorios por correo electrónico diarios con las notificaciones sin leer
- workdays:
- title: Recibir recordatorios por correo electrónico en estos días
- immediate:
- title: Enviarme un recordatorio por correo electrónico
- mentioned: De inmediato cuando alguien me @mencione
- personal_reminder: Inmediatamente al recibir un recordatorio personal
- alerts:
- title: Alertas por correo electrónico de otros elementos (que no sean paquetes de trabajo)
- explanation: 'Las notificaciones por ahora están limitadas a los paquetes de trabajo. Puede elegir seguir recibiendo alertas por correo electrónico de estos eventos hasta que se incluyan en las notificaciones:
-
- '
- news_added: Noticias añadidas
- news_commented: Comentarios en un elemento de noticias
- document_added: Documentos añadidos
- forum_messages: Nuevos mensajes en foro
- wiki_page_added: Página wiki añadida
- wiki_page_updated: Página wiki actualizada
- membership_added: Subscripción añadida
- membership_updated: Subscripción actualizada
- title: Recordatorios por correo electrónico
- pause:
- label: Pausar temporalmente los recordatorios por correo electrónico diarios
- first_day: Primer día
- last_day: Último día
text_are_you_sure: "¿Estás seguro?"
text_are_you_sure_to_cancel: Tiene cambios sin guardar en esta página. ¿Seguro que quiere descartarlos?
breadcrumb: Ruta de navegación
@@ -1061,13 +979,6 @@ es:
form_submit:
title: Confirme para continuar
text: "¿Seguro que desea realizar esta acción?"
- destroy_work_package:
- title: Confirmar la eliminación de %{label}
- single_text: Está seguro que desea eliminar este paquete de trabajo
- bulk_text: "¿Estás seguro de que quiere eliminar el siguiente %{label}?"
- has_children: 'El paquete de trabajo tiene %{childUnits}:'
- confirm_deletion_children: Reconozco que TODOS los descendientes de los paquetes de trabajo enumerados se eliminarán recursivamente.
- deletes_children: También se eliminarán de forma recursiva todos los sub-paquetes de trabajo y sus descendientes.
destroy_time_entry:
title: Confirmar la eliminación de la entrada de tiempo
text: "¿Realmente quiere eliminar la siguiente entrada de tiempo?"
diff --git a/config/locales/crowdin/js-et.yml b/config/locales/crowdin/js-et.yml
index 2c43842063e..1777a5cfcf6 100644
--- a/config/locales/crowdin/js-et.yml
+++ b/config/locales/crowdin/js-et.yml
@@ -515,12 +515,6 @@ et:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ et:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mainitud
- description: Receive a notification every time someone mentions me anywhere
- assignee: Määratud tegija
- responsible: Accountable
- shared: Jagatud
- watched: Jälgija
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ et:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Uudis lisatud
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Viki leht on lisatud
- wiki_page_updated: Viki leht on uuendatud
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Kas oled kindel?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ et:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-eu.yml b/config/locales/crowdin/js-eu.yml
index d5a00cb840d..5849d78b37d 100644
--- a/config/locales/crowdin/js-eu.yml
+++ b/config/locales/crowdin/js-eu.yml
@@ -515,12 +515,6 @@ eu:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ eu:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ eu:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ eu:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-fa.yml b/config/locales/crowdin/js-fa.yml
index ef7ba039e6f..36c4f820b8e 100644
--- a/config/locales/crowdin/js-fa.yml
+++ b/config/locales/crowdin/js-fa.yml
@@ -515,12 +515,6 @@ fa:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: کار خود را در نمای backlogs مدیریت کنید.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ fa:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: نماینده
- responsible: Accountable
- shared: Shared
- watched: ناظر
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: اطلاعیه (اعلان) برای تمام فعالیتها در پکیجهای کاری که در آنها شرکت دارید (به عنوان مسئول، متولی یا تماشاگر).
- delayed:
- title: Non-participating
- description: اعلانهای اضافی برای فعالیتها در تمام پروژهها
- date_alerts:
- title: Date alerts
- description: اعلانهای خودکار هنگام نزدیک شدن تاریخهای مهم برای پکیجهای کاری باز که در آنها شرکت دارید (به عنوان مسئول، متولی یا تماشاگر).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: این تنظیمات خاص پروژه تنظیمات پیشفرض بالا را بازنویسی میکنند.
- add: Add setting for project
- already_selected: این پروژه قبلاً انتخاب شده است
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ fa:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: آیا مطمئن هستید؟
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ fa:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: تایید حذف %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'بسته کار دارای %{childUnits} است:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-fi.yml b/config/locales/crowdin/js-fi.yml
index 053f8f05791..f2d8ae4680d 100644
--- a/config/locales/crowdin/js-fi.yml
+++ b/config/locales/crowdin/js-fi.yml
@@ -515,12 +515,6 @@ fi:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ fi:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Työn suorittaja
- responsible: Vastuuhenkilö
- shared: Shared
- watched: Seuraajat
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: Olet jo ainoalla sivulla.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ fi:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Uutinen lisätty
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki-sivu lisätty
- wiki_page_updated: Wiki-sivu päivitetty
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Oletko varma?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ fi:
form_submit:
title: Vahvista jatkaaksesi
text: Oletko varma, että haluat suorittaa tämän toiminnon?
- destroy_work_package:
- title: 'Vahvista poisto: %{label}'
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Vahvista
text: Haluatko varmasti poistaa tämän aikakirjauksen?
diff --git a/config/locales/crowdin/js-fil.yml b/config/locales/crowdin/js-fil.yml
index f14b44cfc35..cdce47f357a 100644
--- a/config/locales/crowdin/js-fil.yml
+++ b/config/locales/crowdin/js-fil.yml
@@ -515,12 +515,6 @@ fil:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ fil:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Naitalaga
- responsible: Accountable
- shared: Shared
- watched: Tagapagmasid
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: Ikaw ay nasa pahina lamang.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ fil:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Bagong idinagdag
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Ang idinagdag na wiking pahina
- wiki_page_updated: Naka-update na wiking pahina
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Sigurado ka ba?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ fil:
form_submit:
title: Kumpirmahin upang magpatuloy
text: Sigurado ka bang na gusto mong magtanghal ng aksyon ito?
- destroy_work_package:
- title: Kumpirmahin ang pagbubura ng %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Ang work package ay mayroong %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-fr.yml b/config/locales/crowdin/js-fr.yml
index 28213a57b9c..fe6129b1443 100644
--- a/config/locales/crowdin/js-fr.yml
+++ b/config/locales/crowdin/js-fr.yml
@@ -515,12 +515,6 @@ fr:
sidebar_arrow: Utilisez la flèche de retour dans le coin supérieur gauche pour retourner au menu principal du projet.
welcome: Faites une visite d’introduction de trois minutes pour apprendre les fonctionnalités les plus importantes. Il est recommandé d’effectuer les étapes jusqu'à la fin. Vous pouvez redémarrer cette visite à tout moment.
wiki: Dans le wiki vous pouvez documenter et partager vos connaissances avec votre équipe.
- backlogs:
- overview: Gérez votre travail dans la vue backlogs.
- sprints: Sur la droite, vous avez le backlog de produit et le backlog des bugs. Sur la gauche, vous avez leurs sprints respectifs. Ici, vous pouvez créer des epics, user stories et bugs, les prioriser via glisser-déposer et les ajouter à un sprint.
- task_board_arrow: Pour voir votre Tableau de bord des Tâches, ouvrez le menu déroulant Sprint...
- task_board_select: "…et sélectionnez l'entrée Tableau de bord des Tâches."
- task_board: Le tableau des tâches visualise la progression pour ce sprint. Cliquez sur l'icône plus (+) à côté d'une user story pour ajouter de nouvelles tâches ou de nouveaux obstacles. Le statut peut être mis à jour par glisser-déposer.
boards:
overview: Sélectionnez tableaux pour déplacer la vue et gérer votre projet en utilisant la vue des tableaux agiles.
lists_kanban: Ici, vous pouvez créer plusieurs listes (colonnes) dans votre tableau. Cette fonctionnalité vous permet de créer un tableau Kanban, par exemple.
@@ -592,49 +586,6 @@ fr:
settings:
change_notification_settings: Vous pouvez modifier vos paramètres de notification pour vous assurer de ne jamais manquer une mise à jour importante.
title: Paramètres de notifications
- notify_me: M'alerter
- reminders:
- no_notification: Aucune notification
- timeframes:
- normal:
- PT0S: le jour même
- P1D: 1 jour avant
- P3D: 3 jours avant
- P7D: une semaine avant
- overdue:
- P1D: tous les jours
- P3D: tous les 3 jours
- P7D: toutes les semaines
- reasons:
- mentioned:
- title: Mentionné
- description: Recevoir une notification chaque fois que quelqu'un me mentionne n'importe où
- assignee: Assigné à
- responsible: Responsable
- shared: Partagé
- watched: Observateur
- work_package_commented: Tous les nouveaux commentaires
- work_package_created: Nouveaux lots de travaux
- work_package_processed: Tous les changements de statut
- work_package_prioritized: Tous les changements de priorité
- work_package_scheduled: Tous les changements de date
- global:
- immediately:
- title: Participant
- description: Notifications pour toute activité sur les lots de travaux vous concernant (assigné, responsable ou observateur).
- delayed:
- title: Non participant
- description: Notifications additionnelles lors d'activités sur tous les projets.
- date_alerts:
- title: Alertes de date
- description: Notifications automatiques lorsque des dates importantes approchent pour les lots de travaux ouverts vous concernant (assigné, responsable ou observateur).
- overdue: En cas de retard
- project_specific:
- title: Paramètres de notification spécifiques au projet
- description: Ces paramètres spécifiques au projet remplacent les paramètres par défaut ci-dessus.
- add: Ajouter un paramètre pour le projet
- already_selected: Ce projet est déjà sélectionné
- remove: Suppression des paramètres de projet
pagination:
no_other_page: Vous êtes sur la seule page.
pages_skipped: Pages ignorées.
@@ -658,39 +609,6 @@ fr:
required_outside_context: 'Veuillez choisir un projet pour créer le lot de travaux et voir tous les attributs. Vous pouvez seulement sélectionner des projets ayant le type ci-dessus activé.
'
- reminders:
- settings:
- daily:
- add_time: Ajouter une heure
- enable: Activer les rappels quotidiens par e-mail
- explanation: Vous ne recevrez ces rappels que pour les notifications non lues et seulement aux heures que vous spécifiez. %{no_time_zone}
- no_time_zone: Jusqu'à ce que vous configurez un fuseau horaire pour votre compte, les temps seront interprétés en UTC.
- time_label: 'Temps %{counter} :'
- title: Envoyez-moi des rappels quotidiens par e-mail pour les notifications non lues
- workdays:
- title: Recevoir des rappels par e-mail ces jours
- immediate:
- title: Envoyez-moi un rappel par e-mail
- mentioned: Immédiatement quand quelqu'un me @mentionne
- personal_reminder: Immédiatement lorsque je reçois un rappel personnel
- alerts:
- title: Alertes par e-mail pour les autres éléments (qui ne sont pas des lots de travaux)
- explanation: 'Les notifications d''aujourd''hui sont limitées aux lots de travaux. Vous pouvez choisir de continuer à recevoir des alertes par e-mail pour ces événements jusqu''à ce qu''elles soient incluses dans les notifications:
-
- '
- news_added: Actualités ajoutées
- news_commented: Commenter sur une actualité
- document_added: Documents ajoutés
- forum_messages: Nouveaux messages du forum
- wiki_page_added: Page wiki ajoutée
- wiki_page_updated: Page wiki mise à jour
- membership_added: Adhésion ajoutée
- membership_updated: Adhésion mise à jour
- title: Rappels par e-mail
- pause:
- label: Mettre temporairement en pause les rappels quotidiens par e-mail
- first_day: Premier jour
- last_day: Dernier jour
text_are_you_sure: Êtes-vous sûr ?
text_are_you_sure_to_cancel: Vous avez des modifications non enregistrées sur cette page. Voulez-vous vraiment les supprimer ?
breadcrumb: Fil d'Ariane
@@ -1063,13 +981,6 @@ fr:
form_submit:
title: Confirmez pour continuer
text: Êtes-vous sûr de vouloir effectuer cette action ?
- destroy_work_package:
- title: Confirmer la suppression de %{label}
- single_text: Voulez-vous vraiment supprimer le lot de travaux
- bulk_text: Voulez-vous vraiment supprimer le %{label} suivant ?
- has_children: 'Le lot de travaux a %{childUnits} :'
- confirm_deletion_children: Je reconnais que TOUS les descendants des lots de travaux de la liste seront supprimés récursivement.
- deletes_children: Tous les lots de travaux enfants et leurs descendants seront également supprimés récursivement.
destroy_time_entry:
title: Confirmer la suppression de l’entrée de temps
text: Êtes-vous sur de vouloir supprimer l'entrée de temps suivante ?
diff --git a/config/locales/crowdin/js-he.yml b/config/locales/crowdin/js-he.yml
index 71b534d073a..dd7cbcb4097 100644
--- a/config/locales/crowdin/js-he.yml
+++ b/config/locales/crowdin/js-he.yml
@@ -515,12 +515,6 @@ he:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -594,49 +588,6 @@ he:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: משויך אל
- responsible: Accountable
- shared: Shared
- watched: צופה
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -660,39 +611,6 @@ he:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: האם הינך בטוח?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1065,13 +983,6 @@ he:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-hi.yml b/config/locales/crowdin/js-hi.yml
index c27c925e6e5..642a717e2db 100644
--- a/config/locales/crowdin/js-hi.yml
+++ b/config/locales/crowdin/js-hi.yml
@@ -515,12 +515,6 @@ hi:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ hi:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: अनुदिष्ट
- responsible: जवाबदेह
- shared: Shared
- watched: वॉचर
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ hi:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: विकी पृष्ठ अद्यतित
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ hi:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-hr.yml b/config/locales/crowdin/js-hr.yml
index ac3ad1133a1..67c0035186c 100644
--- a/config/locales/crowdin/js-hr.yml
+++ b/config/locales/crowdin/js-hr.yml
@@ -515,12 +515,6 @@ hr:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -593,49 +587,6 @@ hr:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Opunomoćeno
- responsible: Accountable
- shared: Shared
- watched: Nadglednik
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -659,39 +610,6 @@ hr:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Vijest dodana
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki stranica dodana
- wiki_page_updated: Wiki stranica ažurirana
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Da li ste sigurni?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1064,13 +982,6 @@ hr:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-hu.yml b/config/locales/crowdin/js-hu.yml
index 628eef119fd..3e630f2f4ce 100644
--- a/config/locales/crowdin/js-hu.yml
+++ b/config/locales/crowdin/js-hu.yml
@@ -527,16 +527,6 @@ hu:
sidebar_arrow: Használja a vissza nyilat bal felül hogy visszatérjen a projektekhez main menu..
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: A Wiki modulban tudását dokumentálhatja és megoszthatja a csapatával.
- backlogs:
- overview: Munka kezelése a backlogs nézetben
- sprints: 'Jobbra a termék- és a hibatár, balra pedig a megfelelő sprintek. Itt létrehozhatsz képeket, felhasználói történeteket és hibákat, drag & drop segítségével priorizálhatsz, és hozzáadhatod őket egy sprinthez.
-
- '
- task_board_arrow: A Feladatlap megjelenítéséhez nyissa meg a Sprint legördülő listát...
- task_board_select: "... és válassza ki a Feladatlap bejegyzést."
- task_board: 'A feladattábla megjeleníti a sprint haladását . Új feladatok vagy akadályok hozzáadásához kattintson a felhasználói történet melletti plusz (+) ikonra. Az állapot húzással frissíthető.
-
- '
boards:
overview: 'Válassza a táblák lehetőséget a nézetváltáshoz, és kezelje projektjét az agilis táblák nézetben.
@@ -626,49 +616,6 @@ hu:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Értesítési beállítások
- notify_me: Értesítést kérek
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Megemlített
- description: Értesítés fogadása minden alkalommal, amikor bárki bárhol megemlít
- assignee: Megbízott
- responsible: Felelős
- shared: Megosztva
- watched: Megfigyelő
- work_package_commented: Új megjegyzések
- work_package_created: Új munkacsomagok
- work_package_processed: Összes státusz változás
- work_package_prioritized: Összes prioritás változás
- work_package_scheduled: Összes dátum változás
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Projekt-specifikus értesítések beállításai
- description: These project-specific settings override default settings above.
- add: Beállítás hozzáadása a projekthez
- already_selected: A projekt már ki lett választva
- remove: Projekt beállítások eltávolítása
pagination:
no_other_page: Csak egyetlen oldalon tartózkodik.
pages_skipped: Pages skipped.
@@ -692,47 +639,6 @@ hu:
required_outside_context: 'Kérjük, válasszon egy projektet a munkacsomag létrehozásához az összes attribútum megtekintéséhez. Csak olyan projekteket választhat ki, amelyek aktiválták a fenti típust.
'
- reminders:
- settings:
- daily:
- add_time: 'Idő hozzáadása
-
- '
- enable: 'Napi e-mail emlékeztetők engedélyezése
-
- '
- explanation: 'Ezeket az emlékeztetőket csak az olvasatlan értesítésekről kapja, és csak az Ön által megadott órákban. %{no_time_zone}
-
- '
- no_time_zone: Amíg a fiókjához nincs időzóna beállítva, addig az időpontok UTC szerint értendők.
- time_label: 'Idő%{counter}:'
- title: 'Napi e-mail emlékeztető küldése az olvasatlan értesítésekről
-
- '
- workdays:
- title: Email emlékeztetők fogadása ezeken a napokon
- immediate:
- title: Kérek email emlékeztetőt!
- mentioned: Amint valaki @megemlít engem
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Hírek hozzáadva
- news_commented: Megjegyzés egy hír elemhez
- document_added: Dokumentum hozzáadva
- forum_messages: Új fórum üzenetek
- wiki_page_added: Wiki oldal hozzáadva
- wiki_page_updated: Wiki oldal frissítve
- membership_added: Felhasználó hozzáadva
- membership_updated: Felhasználó frissítve
- title: E-mail emlékeztetők
- pause:
- label: Napi email emlékeztetők ideiglenes szüneteltetése
- first_day: Első nap
- last_day: Utolsó nap
text_are_you_sure: Biztos vagy benne?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1113,15 +1019,6 @@ hu:
form_submit:
title: Megerősítés a folytatáshoz
text: Biztosan végre szeretné hajtani ezt a műveletet?
- destroy_work_package:
- title: Jóváhagyja %{label} törlését
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'A feladatcsoportnak van %{childUnits}:'
- confirm_deletion_children: 'Tudomásul veszem, hogy a felsorolt munkacsomagok MINDEN leszármazottja rekurzív módon eltávolításra kerül.
-
- '
- deletes_children: Minden al feladatcsoportot és leszármazottait is rekurzívan törli.
destroy_time_entry:
title: Időbejegyzés törlésének jóváhagyása
text: Biztosan törölni akarja a következő időbejegyzést?
diff --git a/config/locales/crowdin/js-id.yml b/config/locales/crowdin/js-id.yml
index a20613bbfef..292ae98be47 100644
--- a/config/locales/crowdin/js-id.yml
+++ b/config/locales/crowdin/js-id.yml
@@ -515,12 +515,6 @@ id:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -591,49 +585,6 @@ id:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Pelimpahan
- responsible: Akuntabel
- shared: Shared
- watched: Pemantau
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -657,39 +608,6 @@ id:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News ditambahkan
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Halaman Wiki ditambahkan
- wiki_page_updated: Halaman Wiki diupdate
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Apakah anda yakin?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1062,13 +980,6 @@ id:
form_submit:
title: Konfirmasi untuk melanjutkan
text: Apakah Anda yakin untuk melakukan tindakan ini?
- destroy_work_package:
- title: Mengkonfirmasi penghapusan %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Paket kerja memiliki %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Apakah Anda ingin menghapus entri waktu berikut?
diff --git a/config/locales/crowdin/js-it.yml b/config/locales/crowdin/js-it.yml
index a976edd5da5..510689b4e83 100644
--- a/config/locales/crowdin/js-it.yml
+++ b/config/locales/crowdin/js-it.yml
@@ -515,12 +515,6 @@ it:
sidebar_arrow: Utilizza la freccia di ritorno nell'angolo in alto a sinistra per tornare al menu principale del progetto.
welcome: Fai un tour introduttivo di tre minuti per apprendere le funzioni importanti. Consigliamo di completare i passaggi fino alla fine. Puoi riavviare il tour in qualsiasi momento.
wiki: Nella wiki puoi documentare e condividere la conoscenza con il tuo team.
- backlogs:
- overview: Gestisci il tuo lavoro nella vista backlog.
- sprints: A destra hai il product backlog e il bug backlog, a sinistra i rispettivi sprint. Qui puoi creare epics, storie utente e bug, assegnare priorità tramite trascinamento e aggiungerli a uno sprint.
- task_board_arrow: Per vedere il tuo pannello delle attività, apri il menu a cascata Sprint...
- task_board_select: "...e seleziona la voce pannello delle attività."
- task_board: Il pannello delle attività visualizza l'avanzamento dello sprint. Fai clic sull'icona più (+) accanto a una storia utente per aggiungere nuove attività o impedimenti. Lo stato può essere aggiornato trascinandolo.
boards:
overview: Seleziona board per cambiare visualizzazione e gestire il tuo progetto utilizzando la visualizzazione agile delle schede.
lists_kanban: Qui puoi creare più liste (colonne) all'interno della tua board. Questa funzione ti consente di creare una board Kanban, ad esempio.
@@ -592,49 +586,6 @@ it:
settings:
change_notification_settings: Puoi modificare le tue impostazioni di notifica per assicurarti di non perderti mai un aggiornamento importante.
title: Impostazioni notifiche
- notify_me: Avvisami
- reminders:
- no_notification: Nessuna notifica
- timeframes:
- normal:
- PT0S: stesso giorno
- P1D: 1 giorno prima
- P3D: 3 giorni prima
- P7D: una settimana prima
- overdue:
- P1D: ogni giorno
- P3D: ogni 3 giorni
- P7D: ogni settimana
- reasons:
- mentioned:
- title: Menzionato
- description: Ricevi una notifica ogni volta che qualcuno ti menziona ovunque
- assignee: Assegnatario
- responsible: Responsabile
- shared: Condiviso
- watched: Osservatore
- work_package_commented: Tutti i nuovi commenti
- work_package_created: Nuove macro-attività
- work_package_processed: Tutte le modifiche di stato
- work_package_prioritized: Tutte le modifiche prioritarie
- work_package_scheduled: Tutte le modifiche della data
- global:
- immediately:
- title: Partecipazione
- description: Notifiche per tutte le attività nelle macro-attività in cui sei coinvolto (assegnatario, responsabile od osservatore)
- delayed:
- title: Non partecipante
- description: Notifiche aggiuntive sulle attività in tutti i progetti
- date_alerts:
- title: Avvisi data
- description: Notifiche automatiche quando si avvicinano date importanti per le macro-attività aperte in cui sei coinvolto (assegnatario, responsabile od osservatore)
- overdue: Alla scadenza
- project_specific:
- title: Impostazioni di notifica specifiche del progetto
- description: Queste impostazioni specifiche del progetto sostituiscono le impostazioni predefinite sopra.
- add: Aggiungi impostazione per il progetto
- already_selected: Questo progetto è già selezionato
- remove: Rimuovi impostazioni progetto
pagination:
no_other_page: Sei nella pagina unica.
pages_skipped: Pagine saltate.
@@ -658,39 +609,6 @@ it:
required_outside_context: 'Scegli un progetto per creare una macro-attività e vederne tutti gli attributi. Puoi selezionare solo progetti che hanno il tipo sopra indicato attivato.
'
- reminders:
- settings:
- daily:
- add_time: Aggiungi tempo
- enable: Abilita promemoria email giornalieri
- explanation: Riceverai questi promemoria solo per le notifiche non lette e solo nelle ore specificate. %{no_time_zone}
- no_time_zone: Fino a quando non configuri un fuso orario per il tuo account, gli orari verranno interpretati in UTC.
- time_label: 'Tempo %{counter}:'
- title: Inviami promemoria email giornalieri per le notifiche non lette
- workdays:
- title: Ricevi promemoria email in questi giorni
- immediate:
- title: Inviami un promemoria email
- mentioned: Subito quando qualcuno mi @menziona
- personal_reminder: Immediatamente quando ricevo un promemoria personale
- alerts:
- title: Avvisi email per altri elementi (che non sono macro-attività)
- explanation: 'Le notifiche oggi sono limitate ai pacchetti di lavoro. Puoi scegliere di continuare a ricevere avvisi email per questi eventi finché non vengono inclusi nelle notifiche:
-
- '
- news_added: Notizie aggiunte
- news_commented: Commento su un articolo di notizie
- document_added: Documenti aggiunti
- forum_messages: Nuovi messaggi del forum
- wiki_page_added: Pagina wiki aggiunta
- wiki_page_updated: Pagina wiki aggiornata
- membership_added: Iscrizione aggiunta
- membership_updated: Iscrizione aggiornata
- title: Promemoria email
- pause:
- label: Sospendi temporaneamente i promemoria email giornalieri
- first_day: 'Primo giorno '
- last_day: Ultimo giorno
text_are_you_sure: Sei sicuro/a?
text_are_you_sure_to_cancel: Ci sono modifiche non salvate in questa pagina. Vuoi davvero eliminarle?
breadcrumb: Percorso di navigazione
@@ -1063,13 +981,6 @@ it:
form_submit:
title: Conferma per continuare
text: Eseguire questa azione?
- destroy_work_package:
- title: Conferma l'eliminazione di %{label}
- single_text: Vuoi davvero eliminare questa macro-attività?
- bulk_text: Eliminare il seguente %{label}?
- has_children: 'Questa macro-attività ha %{childUnits}:'
- confirm_deletion_children: Prendo atto che TUTTI i discendenti delle macro-attività elencate verranno eliminati in modo ricorsivo.
- deletes_children: Tutte le macro-attività ed i relativi discendenti verranno eliminati ricorsivamente.
destroy_time_entry:
title: Conferma l'eliminazione della voce temporale
text: Eliminare la seguente voce temporale?
diff --git a/config/locales/crowdin/js-ja.yml b/config/locales/crowdin/js-ja.yml
index a28fa088b5a..e92442dacf1 100644
--- a/config/locales/crowdin/js-ja.yml
+++ b/config/locales/crowdin/js-ja.yml
@@ -34,12 +34,12 @@ ja:
draggable_hint: |
埋め込み画像または添付ファイルをエディタにドラッグします。
ドラッグしつづけると閉じているエディタ領域が開きます。
- quarantined_hint: ウイルスが発見されたように、ファイルは隔離されています。ダウンロードできません。
+ quarantined_hint: ウイルスが発見されたため,ファイルは隔離されています。ダウンロードできません。
autocomplete_ng_select:
- add_tag: アイテムを追加
+ add_tag: 項目を追加
clear_all: すべてクリア
loading: 読み込み中...
- not_found: アイテムが見つかりません
+ not_found: 見つかりませんでした
type_to_search: 検索キーワードを入力
autocomplete_select:
placeholder:
@@ -71,7 +71,7 @@ ja:
button_back_to_list_view: リスト表示に戻る
button_cancel: キャンセル
button_close: 閉じる
- button_change_project: 別のプロジェクトに移動
+ button_change_project: 他のプロジェクトに移る
button_check_all: 全てを選択
button_configure-form: フォームを設定
button_confirm: 確認
@@ -79,7 +79,7 @@ ja:
button_copy: コピー
button_copy_to_clipboard: クリップボードにコピー
button_copy_link_to_clipboard: クリップボードにリンクをコピー
- button_copy_to_other_project: 別のプロジェクトで複製
+ button_copy_to_other_project: 別のプロジェクトで複製する
button_custom-fields: カスタムフィールド
button_delete: 削除
button_delete_watcher: ウォッチャーを削除
@@ -101,7 +101,7 @@ ja:
button_open_fullscreen: 全画面表示を開く
button_show_cards: カードビュー表示
button_show_list: リストビュー表示
- button_show_table: テーブルビューを表示
+ button_show_table: テーブル表示
button_show_gantt: ガントビューを表示
button_show_fullscreen: 全画面表示
button_more_actions: その他の操作
@@ -111,7 +111,7 @@ ja:
button_uncheck_all: 全てを選択解除
button_update: 更新
button_export-atom: Atomをダウンロード
- button_generate_pdf: PDFを生成
+ button_generate_pdf: PDF作成
button_create: 作成
card:
add_new: 新規カード追加
@@ -145,8 +145,8 @@ ja:
description_select_work_package: 'ワークパッケージを選択 #%{id}'
description_subwork_package: 'ワークパッケージの子 #%{id}'
editor:
- revisions: ローカルの変更を表示
- no_revisions: ローカルの変更は見つかりませんでした
+ revisions: ローカルの修正を表示
+ no_revisions: ローカルでの修正は見つからず
preview: プレビューモードの切り替え
source_code: Markdown ソースモードの切り替え
error_saving_failed: '次のエラーで文書を保存するのに失敗しました: %{error}'
@@ -159,7 +159,7 @@ ja:
attribute_reference:
macro_help_tooltip: このテキストセグメントはマクロによって動的にレンダリングされています。
not_found: 要求されたリソースが見つかりませんでした
- nested_macro: このマクロは %{model} %{id} を再帰的に参照しています。
+ nested_macro: このマクロは %{model} %{id}を再帰的に参照している。
invalid_attribute: 選択した属性 '%{name}' は存在しません。
child_pages:
button: 子ページへのリンク
@@ -216,10 +216,10 @@ ja:
calendar:
empty_state_header: 休業日
empty_state_description: 休業日が定義されていません。「休業日を追加」ボタンをクリックして日付を追加してください。
- new_date: "(新規)"
+ new_date: "(新)"
add_non_working_day: 休業日を追加
- already_added_error: この日付の非作業日はすでに存在します。それぞれの日付に1つの非作業日が作成されます。
- change_button: 保存してスケジュールを変更
+ already_added_error: この日付の非営業日はすでに存在します。一意の日付に対して作成できる非営業日は1つだけです。
+ change_button: 保存して再スケジュール
change_title: 営業日を変更する
removed_title: 以下の日を非稼働日リストから削除します:
change_description: 営業日とみなす曜日を変更すると、このサイト内のすべてのプロジェクトのすべてのワークパッケージの開始日と終了日に影響を与える可能性があります。
@@ -301,14 +301,14 @@ ja:
ical_sharing_modal:
title: カレンダーを購読する
inital_setup_error_message: データ取得中にエラーが発生しました。
- description: URL(iCalendar)を使って外部クライアントでこのカレンダーを購読し、そこから最新のワークパッケージ情報を見ることができます。
- warning: このURLを他のユーザーと共有しないでください。このリンクがあれば、誰でもアカウントやパスワードなしでワークパッケージの詳細を見ることができます。
- token_name_label: どこで使うのですか?
+ description: URL(iCalendar)を使用して、外部クライアントでこのカレンダーを購読し、そこから最新のワークパッケージ情報を表示することができます。
+ warning: このURLを他のユーザーと共有しないでください。このリンクを持つ誰でもアカウントやパスワードなしでワークパッケージの詳細を表示することができます。
+ token_name_label: どこで使うのですか??
token_name_placeholder: 名前を入力してください。例:"電話"
token_name_description_text: If you subscribe to this calendar from multiple devices, this name will help you distinguish between them in your access tokens list.
copy_url_label: URLをコピー
- ical_generation_error_text: カレンダー URL の生成中にエラーが発生しました。
- success_message: URL "%{name}" は正常にクリップボードにコピーされました。サブスクリプションを完了するためにカレンダークライアントに貼り付けてください。
+ ical_generation_error_text: カレンダーのURL生成時にエラーが発生しました。
+ success_message: URL "%{name}" がクリップボードにコピーされました。カレンダークライアントに貼り付けて購読を完了してください。
label_activate: 有効にする
label_assignee: 担当者
label_assignee_alt_text: This work package is assigned to %{name}
@@ -321,7 +321,7 @@ ja:
label_add_row_before: 前に行を追加
label_add_selected_columns: 選択した列を追加
label_added_by: 追加した人
- label_added_time_by: %{author} が %{age} に追加しました
+ label_added_time_by: 追加 %{author} %{age}
label_ago: "○日前"
label_all: 全て
label_all_projects: すべてのプロジェクト
@@ -432,7 +432,7 @@ ja:
label_repository_plural: リポジトリ
label_resize_project_menu: Resize project menu
label_save_as: 名前をつけて保存
- label_search_columns: 列を検索
+ label_search_columns: 列を検索する
label_select_watcher: ウォッチャーを選択...
label_selected_filter_list: 選択されたフィルタ
label_show_attributes: すべての属性を表示
@@ -470,8 +470,8 @@ ja:
label_watch_work_package: ワークパッケージをウォッチ
label_watcher_added_successfully: ウォッチャーが正常に追加されました !
label_watcher_deleted_successfully: ウォッチャーが正常に削除されました !
- label_work_package_details_you_are_here: あなたは %{tab} %{type} %{subject} のタブにいます。
- label_work_package_context_menu: ワークパッケージのコンテキスト メニュー
+ label_work_package_details_you_are_here: あなたは %{type} %{subject}の %{tab} タブを表示しています。
+ label_work_package_context_menu: ワークパッケージのコンテキストメニュー
label_unwatch: ウォッチしない
label_unwatch_work_package: ワークパッケージのウォッチを削除
label_uploaded_by: アップロードした人
@@ -502,7 +502,7 @@ ja:
label_version_plural: バージョン
label_view_has_changed: このビューには未保存の変更があります。 クリックすると保存します。
help_texts:
- show_modal: ヘルプテキストを表示
+ show_modal: ヘルプテキストを表示する
onboarding:
buttons:
skip: スキップ
@@ -510,17 +510,11 @@ ja:
got_it: 了承
steps:
help_menu: ヘルプ(?)メニューは、その他のヘルプリソースを提供します。ここでは、ユーザーガイド、役立つハウツービデオなどを見つけることができます。 OpenProjectでの作業をお楽しみください!
- members: 新しい メンバー をプロジェクトに招待します。
+ members: 新しいメンバーをプロジェクトに招待する。
quick_add_button: ヘッダーナビゲーションにあるプラス(+)アイコンをクリックして、新規プロジェクトを作成したり、同僚を招待したりできます。
sidebar_arrow: プロジェクトのメインメニューに戻るには、左上の矢印を使います。
welcome: 3分間のイントロダクションツアーで、最も重要な機能を学びましょう。 最後までステップを完了することをお勧めします。ツアーはいつでも再開できます。
wiki: "Wiki内では、チームと一緒に知識を文書化し、共有することができます。"
- backlogs:
- overview: "バックログビューで仕事を管理する。"
- sprints: 右側にはプロダクトバックログとバグバックログがあり、左側にはそれぞれのスプリントがあります。ここでエピック、ユーザーストーリー、バグを作成し、ドラッグ&ドロップで優先順位をつけ、スプリントに追加することができます。
- task_board_arrow: "タスクボードを表示するには、スプリントドロップダウンを開きます…"
- task_board_select: "...そして、 タスク ボード エントリを選択します。"
- task_board: タスクボードは、このスプリントの進捗を視覚化します。ユーザーストーリーの横にあるプラス(+)アイコンをクリックすると、新しいタスクや障害を追加できます。 ステータスはドラッグ&ドロップで更新できます。
boards:
overview: "ボードを選択してビューをシフトし、アジャイルボードビューを使ってプロジェクトを管理する。"
lists_kanban: ここでは、ボード内に複数のリスト(列)を作成することができます。この機能により、例えば、カンバンボードを作成することができます。
@@ -591,57 +585,14 @@ ja:
settings:
change_notification_settings: 通知設定を変更することで、重要なアップデートを見逃すことはありません。
title: 通知設定
- notify_me: 通知する
- reminders:
- no_notification: 通知なし
- timeframes:
- normal:
- PT0S: 同じ日
- P1D: 1 日前
- P3D: 3 日前
- P7D: 週間前
- overdue:
- P1D: 毎日
- P3D: 3日ごと
- P7D: 毎週
- reasons:
- mentioned:
- title: メンションされた
- description: メンションされたときに通知を受け取る
- assignee: 担当者
- responsible: 責任者
- shared: 共有
- watched: ウォッチャー
- work_package_commented: すべての新着コメント
- work_package_created: 新しいワークパッケージ
- work_package_processed: すべてのステータス変更
- work_package_prioritized: すべての優先度の変更
- work_package_scheduled: すべての日付の変更
- global:
- immediately:
- title: 参加
- description: 自分が関与しているワークパッケージのすべてのアクティビティに関する通知(アサイニー、アカウンタブル、ウォッチャー)。
- delayed:
- title: 不参加
- description: すべてのプロジェクトでのアクティビティの追加通知。
- date_alerts:
- title: 日付アラート
- description: あなたが関与している(アサイニー、アカウンタブル、ウォッチャー)オープンワークパッケージの重要な日付が近づくと自動通知。
- overdue: 期限を過ぎた場合
- project_specific:
- title: プロジェクト固有の通知設定
- description: これらのプロジェクト固有の設定は、上記のデフォルト設定を上書きする。
- add: プロジェクトの設定を追加する
- already_selected: このプロジェクトは既に選択されています
- remove: プロジェクトの設定を削除する
pagination:
no_other_page: このページだけです。
- pages_skipped: ページがスキップされました。
+ pages_skipped: ページスキップ。
page_navigation: ページネーション・ナビゲーション
per_page_navigation: ページ毎のアイテム選択
pages:
page_number: ページ %{number}
- show_per_page: ページあたり %{number} を表示
+ show_per_page: ページごとに %{number}
placeholders:
default: "-"
subject: ここにタイトルを入力します
@@ -651,45 +602,12 @@ ja:
project:
autocompleter:
label: プロジェクト名の入力補完
- click_to_switch_to_project: 'プロジェクト: %{projectname}'
+ click_to_switch_to_project: プロジェクト: %{projectname}
context: プロジェクトのコンテキスト
not_available: プロジェクトなし
required_outside_context: 'ワークパッケージを作成するプロジェクトを選択して、すべての属性を確認してください。 上記で有効になっているタイプのプロジェクトのみ選択できます。
'
- reminders:
- settings:
- daily:
- add_time: 時間を追加
- enable: 毎日のEメールリマインダーを有効にする
- explanation: このリマインダーは、未読の通知に対してのみ、指定した時間帯にのみ届きます。 %{no_time_zone}
- no_time_zone: アカウントにタイムゾーンを設定するまでは、時間はUTCで解釈されます。
- time_label: 時間 %{counter}:
- title: 未読の通知を毎日メールで通知する
- workdays:
- title: これらの日にリマインダーメールを受け取る
- immediate:
- title: 電子メールのリマインダーを送信
- mentioned: "@mentionするとすぐに"
- personal_reminder: 個人的なリマインダーを受け取ったら直ちに
- alerts:
- title: その他の項目(ワークパッケージではないもの)に対する電子メールアラート
- explanation: '本日の通知はワークパッケージに限定されています。これらのイベントが通知に含まれるようになるまで、Eメールアラートを受信し続けることを選択できます:
-
- '
- news_added: ニュースが追加されました。
- news_commented: ニュースへのコメント
- document_added: 追加された書類
- forum_messages: 新しいフォーラムメッセージ
- wiki_page_added: Wikiページが追加されました。
- wiki_page_updated: Wikiページが更新されました。
- membership_added: メンバーシップが追加されました
- membership_updated: メンバーシップ更新
- title: 電子メールによるリマインダー
- pause:
- label: 毎日のEメールリマインダーを一時停止する
- first_day: 初日
- last_day: 最終日
text_are_you_sure: よろしいですか?
text_are_you_sure_to_cancel: このページには未保存の変更があります。本当に破棄しますか?
breadcrumb: パンくず
@@ -1062,13 +980,6 @@ ja:
form_submit:
title: 続行の確認
text: この操作を実行してもよろしいですか?
- destroy_work_package:
- title: "%{label} の削除を確認"
- single_text: ワークパッケージを削除してもよろしいですか?
- bulk_text: "%{label}を削除してもよろしいですか?"
- has_children: ワークパッケージは %{childUnits} あります。
- confirm_deletion_children: 列挙されたワークパッケージのすべての子孫が再帰的に削除されることを承認します。
- deletes_children: すべての子ワークパッケージとその子孫も再帰的に削除されます。
destroy_time_entry:
title: タイムエントリの削除を確認
text: 次のタイムエントリを削除してもよろしいですか?
@@ -1176,7 +1087,7 @@ ja:
toggle_title: ベースライン
clear: クリア
apply: 適用
- header_description: 過去のいずれかの時点からこのリストに加えられた変更を強調する。
+ header_description: 過去の選択した時点からこのリストに加えられた変更をハイライト
show_changes_since: 以降の変更を表示する
help_description: ベースラインの基準タイムゾーン。
time_description: '現地時間: %{datetime}'
diff --git a/config/locales/crowdin/js-ka.yml b/config/locales/crowdin/js-ka.yml
index c0e2885ad6d..5d5a8338b65 100644
--- a/config/locales/crowdin/js-ka.yml
+++ b/config/locales/crowdin/js-ka.yml
@@ -515,12 +515,6 @@ ka:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ ka:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: შემატყობინე
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: იგივე დღე
- P1D: 1 დღით ადრე
- P3D: 3 დღით ადრე
- P7D: 1 კვირით ადრე
- overdue:
- P1D: ყოველდღე
- P3D: ყოველ 3 დღეში
- P7D: ყოველკვირა
- reasons:
- mentioned:
- title: მოხსენიებულები
- description: Receive a notification every time someone mentions me anywhere
- assignee: დამსაქმებელი
- responsible: ანგარიშვალდებული
- shared: გაზიარებული
- watched: მეთვალყურე
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: მონაწილეობა
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: განგაშების თარიღი
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: როცა ვადა გადაცილდება
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ ka:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: დროის დამატება
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: სიახლე დამატებულია
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: პირველი დღე
- last_day: ბოლო დღე
text_are_you_sure: დარწმუნებული ბრძანდებით?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ ka:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-kk.yml b/config/locales/crowdin/js-kk.yml
index 67ca4f89984..35baaecdaa8 100644
--- a/config/locales/crowdin/js-kk.yml
+++ b/config/locales/crowdin/js-kk.yml
@@ -515,12 +515,6 @@ kk:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ kk:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ kk:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ kk:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-ko.yml b/config/locales/crowdin/js-ko.yml
index ed4186c89c7..f7c1dfe2074 100644
--- a/config/locales/crowdin/js-ko.yml
+++ b/config/locales/crowdin/js-ko.yml
@@ -515,12 +515,6 @@ ko:
sidebar_arrow: 프로젝트의 기본 메뉴로 돌아가려면 왼쪽 상단의 뒤로 화살표를 사용하세요.
welcome: 3분 소개 투어를 보고 가장 중요한 기능에 대해 알아보세요. 끝까지 단계를 완료하는 것이 좋습니다. 언제든지 투어를 다시 시작할 수 있습니다.
wiki: "Wiki에서 문서화하고 팀과 함께 지식을 공유할 수 있습니다."
- backlogs:
- overview: "백로그 보기에서 작업을 관리하세요."
- sprints: 오른쪽에 제품 백로그 및 버그 백로그가 있고, 왼쪽에 해당 스프린트가 있습니다. 여기에서 에픽, 사용자 이야기 및 버그를 작성하고 드래그 앤 드롭으로 우선 순위를 정하고 스프린트에 추가할 수 있습니다.
- task_board_arrow: "작업 보드를 보려면 스프린트 드롭다운을 여세요..."
- task_board_select: "...그리고 작업보드 항목을 선택하세요."
- task_board: 작업 보드는 이 스프린트의 진행률을 시각화합니다. 사용자 이야기 옆에 있는 더하기(+) 아이콘을 클릭하여 새 작업이나 제한을 추가하세요. 드래그 앤 드롭으로 상태를 업데이트할 수 있습니다.
boards:
overview: "보드를 선택하여 보기를 전환하고 애자일 보드 보기를 사용하여 프로젝트를 관리하세요."
lists_kanban: 여기에서 보드 내 여러 목록(열)을 만들 수 있습니다. 예를 들어, 이 기능을 사용하면 Kanban 보드를 만들 수 있습니다.
@@ -591,49 +585,6 @@ ko:
settings:
change_notification_settings: 중요 업데이트를 놓치지 않도록 알림 설정을 수정할 수 있습니다.
title: 알림 설정
- notify_me: 알림 받기
- reminders:
- no_notification: 알림 없음
- timeframes:
- normal:
- PT0S: 같은 날
- P1D: 1일 전
- P3D: 3일 전
- P7D: 1주 전
- overdue:
- P1D: 매일
- P3D: 3일마다
- P7D: 매주
- reasons:
- mentioned:
- title: 멘션됨
- description: 어디에서든 누군가가 나를 멘션할 때마다 알림 받기
- assignee: 담당자
- responsible: 책임자
- shared: 공유됨
- watched: 주시자
- work_package_commented: 모든 새로운 코멘트
- work_package_created: 새 작업 패키지
- work_package_processed: 모든 상태 변경 사항
- work_package_prioritized: 모든 우선 순위 변경 사항
- work_package_scheduled: 모든 날짜 변경 사항
- global:
- immediately:
- title: 참여
- description: 귀하가 참여하고 있는 작업 패키지의 모든 활동에 대한 알림(담당자, 책임자 또는 주시자).
- delayed:
- title: 참여하지 않음
- description: 모든 프로젝트의 활동에 대한 추가 알림.
- date_alerts:
- title: 날짜 경보
- description: 귀하가 참여하고 있는 오픈 작업 패키지에 대한 중요 날짜가 다가올 때 자동 알림(담당자, 책임자 또는 주시자).
- overdue: 기한이 지난 경우
- project_specific:
- title: 프로젝트별 알림 설정
- description: 이러한 프로젝트별 설정은 위의 기본 설정을 재정의합니다.
- add: 프로젝트에 대한 설정 추가
- already_selected: 이 프로젝트는 이미 선택되었습니다.
- remove: 프로젝트 설정 제거
pagination:
no_other_page: 유일한 페이지에 있습니다.
pages_skipped: 페이지를 건너뛰었습니다.
@@ -657,39 +608,6 @@ ko:
required_outside_context: '모든 특성을 보려면 작업 패키지를 만들 프로젝트를 선택하십시오. 위 유형이 활성화된 프로젝트만 선택할 수 있습니다.
'
- reminders:
- settings:
- daily:
- add_time: 시간 추가
- enable: 일일 이메일 미리 알림 사용
- explanation: 읽지 않은 알림에 대해서만 그리고 지정된 시간에만, 이러한 미리 알림이 전송됩니다. %{no_time_zone}
- no_time_zone: 계정의 시간대를 구성할 때까지 시간이 UTC로 표시됩니다.
- time_label: '시간 %{counter}:'
- title: 읽지 않은 알림에 대해 내게 일일 이메일 미리 알림 보내기
- workdays:
- title: 해당 요일에 이메일 미리 알림 받기
- immediate:
- title: 내게 이메일 미리 알림 보내기
- mentioned: 누군가 나를 @멘션할 때 즉시
- personal_reminder: 개인 미리 알림을 받는 즉시
- alerts:
- title: 기타 항목에 대한 이메일 알림(작업 패키지 외)
- explanation: '오늘 알림은 작업 패키지로 제한됩니다. 알림에 포함될 때까지 이러한 이벤트에 대한 이메일 알림을 계속 받도록 선택할 수 있습니다.
-
- '
- news_added: 뉴스 추가됨
- news_commented: 뉴스 항목의 코멘트
- document_added: 문서 추가됨
- forum_messages: 새 포럼 메시지
- wiki_page_added: 위키 페이지 추가됨
- wiki_page_updated: 위키 페이지 업데이트됨
- membership_added: 멤버십 추가됨
- membership_updated: 멤버십 업데이트됨
- title: 이메일 미리 알림
- pause:
- label: 임시로 일일 이메일 미리 알림 일시 중지
- first_day: 첫날
- last_day: 마지막 날
text_are_you_sure: 계속하시겠습니까?
text_are_you_sure_to_cancel: 이 페이지에 저장되지 않은 변경 사항이 있습니다. 변경 사항을 취소하시겠습니까?
breadcrumb: 이동 경로
@@ -1062,13 +980,6 @@ ko:
form_submit:
title: 계속하려면 확인하세요
text: 정말로 이 작업을 수행하기를 원하시나요?
- destroy_work_package:
- title: "%{label} 삭제 확인"
- single_text: 작업 패키지를 삭제하시겠습니까?
- bulk_text: 다음 %{label}을(를) 삭제하시겠습니까?
- has_children: 작업 패키지에 %{childUnits}이(가) 있습니다.
- confirm_deletion_children: 나는 작업 패키지의 모든 하위 목록이 재귀적으로 제거되는 것을 인정합니다.
- deletes_children: 모든 하위 작업 패키지 및 그 하위 항목도 재귀적으로 삭제됩니다.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-lt.yml b/config/locales/crowdin/js-lt.yml
index c154110b0b1..a2123dcb83a 100644
--- a/config/locales/crowdin/js-lt.yml
+++ b/config/locales/crowdin/js-lt.yml
@@ -515,12 +515,6 @@ lt:
sidebar_arrow: Pasinaudokite grįžimo rodykle viršutiniame kairiajame kampe grįžimui į projekto pagrindinį meniu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: "Wiki'yje galite dokumentuoti ir dalintis žiniomis su savo komandos nariais."
- backlogs:
- overview: Valdykite savo darbus Darbų sąrašo vaizde.
- sprints: Kairėje jūs matote produkto darbų sąrašą ir klaidų darbų sąrašą, dešinėje -- atitinkamus sprintus. Čia jūs galite kurti epics, user stories ir bugs, prioritetizuoti vilkdami į reikiamą vietą ir priskirti sprintui.
- task_board_arrow: Norėdami matyti jūsų užduočių lentą, atverkite sprinto iškrentantį meniu...
- task_board_select: "... ir pasirinkite task board elementą."
- task_board: Užduočių lenta vaizduoja sprinto progresą. Nuspauskite pliuso (+) ženklą prie user story norėdami pridėti naujas užduotis arba trukdžius. Būsena gali būti pakeista nuvelkant į reikiamą vietą.
boards:
overview: Pasirinkite lentas siekdami pakeisti vaizdą ir valdyti projektą naudodami agile lentų vaizdą.
lists_kanban: Lentoje galite sukurti keletą sąrašų (stulpelių) . Ši funkcija leidžia sukurti Kanban lentą.
@@ -594,49 +588,6 @@ lt:
settings:
change_notification_settings: Jūs galite keisti savo pranešimų nustatymus, kad užtikrintumėte, jog niekada nepraleisite svarbaus atnaujinimo.
title: Pranešimų nustatymai
- notify_me: Pranešti man
- reminders:
- no_notification: Jokio pranešimo
- timeframes:
- normal:
- PT0S: tą pačią dieną
- P1D: prieš 1 dieną
- P3D: prieš 3 dienas
- P7D: prieš savaitę
- overdue:
- P1D: kiekvieną dieną
- P3D: kas 3 dienas
- P7D: kiekvieną savaitę
- reasons:
- mentioned:
- title: Paminėtas
- description: Gauti pranešimą kiekvieną kartą, kai kas nors mane bet kur pamini
- assignee: Paskirtas
- responsible: Atsakingas
- shared: Bendrinta
- watched: Stebėtojas
- work_package_commented: Visi nauji komentarai
- work_package_created: Nauji darbų paketai
- work_package_processed: Visi būsenų pakeitimai
- work_package_prioritized: Visi prioritetų pakeitimai
- work_package_scheduled: Visi datų pakeitimai
- global:
- immediately:
- title: Dalyvaujate
- description: Pranešimai apie visus veiksmus darbo paketuose, su kuriais jūs susiję (priskirtasis, atsakingas ar stebėtojas).
- delayed:
- title: Nedalyvaujate
- description: Papildomi pranešimai apie veiksmus visuose projektuose.
- date_alerts:
- title: Datos įspėjimai
- description: Automatiniai pranešimai apie artėjančias svarbias atvirų darbo paketų, su kuriais jūs susiję (paskirtasis, atsakingas ar stebėtojas), datas.
- overdue: Kai pavėluota
- project_specific:
- title: Konkrečių projektų pranešimų nustatymai
- description: Šie konkrečių projektų nustatymai permuša aukščiau esančius numatytuosius nustatymus.
- add: Pridėti nustatymą projektui
- already_selected: Šis projektas jau pažymėtas
- remove: Išimti projekto nustatymus
pagination:
no_other_page: Jūs esate vieninteliame puslapyje.
pages_skipped: Pages skipped.
@@ -660,39 +611,6 @@ lt:
required_outside_context: 'Prašau pasirinkti projektą, kuriame turi būti sukurtas darbo paketas, kad matytumėte visus atributus. Jūs galite pasirinkti tik tuos projektus, kurie turi aukščiau nurodytą tipą.
'
- reminders:
- settings:
- daily:
- add_time: Pridėti laiką
- enable: Įjungti kasdienius el.pašto priminimus
- explanation: Jūs gausite šiuos priminimus tik neskaitytiems pranešimams ir tik jūsų nurodytomis valandomis. %{no_time_zone}
- no_time_zone: Iki jūs sukonfigūruosite jūsų paskyros laiko juostą, šie laikai bus interpretuojami kaip UTC.
- time_label: 'Laikas %{counter}:'
- title: Siųskite man kasdienius el.pašto priminimus apie neskaitytus pranešimus
- workdays:
- title: Gauti e-pašto priminimus šiomis dienomis
- immediate:
- title: Siųsti man e-pašto priminimą
- mentioned: Iš karto, kai kažkas @pamini mane
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: E-pašto pranešimai kitiems (ne darbo paketų) elementams
- explanation: 'Šiandien pranešimai galimi tik darbų paketams. Jūs galite pasirinkti gauti įspėjimus laiškais apie šiuos įvykius, kol jie dar įtraukiami į pranešimus:
-
- '
- news_added: Pridėta naujiena
- news_commented: Komentuoti naujienų elementą
- document_added: Dokumentai pridėti
- forum_messages: Nauji forumo pranešimai
- wiki_page_added: Wiki puslapis pridėtas
- wiki_page_updated: Wiki puslapis atnaujintas
- membership_added: Narystė pridėta
- membership_updated: Narystė atnaujinta
- title: El.pašto priminimai
- pause:
- label: Laikinai stabdyti kasdieninius e-pašto priminimus
- first_day: Pirma diena
- last_day: Paskutinė diena
text_are_you_sure: Ar esate įsitikinę?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Susijusi informacija
@@ -1065,13 +983,6 @@ lt:
form_submit:
title: Norėdami tęsti, patvirtinkite
text: Ar tikrai norite atlikti šį veiksmą?
- destroy_work_package:
- title: Patvirtinkite, jog %{label} ištrinamas
- single_text: Ar tikrai norite ištrinti darbo paketą
- bulk_text: Ar tikrai norite ištrinti %{label}?
- has_children: 'Darbų paketas turi %{childUnits}:'
- confirm_deletion_children: Aš sutinku, kad VISI šio darbų paketo palikuoniai bus rekursiškai ištrinti.
- deletes_children: Visi darbų paketo vaikai ir jų palikuoniai taip pat bus rekursiškai ištrinti.
destroy_time_entry:
title: Patvirtinkite laiko įrašo trynimą.
text: Ar Jūs tikrai norite ištrinti šį laiko įrašą?
diff --git a/config/locales/crowdin/js-lv.yml b/config/locales/crowdin/js-lv.yml
index b828313761b..1d0e6703022 100644
--- a/config/locales/crowdin/js-lv.yml
+++ b/config/locales/crowdin/js-lv.yml
@@ -515,12 +515,6 @@ lv:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -593,49 +587,6 @@ lv:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Pašreizējais atbildīgais
- responsible: Accountable
- shared: Shared
- watched: Sekotājs
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: Jūs esat vienīgajā lapā.
pages_skipped: Pages skipped.
@@ -659,39 +610,6 @@ lv:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Vai esat pārliecināts?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1064,13 +982,6 @@ lv:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-mn.yml b/config/locales/crowdin/js-mn.yml
index f4495277453..14ec7f4832a 100644
--- a/config/locales/crowdin/js-mn.yml
+++ b/config/locales/crowdin/js-mn.yml
@@ -515,12 +515,6 @@ mn:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ mn:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Даалгагч
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ mn:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ mn:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-ms.yml b/config/locales/crowdin/js-ms.yml
index 008af2c06be..6de174f5ed9 100644
--- a/config/locales/crowdin/js-ms.yml
+++ b/config/locales/crowdin/js-ms.yml
@@ -515,12 +515,6 @@ ms:
sidebar_arrow: Guna anak panah kembali di sudut kiri atas untuk kembali ke menu utama projek.
welcome: Ikuti lawatan pengenalan selama tiga minit untuk mempelajari ciri penting yang paling. Kami mengesyorkan anda melengkapkan langkah sehingga tamat. Anda boleh memulakan semula lawatan pada bila-bila masa.
wiki: Dalam wiki anda boleh mendokumentasikan dan kongsi pengetahuan bersama pasukan anda.
- backlogs:
- overview: Kendalikan kerja anda dalam paparan tunggakan.
- sprints: Di kanan anda mempunyai tunggakan produk dan tunggakan bug, di kiri anda mempunyai pecutan yang berkenaan. Di sini anda boleh mencipta epik, cerita pengguna, dan bug, utamakan dengan menarik & melepaskan dan tambah mereka ke pecutan.
- task_board_arrow: Untuk lihat papan tugasan anda, buka pecutan drop-down...
- task_board_select: "...dan pilih entri papan tugasan."
- task_board: Papan tugasan menggambarkan secara visual perkembangan untuk pecutan ini. Klik ikon tambah (+) di sebelah cerita pengguna untuk tambah tugasan baru atau halangan. Status tersebut boleh dikemas kini dengan tarik dan lepas.
boards:
overview: Pilih board untuk tukar paparan dan uruskan projek anda menggunakan paparan board agile.
lists_kanban: Disini anda boleh mencipta pelbagai senarai (kolum) dalam board anda. Fitur ini membenarkan anda untuk mencipta, sebagai contoh, board Kanban.
@@ -591,49 +585,6 @@ ms:
settings:
change_notification_settings: Anda boleh mengubah suai tetapan pemberitahuan anda untuk memastikan anda tidak terlepas tarikh yang penting.
title: Tetapan pemberitahuan
- notify_me: Maklumkan saya
- reminders:
- no_notification: Tiada pemberitahuan
- timeframes:
- normal:
- PT0S: hari yang sama
- P1D: 1 hari sebelum
- P3D: 3 hari sebelum
- P7D: 1 minggu sebelum
- overdue:
- P1D: setiap hari
- P3D: setiap 3 hari
- P7D: setiap minggu
- reasons:
- mentioned:
- title: Disebutkan
- description: Terima pemberitahuan setiap kali sesiapa menyebut saya di mana saja
- assignee: Penerima tugasan
- responsible: Bertanggungjawab
- shared: Dikongsi
- watched: Pemerhati
- work_package_commented: Semua komen baharu
- work_package_created: Pakej kerja baharu
- work_package_processed: Semua perubahan status
- work_package_prioritized: Semua perubahan utama
- work_package_scheduled: Semua perubahan tarikh
- global:
- immediately:
- title: Menyertai
- description: Pemberitahuan untuk semua aktiviti dalam pakej kerja yang anda terlibat (penerima tugasan, bertanggungjawab, atau pemerhati).
- delayed:
- title: Tidak menyertai
- description: Pemberitahuan tambahan untuk aktiviti dalam semua projek.
- date_alerts:
- title: Peringatan tarikh
- description: Pemberitahuan secara automatik apabila tarikh penting menghampiri untuk pakej kerja terbuka yang anda terlibat (penerima tugasan, bertanggungjawab atau pemerhati).
- overdue: Apabila tertunggak
- project_specific:
- title: Tetapan pemberitahuan khusus projek
- description: Tetapan pemberitahuan khusus projek mengatasi tetapan default diatas.
- add: Tambah tetapan untuk projek
- already_selected: Projek ini telah dipilih
- remove: Keluarkan tetapan projek
pagination:
no_other_page: Anda berada di satu-satunya halaman.
pages_skipped: Pages skipped.
@@ -657,39 +608,6 @@ ms:
required_outside_context: 'Sila pilih projek untuk mencipta pakej kerja untuk melihat semua atribut. Anda hanya boleh memilih projek yang mempunyai jenis di atas yang telah diaktifkan.
'
- reminders:
- settings:
- daily:
- add_time: Tambah masa
- enable: Benarkan peringatan e-mel harian
- explanation: Anda akan menerima peringatan hanya untuk pemberitahuan yang belum dibaca dan hanya pada jam yang anda tentukan. %{no_time_zone}
- no_time_zone: Sehingga anda konfigurasi zon masa untuk akaun anda, masa akan ditafsirkan dalam UTC.
- time_label: 'Masa %{counter}:'
- title: Hantar saya peringatan e-mel harian untuk pemberitahuan yang belum dibaca
- workdays:
- title: Terima peringatan e-mel pada hari-hari ini
- immediate:
- title: Hantar saya peringatan e-mel
- mentioned: Serta merta apabila sesiapa @menyebut saya
- personal_reminder: Serta-merta apabila saya menerima peringatan peribadi
- alerts:
- title: Peringatan e-mel untuk item lain (yang bukan pakej kerja)
- explanation: 'Pemberitahuan hari ini adalah terhad untuk pakej kerja. Anda boleh memilih untuk terus menerima makluman e-mel untuk kejadian ini sehingga mereka disertakan dalam pemberitahuan:
-
- '
- news_added: Berita yang ditambah
- news_commented: Komen pada item berita
- document_added: Dokumen ditambah
- forum_messages: Mesej forum baharu
- wiki_page_added: Halaman wiki ditambah
- wiki_page_updated: Halaman wiki dikemas kini
- membership_added: Keahlian ditambah
- membership_updated: Keahlian dikemas kini
- title: Peringatan e-mel
- pause:
- label: Hentikan seketika peringatan e-mel harian
- first_day: Hari pertama
- last_day: Hari terakhir
text_are_you_sure: Adakah anda pasti?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1062,13 +980,6 @@ ms:
form_submit:
title: Sahkan untuk teruskan
text: Adakah anda pasti anda ingin melaksanakan tindakan ini?
- destroy_work_package:
- title: Sahkan pemadaman %{label}
- single_text: Adakah anda pasti anda ingin memadam pakej kerja
- bulk_text: Adakah anda pasti anda ingin memadam %{label} yang berikut?
- has_children: 'Pakej kerja mempunyai %{childUnits}:'
- confirm_deletion_children: Saya mengesahkan semua keturunan pakej kerja yang tersenarai akan dikeluarkan secara berulang-ulang.
- deletes_children: Semua pakej kerja anak dan keturunan mereka akan dipadamkan secara berulang-ulang.
destroy_time_entry:
title: Sahkan pemadaman entri masa
text: Adakah anda pasti anda ingin memadam entri masa yang berikut?
diff --git a/config/locales/crowdin/js-ne.yml b/config/locales/crowdin/js-ne.yml
index b8671dac6fb..2cccded24bc 100644
--- a/config/locales/crowdin/js-ne.yml
+++ b/config/locales/crowdin/js-ne.yml
@@ -515,12 +515,6 @@ ne:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ ne:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ ne:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ ne:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-nl.yml b/config/locales/crowdin/js-nl.yml
index d5660e9b5b3..ec460500b61 100644
--- a/config/locales/crowdin/js-nl.yml
+++ b/config/locales/crowdin/js-nl.yml
@@ -515,12 +515,6 @@ nl:
sidebar_arrow: Gebruik de terug pijl in de linkerbovenhoek om terug te keren naar het project hoofdmenu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Binnen de wiki kunt u kennis delen en documenteren met uw team.
- backlogs:
- overview: Beheer uw werk in de backlogs weergave.
- sprints: Aan de rechterkant hebt u de product backlog en de bug backlog, aan de linkerkant de respectievelijke sprints. Hier kunt u epics, user stories en bugs maken, prioriteren door ze te slepen en ze toevoegen aan een sprint.
- task_board_arrow: Om uw taakbordte zien, opent u de sprint drop-down...
- task_board_select: "...en selecteer het taakbord item."
- task_board: Het taakbord geeft de vooruitgang voor deze sprint weer. Klik op het plus (+) pictogram naast een verhaal om nieuwe taken of belemmeringen toe te voegen. De status kan worden bijgewerkt door slepen en neerzetten.
boards:
overview: Selecteer borden om het overzicht te verschuiven en uw project te beheren met behulp van de agile borden weergave.
lists_kanban: Hier kunt u meerdere lijsten (kolommen) binnen uw bord maken. Met deze functie kunt u bijvoorbeeld een Kanban boardmaken.
@@ -592,49 +586,6 @@ nl:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Instellingen voor meldingen
- notify_me: Waarschuw mij
- reminders:
- no_notification: Geen melding
- timeframes:
- normal:
- PT0S: dezelfde dag
- P1D: 1 dag ervoor
- P3D: 3 dagen ervoor
- P7D: een week ervoor
- overdue:
- P1D: elke dag
- P3D: elke 3 dagen
- P7D: elke week
- reasons:
- mentioned:
- title: Genoemd
- description: Ontvang een melding elke keer dat iemand mij ergens noemt
- assignee: Toegewezene
- responsible: Verantwoording afleggen
- shared: Gedeeld
- watched: Kijker
- work_package_commented: Alle nieuwe reacties
- work_package_created: Nieuwe werkpakketten
- work_package_processed: Alle statuswijzigingen
- work_package_prioritized: Alle prioriteitswijzigingen
- work_package_scheduled: 'Alle datum wijzigingen '
- global:
- immediately:
- title: Deelnemend
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Niet-deelnemend
- description: Extra meldingen voor activiteiten in alle projecten.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: Wanneer achterstallig
- project_specific:
- title: Project-specifieke meldingsinstellingen
- description: These project-specific settings override default settings above.
- add: Instelling voor project toevoegen
- already_selected: Dit project is al geselecteerd
- remove: Projectinstellingen verwijderen
pagination:
no_other_page: U bent op de enige pagina.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ nl:
required_outside_context: 'Kies een project om het werkpakket in te creëren om alle attributen te zien. U kunt alleen projecten selecteren waarvan het type hierboven is geactiveerd.
'
- reminders:
- settings:
- daily:
- add_time: Tijd toevoegen
- enable: Dagelijkse e-mailherinneringen inschakelen
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Tijd %{counter}:'
- title: Stuur me dagelijkse herinneringen voor ongelezen meldingen
- workdays:
- title: Ontvang herinneringen per e-mail op deze dagen
- immediate:
- title: Stuur me een e-mail herinnering
- mentioned: Onmiddellijk wanneer iemand @vermeldt
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: E-mail meldingen voor andere items (die geen werkpakketten zijn)
- explanation: 'Meldingen vandaag zijn beperkt tot werkpakketten. U kunt ervoor kiezen om e-mailmeldingen voor deze gebeurtenissen te blijven ontvangen totdat ze zijn opgenomen in meldingen:
-
- '
- news_added: Nieuws toegevoegd
- news_commented: Reageer op een nieuwsitem
- document_added: Documenten toegevoegd
- forum_messages: Nieuwe forumberichten
- wiki_page_added: Wiki-pagina toegevoegd
- wiki_page_updated: Wiki-pagina bijgewerkt
- membership_added: Lidmaatschap toegevoegd
- membership_updated: Lidmaatschap bijgewerkt
- title: E-mail herinneringen
- pause:
- label: Temporarily pause daily email reminders
- first_day: Eerste dag
- last_day: Laatste dag
text_are_you_sure: Weet u het zeker?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ nl:
form_submit:
title: Bevestigen om verder te gaan
text: Weet u zeker dat u deze actie wilt uitvoeren?
- destroy_work_package:
- title: Bevestig verwijdering van %{label}
- single_text: Weet u zeker dat u het werkpakket wilt verwijderen
- bulk_text: Weet u zeker dat u de volgende %{label} wilt verwijderen?
- has_children: 'Het werkpakket heeft %{childUnits}:'
- confirm_deletion_children: Ik erken dat alle onderliggende werkpakketten van de weergegeven werkpakketten verwijderd worden.
- deletes_children: Alle onderliggende werkpakketten en hun nakomelingen ook worden verwijderd.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-no.yml b/config/locales/crowdin/js-no.yml
index ac48d95ba53..5595dae373e 100644
--- a/config/locales/crowdin/js-no.yml
+++ b/config/locales/crowdin/js-no.yml
@@ -109,7 +109,7 @@
button_save: Lagre
button_settings: Innstillinger
button_uncheck_all: Avmerk alle
- button_update: Oppdater
+ button_update: Oppdatèr
button_export-atom: Last ned Atom
button_generate_pdf: Generate PDF
button_create: Opprett
@@ -515,12 +515,6 @@
sidebar_arrow: Bruk returpilen i øvre venstre hjørne for å gå tilbake til prosjektets hovedmeny.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: I wiki kan du dokumentere og dele kunnskap sammen med teamet.
- backlogs:
- overview: Administrer arbeidet ditt i - backlogs -visningen.
- sprints: Til høyre har du produktet etterslep og feilloggen, til venstre har du de respektive stegene. Her kan du lage epics, brukerhistorier og bugs, prioriterer du via dra og slipp og legge dem til et steg.
- task_board_arrow: For å se oppgavetavle, åpne steg fra nedtrekksmenyen...
- task_board_select: "...og velg oppgavetavlens oppføring."
- task_board: Oppgavetavlen visualiserer fremdriften for denne etappen. Klikk på plussikonet (+) ved siden av en brukerhistorie for å legge til nye oppgaver eller hindringer. Statusen kan oppdateres ved å dra og slipp.
boards:
overview: Velg tavler for å skift visningen og administrere prosjektet ved hjelp av den dynamiske tavlevisningen.
lists_kanban: Her kan du opprette flere lister (kolonner) i tavlen. Denne funksjonen lar deg for eksempel opprette en Kanban tavle.
@@ -592,49 +586,6 @@
settings:
change_notification_settings: Du kan endre varslingsinnstillinger for å sikre at du aldri går glipp av en viktig oppdatering.
title: Varslingsinnstillinger
- notify_me: Gi meg beskjed
- reminders:
- no_notification: Ingen varsling
- timeframes:
- normal:
- PT0S: samme dag
- P1D: 1 dag før
- P3D: 3 dager før
- P7D: en uke før
- overdue:
- P1D: hver dag
- P3D: hver 3. dag
- P7D: hver uke
- reasons:
- mentioned:
- title: Nevnt
- description: Motta en melding hver gang noen nevner meg hvor som helst
- assignee: Deltaker
- responsible: Ansvarlig
- shared: Delt
- watched: Overvåker
- work_package_commented: Alle nye kommentarer
- work_package_created: Nye arbeidspakker
- work_package_processed: Alle statusendringer
- work_package_prioritized: Alle endringer i prioritet
- work_package_scheduled: Alle dato endringer
- global:
- immediately:
- title: Deltar
- description: Varsler for alle aktiviteter i arbeidspakker du er involvert i (oppdragstaker, ansvarlig eller overvåker).
- delayed:
- title: Ikke-deltakende
- description: Melding om ytterligere aktiviteter i alle prosjekter.
- date_alerts:
- title: Dato varsler
- description: Automatiske varsler når viktige datoer nærmer seg for åpne arbeidspakker du er med i (oppdragstaker, ansvarlig eller overvåker).
- overdue: Når forfalt
- project_specific:
- title: Prosjekt-spesifikke varslingsinnstillinger
- description: Disse prosjektspesifikke innstillingene overstyrer standardinnstillingene ovenfor.
- add: Legg til innstilling for prosjekt
- already_selected: Dette prosjektet er allerede valgt
- remove: Fjern prosjektinnstillinger
pagination:
no_other_page: Du er på den eneste siden.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@
required_outside_context: 'Velg et prosjekt for å opprette arbeidspakken og se alle egenskaper. Du kan bare velge prosjekter som har typen ovenfor aktivert.
'
- reminders:
- settings:
- daily:
- add_time: Legg til tid
- enable: Aktiver daglige e-postpåminnelser
- explanation: Du får bare disse påminnelsene for uleste varslinger og bare på tider du angir. %{no_time_zone}
- no_time_zone: Fram til du konfigurerer en tidssone for kontoen din, vil tidene bli tolket til å være i UTC.
- time_label: 'Tid %{counter}:'
- title: Send meg daglige e-postpåminnelser for uleste varslinger
- workdays:
- title: Motta e-postpåminnelser for disse dagene
- immediate:
- title: Send meg en påminnelse
- mentioned: Umiddelbart hvis noen @nevner meg
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Epost varsler for andre produkter (som ikke er arbeidspakker)
- explanation: 'Varsler i dag er begrenset til arbeidspakker. Du kan velge å fortsette å motta e-postvarsler for disse hendelsene inntil de er inkludert i varsler:
-
- '
- news_added: Lagt til nyhet
- news_commented: Kommenter en nyhet
- document_added: Dokumenter lagt til
- forum_messages: Nye forummeldinger
- wiki_page_added: Wiki-side lagt til
- wiki_page_updated: Wiki-side oppdatert
- membership_added: Medlemskap lagt til
- membership_updated: Medlemskapet er oppdatert
- title: E-postpåminnelser
- pause:
- label: pause daglige e-postpåminnelser midlertidig
- first_day: 'Første dag '
- last_day: Siste dag
text_are_you_sure: Er du sikker?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Brødsmule
@@ -1063,13 +981,6 @@
form_submit:
title: Bekreft for å fortsette
text: Er du sikker på at du vil utføre denne handlingen?
- destroy_work_package:
- title: Bekreft sletting av %{label}
- single_text: Er du sikker på at du vil slette arbeidspakken
- bulk_text: Er du sikker på at du vil slette følgende %{label}?
- has_children: 'Arbeidspakken har %{childUnits}:'
- confirm_deletion_children: Jeg erkjenner at ALLE underordnede av listede arbeidspakker vil fjernes samtidig.
- deletes_children: Alle underordnede arbeidspakker og tilhørende vil også bli slettet samtidig.
destroy_time_entry:
title: Bekreft sletting av tidsregistrering
text: Er du sikker på at du vil slette følgende tidsregistrering?
diff --git a/config/locales/crowdin/js-pl.yml b/config/locales/crowdin/js-pl.yml
index a2ddce6bc77..c77d8f5a2f7 100644
--- a/config/locales/crowdin/js-pl.yml
+++ b/config/locales/crowdin/js-pl.yml
@@ -515,12 +515,6 @@ pl:
sidebar_arrow: Użyj strzałki powrotu w lewym górnym rogu, aby wrócić do menu głównego projektu.
welcome: "Poświęć trzy minuty na zapoznanie się z najważniejszymi funkcjami. \n Zalecamy wykonanie tych kroków do końca. Zwiedzanie można w każdej chwili zacząć od nowa."
wiki: W wiki możesz dokumentować wiedzę i dzielić się nią z zespołem.
- backlogs:
- overview: Zarządzaj swoją pracą w widoku backlogs.
- sprints: Po prawej stronie znajduje się backlog produktu i backlog usterek, a po lewej stronie znajdują się odpowiednie sprinty. Tutaj można tworzyć wydarzenia, wpisy użytkownika i usterki, nadawać priorytety metodą przeciągania i upuszczania oraz dodawać je do sprintu.
- task_board_arrow: Aby zobaczyć swój panel zadań, otwórz menu rozwijane sprint...
- task_board_select: "...i wybierz wpis panel zadań."
- task_board: Panel zadań przedstawia postęp tego sprintu. Dodaj nowe zadania lub przeszkody, klikając ikonę (+) obok wpisu użytkownika. Stan można zaktualizować metodą przeciągania i upuszczania.
boards:
overview: Wybierz tablice, aby zmienić widok i zarządzać projektem za pomocą widoku tablic.
lists_kanban: Tutaj możesz utworzyć wiele list (kolumn) w jednym widoku tablicy. Ta funkcja pozwala ci na przykład na utworzenie tablicy Kanban.
@@ -594,49 +588,6 @@ pl:
settings:
change_notification_settings: Możesz zmodyfikować ustawienia powiadomień, aby upewnić się, że nigdy nie przegapisz ważnej aktualizacji.
title: Ustawienia powiadomień
- notify_me: Powiadom mnie
- reminders:
- no_notification: Bez powiadomienia
- timeframes:
- normal:
- PT0S: tego samego dnia
- P1D: 1 dzień przed
- P3D: 3 dni przed
- P7D: 1 tydzień przed
- overdue:
- P1D: codziennie
- P3D: co 3 dni
- P7D: co tydzień
- reasons:
- mentioned:
- title: Wzmianka
- description: Otrzymuj powiadomienie za każdym razem, gdy pojawi się o tobie wzmianka gdziekolwiek
- assignee: Przypisany do
- responsible: Osoba odpowiedzialna
- shared: Udostępniono
- watched: Obserwator
- work_package_commented: Wszystkie nowe komentarze
- work_package_created: Nowe pakiety robocze
- work_package_processed: Wszystkie zmiany statusu
- work_package_prioritized: Wszystkie zmiany priorytetów
- work_package_scheduled: Wszystkie zmiany daty
- global:
- immediately:
- title: Uczestnictwo
- description: Powiadomienia dotyczące wszystkich działań w pakietach roboczych, do których Cię zaangażowano (jako osobę przypisaną, odpowiedzialną lub obserwator)
- delayed:
- title: Brak uczestnictwa
- description: Dodatkowe powiadomienia dotyczące działań we wszystkich projektach
- date_alerts:
- title: Alerty dotyczące dat
- description: 'Automatyczne powiadomienia, gdy zbliżają się ważne daty otwartych pakietów roboczych, do których Cię zaangażowano (jako osobę: przypisaną, odpowiedzialną lub obserwatora)'
- overdue: Po upływie terminu
- project_specific:
- title: Ustawienia powiadomień dla danego projektu
- description: Te ustawienia dla danego projektu zastępują powyższe ustawienia domyślne.
- add: Dodaj ustawienie dla projektu
- already_selected: Ten projekt jest już wybrany
- remove: Usuń ustawienia projektu
pagination:
no_other_page: Jesteś na jedynej stronie.
pages_skipped: Pominięte strony.
@@ -660,39 +611,6 @@ pl:
required_outside_context: 'Wybierz projekt, w którym chcesz utworzyć pakiet roboczy, aby zobaczyć wszystkie atrybuty. Możesz wybrać tylko projekty, które mają aktywowany powyższy typ.
'
- reminders:
- settings:
- daily:
- add_time: Dodaj czas
- enable: Włącz codzienne przypomnienia e-mail
- explanation: Otrzymasz te przypomnienia tylko dla nieprzeczytanych powiadomień i tylko w określonych przez Ciebie godzinach. %{no_time_zone}
- no_time_zone: Dopóki nie skonfigurujesz strefy czasowej dla swojego konta, czas będzie interpretowany jako UTC.
- time_label: 'Czas %{counter}:'
- title: Wyślij mi codzienne przypomnienia e-mail dla nieprzeczytanych powiadomień
- workdays:
- title: Otrzymuj przypomnienia e-mail w tych dniach
- immediate:
- title: Wyślij mi przypomnienie e-mail
- mentioned: Natychmiast, gdy pojawi się @wzmianka o mnie
- personal_reminder: Natychmiast po otrzymaniu osobistego przypomnienia
- alerts:
- title: Powiadomienia e-mail dla innych elementów (które nie są pakietami roboczymi)
- explanation: 'Dzisiaj powiadomienia są ograniczone do pakietów roboczych. Możesz nadal otrzymywać powiadomienia e-mail dla tych zdarzeń, dopóki nie zostaną one zawarte w powiadomieniach:
-
- '
- news_added: Wiadomość dodana
- news_commented: Komentarz do nowości
- document_added: Dodanie dokumentu
- forum_messages: Nowe wiadomości na forum
- wiki_page_added: Dodano stronę wiki
- wiki_page_updated: Zaktualizowano stronę wiki
- membership_added: Dodanie członkostwa
- membership_updated: Aktualizacja członkostwa
- title: Przypomnienia e-mail
- pause:
- label: Tymczasowo wstrzymuj codzienne przypomnienia e-mail
- first_day: Pierwszy dzień
- last_day: Ostatni dzień
text_are_you_sure: Jesteś pewny?
text_are_you_sure_to_cancel: Na tej stronie znajdują się niezapisane zmiany. Czy na pewno chcesz je odrzucić?
breadcrumb: Ścieżka
@@ -1065,13 +983,6 @@ pl:
form_submit:
title: Potwierdź, aby kontynuować
text: Czy na pewno chcesz wykonać tę akcję?
- destroy_work_package:
- title: Potwierdź usunięcie %{label}
- single_text: Czy na pewno chcesz usunąć pakiet roboczy
- bulk_text: Czy na pewno chcesz usunąć %{label}?
- has_children: 'Pakiet roboczy zawiera %{childUnits}:'
- confirm_deletion_children: Potwierdzam, że WSZYSTKIE elementy potomne pakietów roboczych z listy będą rekurencyjnie usuwane.
- deletes_children: Wszystkie pakiety podrzędne i ich elementy potomne również będą rekursywnie usuwane.
destroy_time_entry:
title: Potwierdź usunięcie wpisu
text: Na pewno chcesz skasować?
diff --git a/config/locales/crowdin/js-pt-BR.yml b/config/locales/crowdin/js-pt-BR.yml
index b0659471aa9..a2a87370503 100644
--- a/config/locales/crowdin/js-pt-BR.yml
+++ b/config/locales/crowdin/js-pt-BR.yml
@@ -515,12 +515,6 @@ pt-BR:
sidebar_arrow: Use a seta de retorno no canto superior esquerdo para retornar ao menu principal do projeto.
welcome: Faça um tour de introdução de três minutos para conhecer os principais recursos. Recomendamos que você siga todas as etapas até o final. O tour pode ser reiniciado a qualquer momento.
wiki: 'Na wiki, você pode documentar e compartilhar conhecimento junto com sua equipe. '
- backlogs:
- overview: Gerencie seu trabalho na visão de backlogs.
- sprints: À direita, você tem o backlog de produto e o backlog de erro, à esquerda, você tem as respectivas sprints. Aqui você pode criar épicos, user stories e erros, priorizar via arrastar e soltar e adicioná-los a uma sprint.
- task_board_arrow: Para ver o seu quadro de tarefas, abra o menu suspenso da sprint...
- task_board_select: "... e selecione a entrada do quadro de tarefas. "
- task_board: O quadro de tarefas visualiza o progresso desta sprint. Clique no ícone de mais (+) ao lado de uma user story para adicionar novas tarefas ou impedimentos. O status pode ser atualizado por arrastar e soltar.
boards:
overview: Selecione quadros para mudar a visão e gerenciar seu projeto usando a exibição de quadros ágeis.
lists_kanban: Aqui você pode criar várias listas (colunas) dentro do seu painel. Este recurso permite que você crie um Quadro Kanban, por exemplo.
@@ -592,49 +586,6 @@ pt-BR:
settings:
change_notification_settings: Você pode modificar suas configurações de notificação para se certificar de nunca perder nenhuma atualização importante.
title: Configurações de notificação
- notify_me: Notifique-me
- reminders:
- no_notification: Sem notificação
- timeframes:
- normal:
- PT0S: mesmo dia
- P1D: 1 dia antes
- P3D: 3 dias antes
- P7D: uma semana antes
- overdue:
- P1D: todo dia
- P3D: a cada 3 dias
- P7D: Toda semana
- reasons:
- mentioned:
- title: Mencionado
- description: Receber uma notificação sempre que alguém me mencionar
- assignee: Cessionário
- responsible: Responsável
- shared: Compartilhado
- watched: Observador
- work_package_commented: Todos os novos comentários
- work_package_created: Novos pacotes de trabalho
- work_package_processed: Todas as mudanças de situação
- work_package_prioritized: Todas as mudanças de prioridade
- work_package_scheduled: Todas as alterações de data
- global:
- immediately:
- title: Participando
- description: Notificações para todas as atividades nos pacotes de trabalho que você está envolvido (cessionário, responsável ou observador).
- delayed:
- title: Não participando
- description: Notificações adicionais para atividades em todos os projetos
- date_alerts:
- title: Alertas de data
- description: Notificações automáticas quando datas importantes estiverem se aproximando para pacotes de trabalho abertos que você esteja envolvido (cessionário, responsável ou observador).
- overdue: Quando vencido
- project_specific:
- title: Configurações de notificação específicas de projetos
- description: Essas configurações específicas de projeto substituem as configurações padrão acima
- add: Adicionar configuração para o projeto
- already_selected: Este projeto já está selecionado
- remove: Remover configurações de projeto
pagination:
no_other_page: Você está na página única.
pages_skipped: Páginas puladas.
@@ -658,39 +609,6 @@ pt-BR:
required_outside_context: 'Por favor, escolha o projeto onde vai criar o pacote de trabalho para visualizar todos os atributos. Você pode selecionar somente projetos que possuam o tipo acima ativado.
'
- reminders:
- settings:
- daily:
- add_time: Adicionar tempo
- enable: 'Ativar lembretes diários por e-mail '
- explanation: Você receberá estes lembretes somente para as notificações não lidas e apenas nas horas especificadas por você. %{no_time_zone}
- no_time_zone: Até que um fuso horário seja configurado em sua conta, os horários serão interpretados como UTC.
- time_label: 'Tempo %{counter}:'
- title: Envie-me lembretes diários por e-mail para as notificações não lidas
- workdays:
- title: Receber lembretes por e-mail nestes dias
- immediate:
- title: Envie-me um lembrete por e-mail
- mentioned: Imediatamente quando alguém me @mencionar
- personal_reminder: Imediatamente quando eu receber um lembrete pessoal
- alerts:
- title: Alertas por e-mail para outros itens (qua não sejam pacotes de trabalho)
- explanation: 'As notificações hoje estão limitadas a pacotes de trabalho. Você pode optar por continuar a receber alertas por e-mail para estes eventos até que eles sejam incluídos nas notificações:
-
- '
- news_added: Notícia adicionada
- news_commented: Comentar em um item de notícia
- document_added: Documentos adicionados
- forum_messages: Novas mensagens de fórum
- wiki_page_added: Página wiki adicionada
- wiki_page_updated: Página wiki atualizada
- membership_added: Associação adicionada
- membership_updated: Associação atualizada
- title: Lembretes por e-mail
- pause:
- label: 'Pausar temporariamente lembretes por e-mail diários '
- first_day: Primeiro dia
- last_day: Último dia
text_are_you_sure: Você tem certeza?
text_are_you_sure_to_cancel: Você tem alterações não salvas nesta página. Tem certeza de que deseja descartá-las?
breadcrumb: Trilha de navegação
@@ -1063,13 +981,6 @@ pt-BR:
form_submit:
title: Confirme para continuar
text: Tem certeza de que deseja executar esta ação?
- destroy_work_package:
- title: Confirmar exclusão do %{label}
- single_text: Tem certeza de que deseja excluir o pacote de trabalho?
- bulk_text: Você tem certeza de que deseja excluir o seguinte %{label}?
- has_children: 'O pacote de trabalho tem %{childUnits}:'
- confirm_deletion_children: Tenho conhecimento que TODOS os descendentes dos pacotes de trabalho listados serão removidos recursivamente.
- deletes_children: Todos os pacotes de trabalho filhos e seus descendentes também serão excluídos recursivamente.
destroy_time_entry:
title: Confirmar exclusão da entrada de tempo
text: Você tem certeza que deseja excluir a seguinte entrada de tempo?
diff --git a/config/locales/crowdin/js-pt-PT.yml b/config/locales/crowdin/js-pt-PT.yml
index 889f67bd505..1703ba94717 100644
--- a/config/locales/crowdin/js-pt-PT.yml
+++ b/config/locales/crowdin/js-pt-PT.yml
@@ -515,12 +515,6 @@ pt-PT:
sidebar_arrow: Use a seta de retorno no canto superior esquerdo para voltar ao menu principal do projeto.
welcome: Faça uma visita guiada de 3 minutos para conhecer as funcionalidades mais importantes. Recomendamos que conclua as etapas até ao final. Pode reiniciar a visita a qualquer momento.
wiki: Na wiki pode documentar e partilhar conhecimento com a sua equipa.
- backlogs:
- overview: Faça a gestão do seu trabalho na vista de backlogs.
- sprints: À direita tem o backlog do produto e o backlog do bug, à esquerda tem os sprints respectivos. Aqui pode criar épicos, histórias de utilizadores e bugs, definir a prioridade arrastando e soltando, e adicioná-los a um sprint.
- task_board_arrow: Para ver o seu quadro de tarefas, abra o menu suspenso de sprint...
- task_board_select: "...e selecione a entrada quadro de tarefas."
- task_board: O painel de tarefas visualiza o progresso deste sprint. Clique no ícone mais (+) ao lado de um histórico de utilizador para adicionar novas tarefas ou impedimentos. O estado pode ser atualizado ao arrastar e soltar.
boards:
overview: Selecione quadros para mudar a vista e gerir o seu projeto através da vista de painéis ágeis.
lists_kanban: Aqui pode criar múltiplas listas (colunas) dentro do seu quadro. Este recurso permite que crie um Painel Kanban, por exemplo.
@@ -592,49 +586,6 @@ pt-PT:
settings:
change_notification_settings: Pode modificar as suas definições de notificações para garantir que nunca perde uma atualização importante.
title: Definições das notificações
- notify_me: Notificar-me
- reminders:
- no_notification: Sem notificações
- timeframes:
- normal:
- PT0S: no mesmo dia
- P1D: 1 dia antes
- P3D: 3 dias antes
- P7D: uma semana antes
- overdue:
- P1D: todos os dias
- P3D: a cada 3 dias
- P7D: todas as semanas
- reasons:
- mentioned:
- title: Mencionou
- description: Receber uma notificação sempre que alguém me mencionar em qualquer lugar
- assignee: Responsável
- responsible: Responsável
- shared: Partilhado
- watched: Observador
- work_package_commented: Todos os novos comentários
- work_package_created: Novos pacotes de trabalho
- work_package_processed: Todas as mudanças de estado
- work_package_prioritized: Todas as mudanças de prioridade
- work_package_scheduled: Todas as alterações de data
- global:
- immediately:
- title: Participante
- description: Notificações para todas as atividades nos pacotes de trabalho em que está envolvido (responsável ou observador).
- delayed:
- title: Não participante
- description: Notificações adicionais para atividades em todos os projetos.
- date_alerts:
- title: Alertas de data
- description: Notificações automáticas ao aproximarem-se datas importantes para pacotes de trabalho abertos em que esteja envolvido (responsável ou observador).
- overdue: Quando vencido
- project_specific:
- title: Configurações de notificação específicas do projeto
- description: Estas configurações específicas do projeto substituem as configurações padrão acima.
- add: Adicionar configuração ao projeto
- already_selected: Este projeto já está selecionado
- remove: Remover definições do projeto
pagination:
no_other_page: Mais nenhuma página a apresentar.
pages_skipped: Páginas saltadas.
@@ -658,39 +609,6 @@ pt-PT:
required_outside_context: 'Por favor escolha um projeto onde criar o pacote de trabalho de forma a ver todos os atributos. Só pode selecionar projetos com o tipo acima ativado.
'
- reminders:
- settings:
- daily:
- add_time: Adicionar hora
- enable: Ativar lembretes diários por e-mail
- explanation: Vai receber estes lembretes apenas para notificações não lidas e apenas às horas que especificar. %{no_time_zone}
- no_time_zone: Até que configure um fuso horário para a sua conta, os horários serão interpretados como estando em UTC.
- time_label: 'Hora %{counter}:'
- title: Envie-me lembretes diários de e-mail para notificações não lidas
- workdays:
- title: Receba lembretes por e-mail nestes dias
- immediate:
- title: Enviar-me um lembrete por e-mail
- mentioned: Imediatamente quando alguém me @mencionar
- personal_reminder: Imediatamente quando recebo um lembrete pessoal
- alerts:
- title: Alertas de e-mail para outros itens (que não são pacotes de trabalho)
- explanation: 'As notificações hoje estão limitadas a pacotes de trabalho. Pode optar por continuar a receber alertas de e-mail para estes eventos até que eles sejam incluídos nas notificações:
-
- '
- news_added: Notícia adicionada
- news_commented: Comentar numa notícia
- document_added: Documentos adicionados
- forum_messages: Novas mensagens do fórum
- wiki_page_added: Página wiki adicionada
- wiki_page_updated: Página wiki atualizada
- membership_added: Adesão adicionada
- membership_updated: Adesão atualizada
- title: Lembretes por e-mail
- pause:
- label: Pausar temporariamente lembretes de e-mail diários
- first_day: Primeiro dia
- last_day: Último dia
text_are_you_sure: Tem a certeza?
text_are_you_sure_to_cancel: Tem alterações não guardadas nesta página. Tem a certeza de que as quer eliminar?
breadcrumb: Estrutural
@@ -1063,13 +981,6 @@ pt-PT:
form_submit:
title: Confirmar para continuar
text: Tem a certeza que pretende realizar esta ação?
- destroy_work_package:
- title: Confirmar exclusão do %{label}
- single_text: Tem a certeza de que deseja eliminar o pacote de trabalho?
- bulk_text: Tem a certeza de que deseja apagar a seguinte %{label}?
- has_children: 'O pacote de trabalho tem %{childUnits}:'
- confirm_deletion_children: Reconheço que todos os descendentes dos pacotes de trabalho listados serão recursivamente removidos.
- deletes_children: Todos os pacotes de trabalho filhos e seus descendentes serão também recursivamente apagados.
destroy_time_entry:
title: Confirmar a eliminação da entrada de tempo
text: Pretende remover a seguinte entrada de tempo?
diff --git a/config/locales/crowdin/js-ro.yml b/config/locales/crowdin/js-ro.yml
index 13eb514d9b7..05b6cff6b0c 100644
--- a/config/locales/crowdin/js-ro.yml
+++ b/config/locales/crowdin/js-ro.yml
@@ -109,7 +109,7 @@ ro:
button_save: Salvează
button_settings: Setări
button_uncheck_all: Deselectează tot
- button_update: Actualizează
+ button_update: Actualizare
button_export-atom: Descarcă Atom
button_generate_pdf: Generează PDF
button_create: Creează
@@ -515,12 +515,6 @@ ro:
sidebar_arrow: Folosește săgeata de întoarcere din colțul din stânga sus pentru a te întoarce în meniul al proiectului.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: În cadrul Wiki puteți documenta și împărtăși cunoștințe împreună cu echipa dumneavoastră.
- backlogs:
- overview: Gestionează-ți munca în vizualizarea backlogs.
- sprints: În dreapta aveți lista de rezultate și erorile restante, în stânga aveți sprintele respective. Aici poți crea epicuri, povestiri pentru utilizatori și erori, prioritizează prin drag & drop și adaugă-le la un sprint.
- task_board_arrow: Pentru a vedea panoul de sarcini, deschideți meniul Sprint...
- task_board_select: "... și selectați intrarea Task board."
- task_board: Grupul de lucru vizualizează progresul pentru această iterație. Dă click pe pictograma plus (+) de lângă o cerință de utilizator pentru a adăuga sarcini noi sau impedimente. Starea poate fi actualizată cu glisare și plasare.
boards:
overview: Selectează secțiunile pentru a schimba vizualizarea și administrarea proiectului tău folosind vizualizarea secțiunilor agile.
lists_kanban: Aici puteţi crea mai multe liste (coloane) în cadrul secţiunii. Această funcţie vă permite să creaţi o tabelă Kanban, de exemplu.
@@ -593,49 +587,6 @@ ro:
settings:
change_notification_settings: Poți modifica setările de notificare pentru a te asigura că nu pierzi niciodată o actualizare importantă.
title: Setări notificare
- notify_me: Notifică-mă
- reminders:
- no_notification: Nicio notificare
- timeframes:
- normal:
- PT0S: în aceeași zi
- P1D: cu 1 zi înainte
- P3D: cu 3 zile înainte
- P7D: " cu o săptămână înainte "
- overdue:
- P1D: zilnic
- P3D: la fiecare 3 zile
- P7D: săptămânal
- reasons:
- mentioned:
- title: Menţionat
- description: Primesc o notificare de fiecare dată când cineva mă menționează oriunde
- assignee: Executant
- responsible: Responsabil
- shared: Partajat
- watched: Observator
- work_package_commented: Toate comentariile noi
- work_package_created: Pachete de lucru noi
- work_package_processed: Toate modificările de stare
- work_package_prioritized: Toate modificările de prioritate
- work_package_scheduled: Toate modificările dății
- global:
- immediately:
- title: Participant
- description: Notificări pentru toate activitățile din pachetele de lucru în care ești implicat (desemnat, responsabil sau observator).
- delayed:
- title: Unde nu participi
- description: Notificări suplimentare pentru activitățile din toate proiectele.
- date_alerts:
- title: Alerte dăți
- description: Notificări automate atunci când se apropie dăți importante pentru pachetele de lucru deschise în care ești implicat (desemnat, responsabil sau observator).
- overdue: În caz de întârziere
- project_specific:
- title: Setări notificare specifice proiectului
- description: Aceste setări specifice proiectului prevalează asupra setărilor implicite de mai sus.
- add: Adaugă o setare pentru proiect
- already_selected: Acest proiect este deja selectat
- remove: Elimină setările proiectului
pagination:
no_other_page: Ești pe singura pagină.
pages_skipped: Pagini sărite.
@@ -659,39 +610,6 @@ ro:
required_outside_context: 'Te rog să alegi un proiect în care să creezi pachetul de lucru pentru a vedea toate atributele. Poți selecta numai proiectele care au tipul de mai sus activat.
'
- reminders:
- settings:
- daily:
- add_time: Adaugă timp
- enable: Activează reamintirile zilnice prin e-mail
- explanation: Vei primi aceste reamintiri numai pentru notificările necitite și numai la câteva ore specificate. %{no_time_zone}
- no_time_zone: Până când configurezi un fus orar pentru contul tău, orele vor fi interpretate ca fiind în UTC.
- time_label: 'Timp %{counter}:'
- title: Trimite-mi reamintiri zilnice prin e-mail pentru notificările necitite
- workdays:
- title: Primește reamintiri prin e-mail în aceste zile
- immediate:
- title: Trimite-mi un e-mail de reamintire
- mentioned: Imediat când cineva mă @menționează
- personal_reminder: Imediat când primesc reamintiri personale
- alerts:
- title: Alerte prin e-mail pentru alte elemente (care nu sunt pachete de lucru)
- explanation: 'Astăzi, notificările se limitează la pachetele de lucru. Puteți alege să continuați să primiți alerte prin e-mail pentru aceste evenimente până când acestea vor fi incluse în notificări:
-
- '
- news_added: Noutăți adăugate
- news_commented: Comentariu la o știre
- document_added: Documente adăugate
- forum_messages: Mesaje noi pe forum
- wiki_page_added: Pagină wiki adăugată
- wiki_page_updated: Pagină wiki actualizată
- membership_added: Adaugă membri
- membership_updated: Membrii actualizați
- title: Reamintiri e-mail
- pause:
- label: Întrerupe temporar reamintirile zilnice prin e-mail
- first_day: Prima zi
- last_day: Ultima zi
text_are_you_sure: Ești sigur?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1064,13 +982,6 @@ ro:
form_submit:
title: Confirmă pentru a continua
text: Ești sigur că vrei să realizezi această acțiune?
- destroy_work_package:
- title: Confirmă ștergerea %{label}
- single_text: Ești sigur că vrei să ștergi pachetul de lucru
- bulk_text: Ești sigur că vrei să ștergi următoarele %{label}?
- has_children: 'Pachetul de lucru conține %{childUnits}:'
- confirm_deletion_children: Recunosc că TOȚI descendenții pachetelor de lucru enumerate vor fi eliminați în mod recursiv.
- deletes_children: De asemenea, toate pachetele de lucru minore și descendenții acestora vor fi șterse în mod recursiv.
destroy_time_entry:
title: Confirmarea ștergerii înregistrării timpului
text: Ești sigur că vrei să ștergi următoarea înregistrare a timpului?
diff --git a/config/locales/crowdin/js-ru.yml b/config/locales/crowdin/js-ru.yml
index e0c88afba90..2420a7ae5af 100644
--- a/config/locales/crowdin/js-ru.yml
+++ b/config/locales/crowdin/js-ru.yml
@@ -109,7 +109,7 @@ ru:
button_save: Сохранить
button_settings: Настройки
button_uncheck_all: Снять все отметки
- button_update: Обновить
+ button_update: Обновление
button_export-atom: Скачать Atom
button_generate_pdf: Создать PDF
button_create: Создать
@@ -517,12 +517,6 @@ ru:
sidebar_arrow: Используйте стрелку возврата в левом верхнем углу, чтобы вернуться в главное меню проекта.
welcome: Совершите вводный трехминутный тур для знакомства с наиболее важными особенностями. Рекомендуем пройти все шаги до конца. Пройти вводный тур повторно можно в любое время.
wiki: В пределах wiki возможно документирование и обмен знаниями в вашей команде.
- backlogs:
- overview: Управляйте своей работой в представлении backlogs.
- sprints: Справа у вас есть бэклог продукта и бэклог ошибок, слева у вас есть соответствующие спринты. Здесь вы можете создать эпики, пользовательские истории и ошибки, приоритизировать через перетаскивание и добавить их в спринт.
- task_board_arrow: Чтобы увидеть вашу панель задач, откройте выпадающий спринт...
- task_board_select: "... и выберите строку Панель задач."
- task_board: Панель задач визуализирует прогресс для этого спринта. Нажмите на значок плюс (+) рядом с пользовательской историей, чтобы добавить новые задачи или препятствия. Статус можно обновить перетаскиванием.
boards:
overview: Выберите доски , чтобы сдвинуть вид и управлять вашим проектом с помощью вида agile-доски.
lists_kanban: Здесь вы можете создать несколько списков (столбцов) на доске. Эта функция позволяет создать доску Канбана, например.
@@ -596,49 +590,6 @@ ru:
settings:
change_notification_settings: Измените настройки уведомлений , чтобы не пропустить важное обновление.
title: Настройки уведомлений
- notify_me: Уведомлять меня
- reminders:
- no_notification: Нет уведомления
- timeframes:
- normal:
- PT0S: тот же день
- P1D: за 1 день до
- P3D: 3 дня до
- P7D: за неделю до
- overdue:
- P1D: каждый день
- P3D: каждые 3 дня
- P7D: каждую неделю
- reasons:
- mentioned:
- title: Упомянутый
- description: Получать уведомления каждый раз, когда кто-то упоминает меня в любом месте
- assignee: Назначенный
- responsible: Ответственный
- shared: Общий доступ
- watched: Наблюдатель
- work_package_commented: Все новые комментарии
- work_package_created: Новые пакеты работ
- work_package_processed: Все изменения статуса
- work_package_prioritized: Все приоритетные изменения
- work_package_scheduled: Все изменения даты
- global:
- immediately:
- title: Участие
- description: Уведомления обо всех действиях в пакетах работ, в которых вы участвуете (назначение, подотчетность или наблюдение).
- delayed:
- title: Неучастие
- description: Дополнительные уведомления для деятельности во всех проектах.
- date_alerts:
- title: Дата оповещения
- description: Автоматическое уведомление, когда приближаются важные даты открытия пакетов работ, в которых вы участвуете (исполнитель, ответственный или наблюдатель).
- overdue: Когда просрочено
- project_specific:
- title: Конкретные настройки уведомлений проекта
- description: Эти настройки специфического проекта переопределяют параметры по умолчанию выше.
- add: Добавить настройку для проекта
- already_selected: Этот проект уже выбран
- remove: Удалить настройки проекта
pagination:
no_other_page: Вы находитесь на единственной странице.
pages_skipped: Страницы пропущены.
@@ -662,39 +613,6 @@ ru:
required_outside_context: 'Пожалуйста, выберите проект для создания пакета работ для просмотра всех атрибутов. Вы можете выбрать только проекты, которые имеют вышеуказанный тип.
'
- reminders:
- settings:
- daily:
- add_time: Добавить время
- enable: Включить ежедневные напоминания по электронной почте
- explanation: Вы будете получать эти напоминания только для непрочитанных уведомлений и только в указанные вами часы. %{no_time_zone}
- no_time_zone: До уточнения часового пояса для вашего аккаунта время будет в UTC.
- time_label: 'Время %{counter}:'
- title: Посылать мне ежедневные напоминания по электронной почте для непрочитанных уведомлений
- workdays:
- title: Получать напоминания по электронной почте в эти дни
- immediate:
- title: Отправить мне напоминание по электронной почте
- mentioned: Сразу же когда кто-то @упоминает меня
- personal_reminder: Немедленно, когда я получаю персональное напоминание
- alerts:
- title: Уведомления по электронной почте для других элементов (которые не являются пакетами работ)
- explanation: 'Уведомления сегодня ограничены пакетами работ. Вы можете продолжать получать уведомления по электронной почте об этих событиях до тех пор, пока они не будут включены в уведомления:
-
- '
- news_added: Новость добавлена
- news_commented: Комментарий к новости
- document_added: Добавлены документы
- forum_messages: Новые сообщения форума
- wiki_page_added: Wiki страница добавлена
- wiki_page_updated: Wiki страница обновлена
- membership_added: Членство добавлено
- membership_updated: Членство обновлено
- title: Почтовые напоминания
- pause:
- label: Временно приостановить ежедневные напоминания по электронной почте
- first_day: Первый день
- last_day: Последний день
text_are_you_sure: Уверены?
text_are_you_sure_to_cancel: У Вас есть несохраненные изменения на этой странице. Вы уверены, что хотите их отменить?
breadcrumb: Навигационная цепочка
@@ -1067,13 +985,6 @@ ru:
form_submit:
title: Подтвердите продолжение
text: Вы действительно хотите выполнить это действие?
- destroy_work_package:
- title: Подтвердите удаление %{label}
- single_text: Вы уверены, что хотите удалить пакет работ
- bulk_text: Вы уверены, что хотите удалить следующие %{label}?
- has_children: 'Пакет работ имеет %{childUnits}:'
- confirm_deletion_children: Я понимаю, что ВСЕ производные элементы указанных пакетов работ будут рекурсивно удалены.
- deletes_children: Все дочерние пакеты работ и их потомки также будут рекурсивно удалены.
destroy_time_entry:
title: Подтвердите удаление записи времени
text: Вы уверены, что хотите удалить следующую запись?
diff --git a/config/locales/crowdin/js-rw.yml b/config/locales/crowdin/js-rw.yml
index fbb287eec30..f744ef2fc9f 100644
--- a/config/locales/crowdin/js-rw.yml
+++ b/config/locales/crowdin/js-rw.yml
@@ -515,12 +515,6 @@ rw:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ rw:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ rw:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ rw:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-si.yml b/config/locales/crowdin/js-si.yml
index cd0caa7c2b1..36836526eb9 100644
--- a/config/locales/crowdin/js-si.yml
+++ b/config/locales/crowdin/js-si.yml
@@ -515,12 +515,6 @@ si:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ si:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: අස්ගිනී
- responsible: වගවීම
- shared: Shared
- watched: මුරකරු
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: ඔබ සිටින්නේ එකම පිටුවේ ය.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ si:
required_outside_context: 'කරුණාකර සියලු ගුණාංග බැලීමට වැඩ පැකේජය නිර්මාණය කිරීම සඳහා ව්යාපෘතියක් තෝරන්න. ඔබට තෝරා ගත හැක්කේ ඉහත ආකාරයේ සක්රිය කර ඇති ව්යාපෘති පමණි.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: පුවත් එකතු
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: විකි පිටුව එකතු කරන ලදි
- wiki_page_updated: විකි පිටුව යාවත්කාලීන කරන ලදි
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: ඔබට විශ්වාසද?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ si:
form_submit:
title: දිගටම කරගෙන යාමට තහවුරු කරන්න
text: ඔබට මෙම ක්රියාව කිරීමට අවශ්ය බව ඔබට විශ්වාසද?
- destroy_work_package:
- title: "%{label}මකාදැමීම තහවුරු කරන්න"
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'වැඩ පැකේජයට %{childUnits}ඇත:'
- confirm_deletion_children: ලැයිස්තුගත වැඩ පැකේජ වලින් පැවත එන සියලුම දෙනා නැවත නැවතත් ඉවත් කරන බව මම පිළිගනිමි.
- deletes_children: සියලුම ළමා වැඩ පැකේජ සහ ඔවුන්ගෙන් පැවත එන්නන් ද නැවත නැවතත් මකා දැමෙනු ඇත.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-sk.yml b/config/locales/crowdin/js-sk.yml
index af58c4b132c..e2890e09f9b 100644
--- a/config/locales/crowdin/js-sk.yml
+++ b/config/locales/crowdin/js-sk.yml
@@ -515,12 +515,6 @@ sk:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -594,49 +588,6 @@ sk:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Priradené
- responsible: Zodpovedný
- shared: Shared
- watched: Pozorovateľ
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: Ste na jedinej stránke.
pages_skipped: Pages skipped.
@@ -660,39 +611,6 @@ sk:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Novinky pridané
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wikistránka bola pridaná
- wiki_page_updated: Wikistránka bola aktualizovaná
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Ste si istí?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1065,13 +983,6 @@ sk:
form_submit:
title: Potvrdiť a pokračovať
text: Ste si istý, že chcete vykonať túto akciu?
- destroy_work_package:
- title: Potvrďte zmazanie %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Pracovný balíček má %{childUnits}:'
- confirm_deletion_children: Potvrdzujem, že všetky podriadené prvky pracovných balíčkov, ktoré sú tu uvedené, budú odstránené rekurzívne.
- deletes_children: Všetky podradené pracovné balíčky a s nimi súvisiace budú rekurzívne odstránené.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-sl.yml b/config/locales/crowdin/js-sl.yml
index 6c243c3fdd7..0e95dc8ada6 100644
--- a/config/locales/crowdin/js-sl.yml
+++ b/config/locales/crowdin/js-sl.yml
@@ -517,12 +517,6 @@ sl:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -596,49 +590,6 @@ sl:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Nastavitve obvestil
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Omenjen
- description: Receive a notification every time someone mentions me anywhere
- assignee: Prevzemnik
- responsible: Odgovorni
- shared: Shared
- watched: Opazovalec
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: 'Ste na edini strani. '
pages_skipped: Pages skipped.
@@ -662,39 +613,6 @@ sl:
required_outside_context: 'Prosimo, izberite projekt, v katerem boste ustvarili delovni paket, če si želite ogledati vse atribute. Izberete lahko samo projekte, ki so aktivirani zgoraj.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: Dodane novice
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki stran dodana
- wiki_page_updated: Wiki stran posodobljena
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Ste prepričani?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1083,13 +1001,6 @@ sl:
form_submit:
title: Potrdite za nadaljevanje
text: Ali ste prepričani, da želite to izvesti?
- destroy_work_package:
- title: Potrdite izbris %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Ta delavni paket ima %{childUnits}:'
- confirm_deletion_children: Zavedam se, da bodo VSI potomci naštetih delovnih paketov rekurzivno odstranjeni.
- deletes_children: Vsi delovni paketi in njihovi potomci bodo tudi rekurzivno izbrisani.
destroy_time_entry:
title: Potrdite brisanje časovnega vnosa
text: Ali ste prepričani, da želite izbrisati naslednji časovni vnos?
diff --git a/config/locales/crowdin/js-sr.yml b/config/locales/crowdin/js-sr.yml
index 6c3197f8805..eacac083a77 100644
--- a/config/locales/crowdin/js-sr.yml
+++ b/config/locales/crowdin/js-sr.yml
@@ -515,12 +515,6 @@ sr:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -593,49 +587,6 @@ sr:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Zadužen
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -659,39 +610,6 @@ sr:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1064,13 +982,6 @@ sr:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-sv.yml b/config/locales/crowdin/js-sv.yml
index 8c256a434c4..f1cc8a5607e 100644
--- a/config/locales/crowdin/js-sv.yml
+++ b/config/locales/crowdin/js-sv.yml
@@ -515,12 +515,6 @@ sv:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ sv:
settings:
change_notification_settings: Du kan ändra dina aviseringsinställningar för att säkerställa att du aldrig missar en viktig uppdatering.
title: Inställningar för aviseringar
- notify_me: Meddela mig
- reminders:
- no_notification: Ingen avisering
- timeframes:
- normal:
- PT0S: samma dag
- P1D: 1 dag innan
- P3D: 3 dagar innan
- P7D: en vecka innan
- overdue:
- P1D: varje dag
- P3D: var 3:e dag
- P7D: varje vecka
- reasons:
- mentioned:
- title: Omnämnd
- description: Få ett meddelande varje gång någon nämner mig var som helst
- assignee: Tilldelad till
- responsible: Huvudansvarig
- shared: Delad
- watched: Bevakare
- work_package_commented: Alla nya kommentarer
- work_package_created: Nya arbetspaket
- work_package_processed: Alla statusändringar
- work_package_prioritized: Alla prioritetsändringar
- work_package_scheduled: Alla datumändringar
- global:
- immediately:
- title: Deltar
- description: Aviseringar för alla aktiviteter i arbetspaket som du är involverad i (tilldelad ansvarig, ansvarig eller bevakare).
- delayed:
- title: Icke-deltagande
- description: Ytterligare aviseringar för aktiviteter i alla projekt.
- date_alerts:
- title: Datumnotiser
- description: Automatiska aviseringar när viktiga datum närmar sig för öppna arbetspaket som du är involverad i (tilldelad ansvarig, ansvarig eller bevakare).
- overdue: När försenad
- project_specific:
- title: Projekt-specifika aviseringsinställningar
- description: Dessa projektspecifika inställningar åsidosätter standardinställningarna ovan.
- add: Lägg till inställning för projekt
- already_selected: Detta projekt är redan valt
- remove: Ta bort projektinställningar
pagination:
no_other_page: Du befinner dig på den enda sidan.
pages_skipped: Sidor överhoppade.
@@ -658,39 +609,6 @@ sv:
required_outside_context: 'Välj ett projekt för att skapa arbetspaketet för att se alla attribut. Du kan bara välja projekt som har typen ovan aktiverad.
'
- reminders:
- settings:
- daily:
- add_time: Lägg till tid
- enable: Aktivera dagliga e-postpåminnelser
- explanation: Du kommer att få dessa påminnelser endast för olästa aviseringar och endast vid timmar du anger. %{no_time_zone}
- no_time_zone: Tills du konfigurerar en tidszon för ditt konto kommer tiderna att tolkas som att vara i UTC.
- time_label: 'Tid %{counter}:'
- title: Skicka dagligen e-postpåminnelser för olästa aviseringar
- workdays:
- title: Få påminnelser via e-post dessa dagar
- immediate:
- title: Skicka mig en påminnelse via e-post
- mentioned: Omedelbart när någon @nämner mig
- personal_reminder: Omedelbart när jag får en personlig påminnelse
- alerts:
- title: E-postmeddelanden för andra artiklar (som inte är arbetspaket)
- explanation: 'Meddelanden i dag är begränsade till arbetspaket. Du kan välja att fortsätta ta emot e-postmeddelanden för dessa händelser tills de ingår i meddelanden:
-
- '
- news_added: Nyheter tillagda
- news_commented: Kommentar till en nyhet
- document_added: Dokument tillagt
- forum_messages: Nya forummeddelanden
- wiki_page_added: Wiki-sidan tillagd
- wiki_page_updated: Wiki-sidan uppdaterad
- membership_added: Medlemskap tillagt
- membership_updated: Medlemskap uppdaterat
- title: E-postpåminnelser
- pause:
- label: Pausa tillfälligt dagliga e-postpåminnelser
- first_day: Första dagen
- last_day: Senaste dagen
text_are_you_sure: Är du säker?
text_are_you_sure_to_cancel: Du har osparade ändringar på denna sida. Är du säker på att du vill kasta dem?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ sv:
form_submit:
title: Bekräfta för att fortsätta
text: Är du säker på att du vill utföra den här åtgärden?
- destroy_work_package:
- title: Bekräfta radering av %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'Arbetspaketet har %{childUnits}:'
- confirm_deletion_children: Jag bekräftar att allt underliggande till de listade arbetspaketen kommer att tas bort rekursivt.
- deletes_children: Alla barnarbetspaket och deras underliggande kommer också att raderas rekursivt.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-th.yml b/config/locales/crowdin/js-th.yml
index 8209937a2d5..e2492cae3d4 100644
--- a/config/locales/crowdin/js-th.yml
+++ b/config/locales/crowdin/js-th.yml
@@ -515,12 +515,6 @@ th:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -591,49 +585,6 @@ th:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: ผู้ได้รับมอบหมาย
- responsible: Accountable
- shared: Shared
- watched: ผู้ดูข้อมูล
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -657,39 +608,6 @@ th:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: เพิ่มข่าวแล้ว
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: เพิ่มหน้าวิกิแล้ว
- wiki_page_updated: ปรับปรุงหน้าวิกิแล้ว
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: คุณแน่ใจหรือไม่ ?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1062,13 +980,6 @@ th:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-tr.yml b/config/locales/crowdin/js-tr.yml
index 8b417636476..d368508ddd5 100644
--- a/config/locales/crowdin/js-tr.yml
+++ b/config/locales/crowdin/js-tr.yml
@@ -515,12 +515,6 @@ tr:
sidebar_arrow: Projenin ana menüsüne dönmek için sol üst köşedeki dönüş okunu kullanın.
welcome: En önemli özellikleri öğrenmek için üç dakikalık bir tanıtım gezintisine çıkın. Tüm adımları tamamlamanızı öneririz. Turu istediğiniz zaman yeniden başlatabilirsiniz.
wiki: "wiki içinde belgeleyebilir ve ekibinizle birlikte bilgi paylaşabilirsiniz."
- backlogs:
- overview: İşinizi birikimler görünümünde yönetin.
- sprints: Sağ tarafta ürün biriktirme listesi ve hata biriktirme listesi var, solda da ilgili sprintler var. Burada epikler, kullanıcı hikayeleri ve buglar oluşturabilir, sürükleyip bırakarak öncelik sırasına koyabilir ve bunları bir sprint'e ekleyebilirsiniz.
- task_board_arrow: "Görev panonuzu görmek için Sprint açılır menüsünde açın..."
- task_board_select: "... ve görev panosu kaydını seçin."
- task_board: Görev panosu, bu sprint için ilerlemeyi görselleştirir. Yeni görevler veya engeller eklemek için bir kullanıcı hikayesinin yanındaki artı (+) simgesine tıklayın. Sürükle bırak ile durum güncellenebilir.
boards:
overview: Görünümü değiştirmek ve çevik panolar görünümünü kullanarak projenizi yönetmek için panolar'ı seçin.
lists_kanban: Burada panonuzda birden çok liste (sütun) oluşturabilirsiniz. Bu özellik, örneğin bir Kanban panosu oluşturmanıza olanak tanır.
@@ -592,49 +586,6 @@ tr:
settings:
change_notification_settings: Önemli bir güncellemeyi asla kaçırmamak için bildirim ayarlarınızı değiştirebilirsiniz.
title: Bildirim ayarları
- notify_me: Beni dürt
- reminders:
- no_notification: Bildirim yok
- timeframes:
- normal:
- PT0S: aynı gün
- P1D: 1 gün önce
- P3D: 3 gün önce
- P7D: 1 hafta önce
- overdue:
- P1D: her gün
- P3D: Her 3 günde bir
- P7D: her hafta
- reasons:
- mentioned:
- title: Bahsedilen
- description: Birisi herhangi bir yerde benden her bahsettiğinde bir bildirim alın
- assignee: Atanan
- responsible: Sorumlu
- shared: Paylaşıldı
- watched: Takip edilen
- work_package_commented: Tüm yeni yorumlar
- work_package_created: Yeni iş paketleri
- work_package_processed: Tüm durum değişiklikleri
- work_package_prioritized: Tüm öncelik değişiklikleri
- work_package_scheduled: Tüm tarih değişiklikleri
- global:
- immediately:
- title: Katılım
- description: Dahil olduğunuz (vekil, sorumlu veya gözlemci) iş paketlerindeki tüm faaliyetler için bildirimler.
- delayed:
- title: Katılmayan
- description: Tüm projelerdeki faaliyetler için ek bildirimler.
- date_alerts:
- title: Tarih uyarısı
- description: Dahil olduğunuz (vekil, sorumlu veya gözlemci) açık iş paketleri için önemli tarihler yaklaştığında otomatik bildirimler.
- overdue: Süresi geçtiğinde
- project_specific:
- title: Projeye özel bildirim ayarları
- description: Bu projeye özgü ayarlar, yukarıdaki varsayılan ayarları geçersiz kılar.
- add: Proje için ayar ekle
- already_selected: Bu proje zaten seçildi
- remove: Proje ayarlarını kaldır
pagination:
no_other_page: Geçerli tek sayfadasınız.
pages_skipped: Sayfalar atlandı.
@@ -658,39 +609,6 @@ tr:
required_outside_context: 'Lütfen tüm özellikleri görmek için çalışma paketini oluşturacak bir proje seçin. Yalnızca yukarıdaki türden etkin olan projeleri seçebilirsiniz.
'
- reminders:
- settings:
- daily:
- add_time: Zaman ekle
- enable: Günlük email hatırlatıcılarını etkinleştir
- explanation: Bu hatırlatıcıları yalnızca okunmamış bildirimler için ve yalnızca sizin belirlediğiniz saatlerde alacaksınız. %{no_time_zone}
- no_time_zone: Hesabınız için bir saat dilimi yapılandırana kadar, saatler UTC olarak yorumlanacaktır.
- time_label: 'Zaman %{counter}:'
- title: Okunmamış bildirimler için bana günlük e-posta hatırlatıcıları gönder
- workdays:
- title: Bu günlerde e-posta hatırlatıcıları alın
- immediate:
- title: Bana email hatırlatıcısı gönder
- mentioned: Birisi benden @bahsettiğinde hemen
- personal_reminder: Kişisel bir hatırlatma aldığımda hemen
- alerts:
- title: Diğer öğeler için e-posta uyarıları (iş paketleri olmayanlar)
- explanation: 'Bildirimler bugün iş paketleri ile sınırlıdır. Bildirimlere eklenene kadar bu etkinlikler için e-posta uyarıları almaya devam etmeyi seçebilirsiniz:
-
- '
- news_added: Haber eklendiğinde
- news_commented: Bir habere yorum yapıldığında
- document_added: Belgeler eklendi
- forum_messages: Yeni forum iletileri yazıldığında
- wiki_page_added: Wiki sayfası eklendiğinde
- wiki_page_updated: Wiki sayfası güncellendiğinde
- membership_added: Üyelik eklendiğinde
- membership_updated: Üyelik güncellendiğinde
- title: Email hatırlatıcıları
- pause:
- label: Email hatırlatıcılarını geçici olarak durdur
- first_day: İlk gün
- last_day: Son gün
text_are_you_sure: Emin misiniz?
text_are_you_sure_to_cancel: Bu sayfada kaydedilmemiş değişiklikleriniz var. Bunları atmak istediğinizden emin misiniz?
breadcrumb: Gezinti Menüsü
@@ -1063,13 +981,6 @@ tr:
form_submit:
title: Devam etmek için onaylayın
text: Bu işlemi gerçekleştirmek istediğinizden emin misiniz?
- destroy_work_package:
- title: "%{label} için silme işlimini onaylayın"
- single_text: Bu iş paketini silmek istediğinize emin misiniz?
- bulk_text: Aşağıdaki %{label}'i silmek istediğinizden emin misiniz?
- has_children: 'İş paketi %{childUnits} alt paketlerine sahip:'
- confirm_deletion_children: Listelenen iş paketlerinin TÜM soylarının tekrar tekrar kaldırılacağını kabul ediyorum.
- deletes_children: Tüm çocuk iş paketleri ve torunları da tekrar tekrar silinir.
destroy_time_entry:
title: Zaman girişinin silinmesini onaylayın
text: Aşağıdaki zaman girişini silmek istediğinizden emin misiniz?
diff --git a/config/locales/crowdin/js-uk.yml b/config/locales/crowdin/js-uk.yml
index 704242f5274..2277c30f7f8 100644
--- a/config/locales/crowdin/js-uk.yml
+++ b/config/locales/crowdin/js-uk.yml
@@ -515,12 +515,6 @@ uk:
sidebar_arrow: Використовуйте стрілку повернення у верхньому лівому куті, щоб повернутися в головне меню проєкту.
welcome: Пройдіть трихвилинний вступний тур, щоб дізнатися про найважливіші функції. Ми рекомендуємо завершити всі етапи до кінця. Ви можете перезапустити тур у будь-який час.
wiki: У межах Wiki ви можете документувати знання та обмінюватися ними зі своєю командою.
- backlogs:
- overview: Керуйте своєю роботою в поданні Backlogs.
- sprints: Праворуч у вікні подання можна переглянути невиконані завдання щодо продукту та помилки. Ліворуч можна створювати епіки, історії користувачів і помилки, визначати їх пріоритет перетягуванням і додавати їх до спринтів.
- task_board_arrow: Щоб переглянути свою дошку завдань, відкрийте спадне меню спринту…
- task_board_select: "... і виберіть запис на дошці завдань."
- task_board: Панель завдань візуалізує перебіг цього спринту. Натисніть на знак плюса (+) біля історії користувача, щоб додати нові завдання або перешкоди. Стан можна оновити перетягуванням.
boards:
overview: Виберіть дошки, щоб зсунути подання та керувати своїм проєктом за допомогою подання дощок Agile.
lists_kanban: Тут можна створити кілька списків (стовпців) у межах дошки. Ця функція дає змогу створити, наприклад, дошку Kanban.
@@ -594,49 +588,6 @@ uk:
settings:
change_notification_settings: Ви можете змінити налаштування сповіщень, щоб ніколи не пропускати важливі оновлення.
title: Налаштування сповіщень
- notify_me: Сповіщати мене
- reminders:
- no_notification: Немає сповіщень
- timeframes:
- normal:
- PT0S: того ж дня
- P1D: за 1 день
- P3D: за 3 дні
- P7D: за тиждень
- overdue:
- P1D: щодня
- P3D: кожні 3 дні
- P7D: щотижня
- reasons:
- mentioned:
- title: Згадано
- description: Отримувати сповіщення щоразу, коли хтось згадує мене де завгодно
- assignee: Виконавець
- responsible: Відповідальний
- shared: Спільні
- watched: Спостерігач
- work_package_commented: Усі нові коментарі
- work_package_created: Нові пакети робіт
- work_package_processed: Усі зміни статусу
- work_package_prioritized: Усі зміни пріоритету
- work_package_scheduled: Усі зміни дат
- global:
- immediately:
- title: Бере участь
- description: Сповіщення про всі дії з пакетами робіт, з якими ви пов’язані (виконавець, відповідальний або спостерігач).
- delayed:
- title: Не бере участі
- description: Додаткові сповіщення про дії в усіх проєктах.
- date_alerts:
- title: Оповіщення про дати
- description: Автоматичні сповіщення в разі наближення важливих дат для відкритих пакетів робіт, з якими ви пов’язані (виконавець, відповідальний або спостерігач).
- overdue: Якщо прострочено
- project_specific:
- title: Параметри сповіщень проєкту
- description: Ці налаштування сповіщень проєкту перевизначають типові налаштування вище.
- add: Додати налаштування для проєкту
- already_selected: Цей проєкт уже вибрано
- remove: Вилучити налаштування проєкту
pagination:
no_other_page: Ви знаходитесь на єдиній сторінці.
pages_skipped: Сторінки пропущено.
@@ -660,39 +611,6 @@ uk:
required_outside_context: 'Виберіть проект, щоб створити робочий пакет, щоб побачити всі атрибути. Ви можете вибирати лише проекти, які мають вказаний вище тип активації.
'
- reminders:
- settings:
- daily:
- add_time: Додати час
- enable: Увімкнути щоденні нагадування електронною поштою
- explanation: Ви отримуватимете ці нагадування лише для непрочитаних сповіщень і тільки в указані години. %{no_time_zone}
- no_time_zone: Доки ви не налаштуєте часовий пояс для свого облікового запису, вважатиметься, що ваш час указано за стандартом UTC.
- time_label: 'Час %{counter}:'
- title: Надсилати мені щоденні нагадування електронною поштою про непрочитані сповіщення
- workdays:
- title: Отримувати нагадування електронною поштою в ці дні
- immediate:
- title: Надсилати мені нагадування електронною поштою
- mentioned: Негайно, коли хтось згадує @мене
- personal_reminder: Одразу після отримання особистого нагадування
- alerts:
- title: Сповіщення електронною поштою для інших елементів (які не є пакетами робіт)
- explanation: 'Сьогодні надходитимуть лише сповіщення про пакети робіт. Ви можете й надалі отримувати сповіщення електронною поштою для цих подій, якщо їх не буде включено в сповіщення:
-
- '
- news_added: Новину додано
- news_commented: Коментар щодо новини
- document_added: Документи додано
- forum_messages: Нові повідомлення форуму
- wiki_page_added: Додано сторінку Wiki
- wiki_page_updated: Сторінка Wiki оновлена
- membership_added: Членство додано
- membership_updated: Членство додано
- title: Нагадування електронною поштою
- pause:
- label: Тимчасово призупинити щоденні нагадування електронною поштою
- first_day: Перший день
- last_day: Останній день
text_are_you_sure: Ви впевненені?
text_are_you_sure_to_cancel: На цій сторінці є незбережені зміни. Ви дійсно хочете їх скасувати?
breadcrumb: Ланцюжок навігації
@@ -1065,13 +983,6 @@ uk:
form_submit:
title: Підтвердьте продовження
text: Дійсно виконати цю дію?
- destroy_work_package:
- title: Підтвердьте видалення %{label}
- single_text: Справді видалити цей пакет робіт?
- bulk_text: Справді видалити %{label} нижче?
- has_children: Робочий пакет має %{childUnits}
- confirm_deletion_children: Я визнаю, що ВСІ нащадки перерахованих робочих пакетів будуть рекурсивно видалені.
- deletes_children: Всі дочірні робочі пакети та їх нащадки також будуть рекурсивно видалені.
destroy_time_entry:
title: Підтвердьте видалення запису часу
text: Справді видалити наведений нижче запис часу?
diff --git a/config/locales/crowdin/js-uz.yml b/config/locales/crowdin/js-uz.yml
index ab77db4e91e..6fa739ffc6c 100644
--- a/config/locales/crowdin/js-uz.yml
+++ b/config/locales/crowdin/js-uz.yml
@@ -515,12 +515,6 @@ uz:
sidebar_arrow: Use the return arrow in the top left corner to return to the project’s main menu.
welcome: Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time.
wiki: Within the wiki you can document and share knowledge together with your team.
- backlogs:
- overview: Manage your work in the backlogs view.
- sprints: On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint.
- task_board_arrow: To see your task board, open the sprint drop-down...
- task_board_select: "...and select the task board entry."
- task_board: The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop.
boards:
overview: Select boards to shift the view and manage your project using the agile boards view.
lists_kanban: Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example.
@@ -592,49 +586,6 @@ uz:
settings:
change_notification_settings: You can modify your notification settings to ensure you never miss an important update.
title: Notification settings
- notify_me: Notify me
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: Mentioned
- description: Receive a notification every time someone mentions me anywhere
- assignee: Assignee
- responsible: Accountable
- shared: Shared
- watched: Watcher
- work_package_commented: All new comments
- work_package_created: New work packages
- work_package_processed: All status changes
- work_package_prioritized: All priority changes
- work_package_scheduled: All date changes
- global:
- immediately:
- title: Participating
- description: Notifications for all activities in work packages you are involved in (assignee, accountable or watcher).
- delayed:
- title: Non-participating
- description: Additional notifications for activities in all projects.
- date_alerts:
- title: Date alerts
- description: Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher).
- overdue: When overdue
- project_specific:
- title: Project-specific notification settings
- description: These project-specific settings override default settings above.
- add: Add setting for project
- already_selected: This project is already selected
- remove: Remove project settings
pagination:
no_other_page: You are on the only page.
pages_skipped: Pages skipped.
@@ -658,39 +609,6 @@ uz:
required_outside_context: 'Please choose a project to create the work package in to see all attributes. You can only select projects which have the type above activated.
'
- reminders:
- settings:
- daily:
- add_time: Add time
- enable: Enable daily email reminders
- explanation: You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}
- no_time_zone: Until you configure a time zone for your account, the times will be interpreted to be in UTC.
- time_label: 'Time %{counter}:'
- title: Send me daily email reminders for unread notifications
- workdays:
- title: Receive email reminders on these days
- immediate:
- title: Send me an email reminder
- mentioned: Immediately when someone @mentions me
- personal_reminder: Immediately when I receive a personal reminder
- alerts:
- title: Email alerts for other items (that are not work packages)
- explanation: 'Notifications today are limited to work packages. You can choose to continue receiving email alerts for these events until they are included in notifications:
-
- '
- news_added: News added
- news_commented: Comment on a news item
- document_added: Documents added
- forum_messages: New forum messages
- wiki_page_added: Wiki page added
- wiki_page_updated: Wiki page updated
- membership_added: Membership added
- membership_updated: Membership updated
- title: Email reminders
- pause:
- label: Temporarily pause daily email reminders
- first_day: First day
- last_day: Last day
text_are_you_sure: Are you sure?
text_are_you_sure_to_cancel: You have unsaved changes on this page. Are you sure you want to discard them?
breadcrumb: Breadcrumb
@@ -1063,13 +981,6 @@ uz:
form_submit:
title: Confirm to continue
text: Are you sure you want to perform this action?
- destroy_work_package:
- title: Confirm deletion of %{label}
- single_text: Are you sure you want to delete the work package
- bulk_text: Are you sure you want to delete the following %{label}?
- has_children: 'The work package has %{childUnits}:'
- confirm_deletion_children: I acknowledge that ALL descendants of the listed work packages will be recursively removed.
- deletes_children: All child work packages and their descendants will also be recursively deleted.
destroy_time_entry:
title: Confirm deletion of time entry
text: Are you sure you want to delete the following time entry?
diff --git a/config/locales/crowdin/js-vi.yml b/config/locales/crowdin/js-vi.yml
index 1e8f3b6ea59..4e34fc537bc 100644
--- a/config/locales/crowdin/js-vi.yml
+++ b/config/locales/crowdin/js-vi.yml
@@ -109,7 +109,7 @@ vi:
button_save: lưu lại
button_settings: cài đặt
button_uncheck_all: Bỏ chọn tất cả
- button_update: cập nhật
+ button_update: Cập Nhật
button_export-atom: Tải xuống nguyên tử
button_generate_pdf: Tạo PDF
button_create: Tạo mới
@@ -515,12 +515,6 @@ vi:
sidebar_arrow: Sử dụng mũi tên quay lại ở góc trên cùng bên trái để quay lại menu chính của dự án.
welcome: Hãy tham gia chuyến tham quan giới thiệu dài ba phút để tìm hiểu tính năng quan trọng nhất. Chúng tôi khuyên bạn nên hoàn thành các bước cho đến hết. Bạn có thể bắt đầu lại chuyến tham quan bất cứ lúc nào.
wiki: Trong wiki bạn có thể ghi lại và chia sẻ kiến thức cùng với nhóm của mình.
- backlogs:
- overview: Quản lý công việc của bạn trong chế độ xem backlogs.
- sprints: Ở bên phải, bạn có tồn đọng sản phẩm và tồn đọng lỗi, ở bên trái, bạn có các lần chạy nước rút tương ứng. Tại đây, bạn có thể tạo sử thi, cốt truyện của người dùng và lỗi, ưu tiên bằng cách kéo và thả và thêm chúng vào chạy nước rút.
- task_board_arrow: Để xem bảng nhiệm vụ của bạn, hãy mở trình đơn thả xuống chạy nước rút...
- task_board_select: "...và chọn mục nhập bảng nhiệm vụ."
- task_board: Bảng nhiệm vụ hiển thị tiến trình cho lần chạy nước rút này. Nhấp vào biểu tượng dấu cộng (+) bên cạnh cốt truyện của người dùng để thêm nhiệm vụ hoặc trở ngại mới. Trạng thái có thể được cập nhật bằng cách kéo và thả.
boards:
overview: Chọn boards để thay đổi chế độ xem và quản lý dự án của bạn bằng chế độ xem bảng linh hoạt.
lists_kanban: 'Tại đây bạn có thể tạo nhiều danh sách (cột) trong bảng của mình. Ví dụ: tính năng này cho phép bạn tạo Kanban board.'
@@ -591,49 +585,6 @@ vi:
settings:
change_notification_settings: Bạn có thể thay đổi cài đặt thông báo của mình để đảm bảo không bỏ lỡ cập nhật quan trọng nào.
title: Cài đặt thông báo
- notify_me: Thông báo cho tôi
- reminders:
- no_notification: Không có thông báo
- timeframes:
- normal:
- PT0S: cùng ngày
- P1D: 1 ngày trước
- P3D: 3 ngày trước
- P7D: một tuần trước
- overdue:
- P1D: mỗi ngày
- P3D: cứ sau 3 ngày
- P7D: mỗi tuần
- reasons:
- mentioned:
- title: Được đề cập
- description: Nhận thông báo mỗi khi ai đó nhắc đến tôi ở bất cứ đâu
- assignee: Người được chuyển nhượng
- responsible: chịu trách nhiệm
- shared: đã chia sẻ
- watched: người theo dõi
- work_package_commented: Tất cả bình luận mới
- work_package_created: Gói công việc mới
- work_package_processed: Mọi thay đổi trạng thái
- work_package_prioritized: Tất cả các thay đổi ưu tiên
- work_package_scheduled: Tất cả các thay đổi ngày
- global:
- immediately:
- title: Tham gia
- description: Thông báo cho tất cả các hoạt động trong gói công việc mà bạn tham gia (người được giao, người chịu trách nhiệm hoặc người theo dõi).
- delayed:
- title: Không tham gia
- description: Thông báo bổ sung cho các hoạt động trong tất cả các dự án.
- date_alerts:
- title: Thông báo ngày
- description: Thông báo tự động khi các ngày quan trọng đang đến gần đối với các gói công việc đang mở mà bạn tham gia (người được giao, người chịu trách nhiệm hoặc người theo dõi).
- overdue: Khi quá hạn
- project_specific:
- title: Cài đặt thông báo dành riêng cho dự án
- description: Các cài đặt dành riêng cho dự án này sẽ ghi đè các cài đặt mặc định ở trên.
- add: Thêm cài đặt cho dự án
- already_selected: Dự án này đã được chọn
- remove: Xóa cài đặt dự án
pagination:
no_other_page: Bạn đang trên trang duy nhất.
pages_skipped: Các trang bị bỏ qua.
@@ -657,39 +608,6 @@ vi:
required_outside_context: 'Vui lòng chọn một dự án để tạo gói công việc để xem tất cả các thuộc tính. Bạn chỉ có thể chọn các dự án đã kích hoạt loại trên.
'
- reminders:
- settings:
- daily:
- add_time: Thêm thời gian
- enable: Bật lời nhắc email hàng ngày
- explanation: Bạn sẽ chỉ nhận được những lời nhắc này đối với những thông báo chưa đọc và chỉ vào những giờ bạn chỉ định. %{no_time_zone}
- no_time_zone: Cho đến khi bạn định cấu hình múi giờ cho tài khoản của mình, thời gian sẽ được hiểu là theo UTC.
- time_label: 'Thời gian %{counter}:'
- title: Gửi cho tôi lời nhắc email hàng ngày về các thông báo chưa đọc
- workdays:
- title: Nhận lời nhắc qua email vào những ngày này
- immediate:
- title: Gửi cho tôi lời nhắc qua email
- mentioned: Ngay lập tức khi ai đó @đề cập đến tôi
- personal_reminder: Ngay lập tức khi tôi nhận được lời nhắc cá nhân
- alerts:
- title: Thông báo qua email cho các mục khác (không phải là gói công việc)
- explanation: 'Thông báo ngày hôm nay được giới hạn trong các gói công việc. Bạn có thể chọn tiếp tục nhận thông báo qua email cho những sự kiện này cho đến khi chúng được đưa vào thông báo:
-
- '
- news_added: Đã thêm tin tức
- news_commented: Bình luận về một tin tức
- document_added: Đã thêm tài liệu
- forum_messages: Thông báo diễn đàn mới
- wiki_page_added: Đã thêm trang Wiki
- wiki_page_updated: Trang Wiki được cập nhật
- membership_added: Đã thêm thành viên
- membership_updated: Đã cập nhật tư cách thành viên
- title: Lời nhắc qua email
- pause:
- label: Tạm dừng nhắc nhở email hàng ngày
- first_day: Ngày đầu tiên
- last_day: Ngày cuối cùng
text_are_you_sure: Bạn có chắc không?
text_are_you_sure_to_cancel: Bạn có những thay đổi chưa được lưu trên trang này. Bạn có chắc chắn muốn loại bỏ chúng không?
breadcrumb: vụn bánh mì
@@ -1062,13 +980,6 @@ vi:
form_submit:
title: Xác nhận để tiếp tục
text: Bạn có thực sự muốn thực hiện thao tác này?
- destroy_work_package:
- title: Xác nhận xóa %{label}
- single_text: Bạn có chắc chắn muốn xóa gói công việc
- bulk_text: Bạn có chắc chắn muốn xóa %{label} sau đây không?
- has_children: 'Gói công việc có %{childUnits}:'
- confirm_deletion_children: Tôi xác nhận rằng TẤT CẢ các gói công việc kế thừa được liệt kê sẽ bị xóa đệ quy.
- deletes_children: Tất cả các gói công việc con và con cháu của chúng cũng sẽ bị xóa đệ quy.
destroy_time_entry:
title: Xác nhận xóa mục nhập thời gian
text: Bạn có chắc chắn muốn xóa mục nhập thời gian sau đây không?
diff --git a/config/locales/crowdin/js-zh-CN.yml b/config/locales/crowdin/js-zh-CN.yml
index 39814fd5b41..32f29d7f603 100644
--- a/config/locales/crowdin/js-zh-CN.yml
+++ b/config/locales/crowdin/js-zh-CN.yml
@@ -515,12 +515,6 @@ zh-CN:
sidebar_arrow: 使用左上角的返回箭头可返回到项目的主菜单。
welcome: 通过三分钟的导览了解最重要的功能 。 我们建议您完成所有步骤。您可以随时重新浏览介绍。
wiki: 在 维基 中,您可以记录并与您的团队共享知识。
- backlogs:
- overview: 在待办清单视图中管理您的工作。
- sprints: 右侧为产品待办清单和缺陷待办清单,左侧为各自的冲刺 (Sprint)。在这里,您可以创建长篇故事、用户故事和错误,通过拖放来确定优先级,以及将它们添加到冲刺 (sprint) 中。
- task_board_arrow: 要查看您的任务面板,请打开冲刺 (sprint) 下拉菜单…
- task_board_select: "…并选择任务面板条目。"
- task_board: 任务面板可以将此冲刺 (sprint) 的进度可视化。点击用户故事旁边的加号 (+) 图标可添加新任务或障碍。 状态可以通过拖放更新。
boards:
overview: 选择面板以切换视图并使用敏捷面板视图管理您的项目。
lists_kanban: 在此,您可以在面板中创建多个列表(列)。例如,此功使让您可以创建看板面板。
@@ -591,51 +585,6 @@ zh-CN:
settings:
change_notification_settings: 您可以修改您的通知设置,以确保您不会错过重要的更新。
title: 通知设置
- notify_me: 通知我
- reminders:
- no_notification: 无通知
- timeframes:
- normal:
- PT0S: 当天
- P1D: 提前 1 天
- P3D: 提前 3 天
- P7D: 提前一周
- overdue:
- P1D: 每天
- P3D: 每 3 天
- P7D: 每周
- reasons:
- mentioned:
- title: 被提及
- description: 每当有人在任何位置提及我时都接收通知
- assignee: 受理人
- responsible: 负责人
- shared: 共享
- watched: 关注者
- work_package_commented: 所有新评论
- work_package_created: 新工作包
- work_package_processed: 所有状态更改
- work_package_prioritized: 所有优先级更改
- work_package_scheduled: 所有日期更改
- global:
- immediately:
- title: 参与
- description: 对于你参与的所有工作包(受理人、负责人或关注者),可以设置通知以接收所有活动的提醒。
- delayed:
- title: 不参与
- description: 在所有项目中通知您所有活动。
- date_alerts:
- title: 日期提醒
- description: 当你参与的开放工作包(作为受理人、负责人或关注者)的重要日期临近时,自动发送通知。
- overdue: 逾期时
- project_specific:
- title: 项目特定通知设置
- description: '这些特定于项目的设置会覆盖上面的默认设置。
-
- '
- add: 为项目添加设置
- already_selected: 此项目已经选定
- remove: 移除项目设置
pagination:
no_other_page: 您位于唯一页面上。
pages_skipped: 跳过的页面。
@@ -659,39 +608,6 @@ zh-CN:
required_outside_context: '请选择要创建工作包的项目以查看所有属性。 您只能选择已激活上述类型的项目。
'
- reminders:
- settings:
- daily:
- add_time: 添加时间
- enable: 启用每日电子邮件提醒
- explanation: 只有存在未读通知时,您才会在指定的时间收到这些提醒。%{no_time_zone}
- no_time_zone: 除非您为帐户配置时区,否则将以 UTC 显示时间。
- time_label: 时间 %{counter}:
- title: 向我发送针对未读通知的每日电子邮件提醒
- workdays:
- title: 在如下日期接收电子邮件提醒
- immediate:
- title: 向我发送电子邮件提醒
- mentioned: 当有人@提及我时立即提醒
- personal_reminder: 收到个人提醒后立即发送
- alerts:
- title: 其他项目(非工作包)的电子邮件提醒
- explanation: '今日提醒仅限于工作包。您可以选择继续接收这些事件的电子邮件提醒,直到它们被包含在通知中。
-
- '
- news_added: 添加新闻
- news_commented: 评论新闻
- document_added: 添加文档
- forum_messages: 新的论坛消息
- wiki_page_added: 添加维基页面
- wiki_page_updated: 更新维基页面
- membership_added: 添加成员
- membership_updated: 更新成员
- title: 电子邮件提醒
- pause:
- label: 临时暂停每日电子邮件提醒
- first_day: 第一天
- last_day: 最后一天
text_are_you_sure: 是否确定?
text_are_you_sure_to_cancel: 您在此页面上有未保存的更改。您确定要放弃这些更改吗?
breadcrumb: 面包屑导航
@@ -1064,13 +980,6 @@ zh-CN:
form_submit:
title: 确认已继续
text: 是否确定想要执行此操作?
- destroy_work_package:
- title: 确认删除%{label}
- single_text: 确定要删除此工作包吗?
- bulk_text: 确定要删除以下%{label}吗?
- has_children: '工作包有 %{childUnits}:'
- confirm_deletion_children: 我确认所列工作包的全部子工作包都将递归移除。
- deletes_children: 所有子工作包及其子级也将递归删除。
destroy_time_entry:
title: 确认删除时间条目
text: 确定要删除以下时间条目?
diff --git a/config/locales/crowdin/js-zh-TW.yml b/config/locales/crowdin/js-zh-TW.yml
index 20f77ec0357..58d066fc883 100644
--- a/config/locales/crowdin/js-zh-TW.yml
+++ b/config/locales/crowdin/js-zh-TW.yml
@@ -515,12 +515,6 @@ zh-TW:
sidebar_arrow: 用左上方的返回鍵,返回至專案的 主選單.
welcome: 觀看三分鐘的介紹導覽, 以瞭解最多 重要功能。 我們建議完成所有步驟直到結束。您可以隨時重新開始導覽。
wiki: 在 wiki 中, 您可以與您的團隊一起記錄和分享知識。
- backlogs:
- overview: " 在backlogs 檢視中,管理您的工作。"
- sprints: 在待辦工作版面中管理您的工作。 在右邊, 你有專案待辦或錯誤紀錄, 在左邊, 你將有各自的衝刺。在這裡, 您可以創建 史詩、使用者故事和錯誤, 通過拖曳進行優先排序, 並將它們添加到衝刺中。
- task_board_arrow: 要查看您的任務面板,請打開衝刺(sprint)下拉選單…
- task_board_select: "…並選擇任務面板條目。"
- task_board: 任務面板可以將此衝刺 (sprint) 的進度可視化。點擊用戶故事旁邊的加號 (+) 圖標可添加新任務或障礙。 狀態可以通過拖放更新。
boards:
overview: 選擇面板以切換視圖並使用敏捷面板視圖管理您的項目。
lists_kanban: 在此,您可以在面板中創建多個列表(列)。例如,此功使讓您可以創建看板面板。
@@ -591,51 +585,6 @@ zh-TW:
settings:
change_notification_settings: 您可以修改 通知設定,以確保您不會錯過重要更新。
title: 通知設定
- notify_me: 通知我
- reminders:
- no_notification: 无通知
- timeframes:
- normal:
- PT0S: 當日
- P1D: 一天前
- P3D: 3 天前
- P7D: 1 週前
- overdue:
- P1D: 每天
- P3D: 每 3 天
- P7D: 每週
- reasons:
- mentioned:
- title: 被提及
- description: 每當有人提及我時都收到通知
- assignee: 執行者
- responsible: 負責人
- shared: 參與
- watched: '監看者
-
- '
- work_package_commented: 有新留言
- work_package_created: 新增工作套件
- work_package_processed: 所有狀態改變
- work_package_prioritized: 優先順序已變更
- work_package_scheduled: 所有日期變更
- global:
- immediately:
- title: 參與中
- description: 你參與的工作套件中所有活動的通知(執行者、負責人或監看者)。
- delayed:
- title: 未參與之工作套件
- description: 額外通知
- date_alerts:
- title: 日期提醒
- description: 當「執行者、負責人或監看者」之開啟的工作套件,其重要日期臨近時,自動發出通知。
- overdue: 逾期
- project_specific:
- title: 特定專案通知設定
- description: 特別專案通知設定將覆蓋上列標準設定。
- add: 新增設定
- already_selected: 已選取此專案
- remove: 移除專案設定
pagination:
no_other_page: 您位於唯一頁面上。
pages_skipped: 跳過的頁面。
@@ -659,39 +608,6 @@ zh-TW:
required_outside_context: '請選擇專案以便新增工作套件以及檢視屬性。您只能選擇啟用中的專案。
'
- reminders:
- settings:
- daily:
- add_time: 加入時間
- enable: 啟用每日電子郵件提醒
- explanation: 只有當未讀取通知時,您才會在指定的時間收到這些提醒。%{no_time_zone}
- no_time_zone: 除非您為帳戶配置時區,否則將以 UTC 顯示時間。
- time_label: '時間 %{counter}:'
- title: 每日將尚未讀取之通知,寄提醒郵件給我
- workdays:
- title: 在以下日期收到電子郵件提醒
- immediate:
- title: 寄發提醒郵件給我
- mentioned: 當有人使用「@帳號」提到我,系統立即發信通知我
- personal_reminder: 當我收到個人提醒時立即通知
- alerts:
- title: 其他非工作套件之提醒
- explanation: '目前的通知僅限於工作套件。您可以選擇在這些事件納入通知系統之前,繼續透過電子郵件接收提醒:
-
- '
- news_added: 有最新消息
- news_commented: 最新消息有留言
- document_added: 文件已新增
- forum_messages: 有新的討論區訊息
- wiki_page_added: 新增維基頁面
- wiki_page_updated: 維基頁面有更新
- membership_added: 成員加入
- membership_updated: 成員更新
- title: 電子郵件提醒
- pause:
- label: 暫時暫停每日電子郵件提醒
- first_day: 第一天
- last_day: 最後一天
text_are_you_sure: 是否確定?
text_are_you_sure_to_cancel: 您在此頁面上有未儲存的變更。您確定要捨棄它們嗎?
breadcrumb: 導覽軌跡
@@ -1064,13 +980,6 @@ zh-TW:
form_submit:
title: 確認以繼續
text: 確定要執行此操作嗎?
- destroy_work_package:
- title: 確認刪除 %{label}
- single_text: 確定要刪除此工作套件嗎
- bulk_text: 確定要刪除以下%{label} 嗎?
- has_children: 此工作套件包含 %{childUnits}:
- confirm_deletion_children: 我確認列出的工作套件的所有細項全部都將被刪除。
- deletes_children: 所有子工作套件及相關套件也全部將被刪除。
destroy_time_entry:
title: 確認刪除時間條目
text: 確定要刪除以下時間條目?
diff --git a/config/locales/crowdin/ka.yml b/config/locales/crowdin/ka.yml
index 67cbfcc0c23..05cf54d7ce5 100644
--- a/config/locales/crowdin/ka.yml
+++ b/config/locales/crowdin/ka.yml
@@ -114,7 +114,7 @@ ka:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ka:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ka:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ka:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ ka:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ ka:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ ka:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ ka:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ ka:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ ka:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ ka:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: ჩვენება სადამდე
attachment:
@@ -1800,6 +1853,7 @@ ka:
identity_url: იდენტიფიკაციის URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ ka:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ ka:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ ka:
avatar: ავატარი
base: 'ზოგადი შეცდომა:'
body: Body
- blocks_ids: IDs of blocked work packages
category: კატეგორია
comment: კომენტარი
comments: კომენტარი
@@ -2922,6 +2977,7 @@ ka:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: შეუზღუდავი
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ ka:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ ka:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: დამსაქმებელი
@@ -3484,6 +3611,7 @@ ka:
invalid_filter: Invalid notification filter
label_accessibility: წვდომადობა
label_account: ანგარიში
+ label_actions: ქმედებები
label_active: აქტიური
label_activate_user: მომხმარებლის გააქტიურება
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ ka:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: უახლესი
label_ical_access_key_revoke: გაუქმება
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: გადატარებულია სტატუსი
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ ka:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: საკვანძო სიტყვები
label_language_based: Based on user's language
label_last_activity: ბოლო აქტივობა
@@ -3812,6 +3941,10 @@ ka:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: მომხმარებლის favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: გასვლა
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: გვერდითი მენიუ
@@ -4884,6 +5017,7 @@ ka:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ ka:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/kk.yml b/config/locales/crowdin/kk.yml
index c7aef34428b..b0a96f521e5 100644
--- a/config/locales/crowdin/kk.yml
+++ b/config/locales/crowdin/kk.yml
@@ -114,7 +114,7 @@ kk:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ kk:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ kk:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ kk:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ kk:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ kk:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ kk:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ kk:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ kk:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ kk:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ kk:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ kk:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ kk:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ kk:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ kk:
avatar: Аватар
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ kk:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ kk:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ kk:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ kk:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ kk:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ kk:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ kk:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ kk:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ kk:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/ko.yml b/config/locales/crowdin/ko.yml
index dc14bb7c0ef..4009e1e8f30 100644
--- a/config/locales/crowdin/ko.yml
+++ b/config/locales/crowdin/ko.yml
@@ -114,7 +114,7 @@ ko:
import:
title: 가져오기
jira:
- title: Jira 가져오기
+ title: Jira Migrator
description: 이 도구를 사용하여 Jira 인스턴스에서 데이터를 가져옵니다. 여러 Jira 호스트를 구성하고 가져오기 실행 각각에서 가져올 항목을 선택할 수 있습니다.
errors:
cannot_delete_with_imports: 기존 가져오기가 있는 Jira 호스트는 삭제할 수 없습니다
@@ -125,8 +125,8 @@ ko:
title: Jira 구성
new: 새 구성
banner:
- title: 제한된 가져오기
- description: 이 가져오기 도구는 현재 베타 버전이며 프로젝트, 이슈(이름, 제목, 설명, 첨부 파일), 사용자(이름, 이메일, 프로젝트 멤버십), 상태 및 유형과 같은 기본 데이터만 가져올 수 있습니다. 워크플로, 사용자 지정 필드, 이슈 관계 또는 권한은 가져올 수 없습니다. Jira Server/Data Center 버전 10.x 및 11.x만 현재 지원합니다. 클라우드 인스턴스는 현재 지원되지 않습니다.
+ title: 제한된 가져오기 기능
+ description: 이 Jira Migrator는 현재 베타 버전이며 프로젝트, 이슈(이름, 제목, 설명, 첨부 파일), 사용자(이름, 이메일, 프로젝트 멤버십), 상태 및 유형과 같은 기본 데이터만 가져올 수 있습니다. 워크플로, 사용자 지정 필드, 이슈 관계 또는 권한은 가져올 수 없습니다. Jira Server/Data Center 버전 10.x 및 11.x만 현재 지원됩니다. 클라우드 인스턴스는 현재 지원되지 않습니다.
form:
fields:
name: 이름
@@ -154,6 +154,7 @@ ko:
connection_timeout: 'Jira 서버에 연결이 시간 초과되었습니다: %{message}'
parse_error: 'Jira API 응답을 구문 분석하지 못했습니다: %{message}'
api_error: Jira API가 오류 상태 %{status}을(를) 반환했습니다
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: 프로젝트
last_change: 마지막 변경
@@ -162,7 +163,7 @@ ko:
run:
title: 가져오기 실행
history: 기록
- remove_error: Jira 가져오기는 실행되는 동안 제거할 수 없습니다
+ remove_error: 실행되는 동안에는 Jira 가져오기 실행을 제거할 수 없습니다
import_blocked_error: 다른 Jira 가져오기 실행이 현재 진행 중이거나 검토를 기다리는 중입니다. 새 가져오기를 시작하기 전에 완료하거나 되돌리세요.
project_identifier_taken: '이미 사용된 식별자가 있는 프로젝트를 가져오려고 합니다: %{taken_identifier}. Jira에서 프로젝트 식별자를 업데이트한 후에 ''다시 시도''를 클릭하세요.'
blank:
@@ -381,19 +382,23 @@ ko:
notification_text_default: "
안녕하세요,
새 프로젝트가 생성되었습니다: projectValue:name
감사합니다.
\n"
work_packages_identifier:
page_header:
- description: 기본 숫자 작업 패키지 ID 또는 작업 패키지 ID 앞에 프로젝트 식별자를 붙이는 프로젝트별 ID 중에서 선택합니다.
+ description: 클래식 숫자 작업 패키지 ID 또는 작업 패키지 ID 앞에 프로젝트 식별자를 붙이는 프로젝트별 시맨틱 ID 중에서 선택합니다.
banner:
- existing_identifiers_notice: "%{project_count}개 프로젝트의 기존 식별자가 프로젝트 기반 영숫자 식별자에 대한 요구 사항을 충족하지 않습니다. OpenProject는 아래 예와 같이 해당 식별자가 유효하도록 자동으로 업데이트할 수 있습니다. '자동 수정 및 저장'을 클릭하여 이러한 방식으로 모든 프로젝트의 식별자를 업데이트하고 프로젝트 기반 영숫자 식별자를 활성화하세요.\n"
+ existing_identifiers_notice: "%{project_count}개 프로젝트의 기존 식별자가 프로젝트 기반 시맨틱 식별자에 대한 요구 사항을 충족하지 않습니다. OpenProject는 아래 예와 같이 해당 식별자가 유효하도록 자동으로 업데이트할 수 있습니다. '자동 수정 및 저장'을 클릭하여 이러한 방식으로 모든 프로젝트의 식별자를 업데이트하고 프로젝트 기반 시맨틱 식별자를 활성화하세요.\n"
box_header:
label_project: 프로젝트
label_previous_identifier: 이전 식별자
label_autofixed_suggestion: 향후 식별자
label_example_work_package_id: 작업 패키지 ID 예
autofix_preview:
- error_too_long: 5자 미만이어야 합니다
+ error_too_long: 10자 이하여야 함
+ error_numerical: 완전히 숫자로만 지정할 수 없음
+ error_starts_with_number: 숫자로 시작할 수 없음
error_special_characters: 특수 문자는 허용되지 않음
+ error_not_fully_uppercased: 대문자여야 함
error_in_use: 이미 다른 프로젝트의 활성 핸들로 사용 중입니다
error_reserved: 다른 프로젝트의 핸들 기록에 의해 예약되었습니다
+ error_unknown: 수동 검토가 필요합니다
remaining_projects:
other: "... %{count}개의 추가 프로젝트"
button_autofix: 자동 수정 및 저장
@@ -407,7 +412,7 @@ ko:
checkbox_label: 이렇게 하면 모든 작업 패키지 ID가 영구적으로 변경됨을 이해합니다
success_banner: 작업 패키지 식별자 형식을 업데이트했습니다.
in_progress:
- banner_message: 프로젝트 기반 영숫자 식별자로 프로젝트 식별자를 현재 업데이트하는 중입니다. 시간이 다소 걸릴 수 있습니다.
+ banner_message: 프로젝트 기반 시맨틱 식별자로 프로젝트 식별자를 현재 업데이트하는 중입니다. 시간이 다소 걸릴 수 있습니다.
workflows:
tabs:
default_transitions: 기본 전환
@@ -672,6 +677,37 @@ ko:
danger_dialog:
confirmation_live_message_checked: 진행 버튼이 이제 활성화되었습니다.
confirmation_live_message_unchecked: 진행 버튼이 이제 비활성화되었습니다. 계속하려면 확인란을 선택해야 합니다.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: 페이지 매김
prev: 이전
@@ -1322,6 +1358,20 @@ ko:
index:
no_results_title_text: 작업 흐름이 없습니다.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1516,6 +1566,9 @@ ko:
dependencies: 종속성
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: 식별자
+ work_package: 작업 패키지
jira_import:
projects: 프로젝트
import/jira:
@@ -1524,7 +1577,7 @@ ko:
personal_access_token: 개인 액세스 토큰
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira 가져오기
+ jira_import: Jira Migrator
announcements:
show_until: 표시 기한
attachment:
@@ -1780,6 +1833,7 @@ ko:
identity_url: ID URL
parent: 부모 그룹
organizational_unit: 조직 단위
+ group_users: Group users
group_detail:
parent: 부모 그룹
organizational_unit: 조직 단위
@@ -1897,6 +1951,7 @@ ko:
confirmation: "%{attribute} 속성에 부합하지 않습니다."
could_not_be_copied: "%{dependency}을(를) (완전히) 복사할 수 없습니다."
does_not_exist: 존재하지 않음
+ user_already_in_department: User %{user_id} is already a member of department %{department_id}.
error_enterprise_only: "%{action}은(는) OpenProject Enterprise Edition에서만 사용할 수 있습니다."
error_unauthorized: 액세스하지 못할 수 있습니다.
error_readonly: "- 쓰려고 했지만 쓸 수 없습니다."
@@ -1963,6 +2018,7 @@ ko:
attributes:
parent_id:
circular_dependency: "- 순환 그룹 계층을 생성합니다."
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2423,7 +2479,6 @@ ko:
avatar: 아바타
base: '일반 오류:'
body: 본문
- blocks_ids: 차단 된 작업 패키지의 ID
category: 카테고리
comment: 코멘트
comments: 코멘트
@@ -2880,6 +2935,7 @@ ko:
title: Enterprise 추가 기능
plan_title: Enterprise %{plan} 추가 기능
plan_name: "%{plan} Enterprise 플랜"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: "%{plan_name}부터 사용 가능합니다."
unlimited: 무제한
already_have_token: '이미 토큰이 있으신가요? 아래 버튼을 사용하여 토큰을 추가하고 예약한 Enterprise 플랜으로 업그레이드하세요.
@@ -3348,6 +3404,11 @@ ko:
quick_add:
label: 추가…
my_account:
+ notifications_and_email:
+ title: 알림 및 이메일
+ tabs:
+ notifications: 알림 설정
+ email_reminders: 이메일 미리 알림
access_tokens:
description: 공급자 토큰은 OpenProject에서 발급하며, 다른 애플리케이션이 액세스하도록 허용합니다. 클라이언트 토큰은 다른 애플리케이션에서 발급하며, OpenProject가 액세스하도록 허용합니다.
no_results:
@@ -3410,6 +3471,72 @@ ko:
disabled_text: 관리자가 RSS 토큰을 활성화하지 않았습니다. 이 기능을 사용하려면 관리자에게 문의하세요.
storages:
unknown_storage: 알 수 없는 저장소
+ email_reminders:
+ immediate_reminders:
+ title: 이메일 미리 알림 보내기
+ mentioned: 내가 멘션되면 알림 보내기
+ personal_reminder: 개인 미리 알림 보내기
+ daily_reminders:
+ title: 읽지 않은 알림에 대한 일일 이메일 미리 알림 보내기
+ caption: 읽지 않은 알림에 대해서만 그리고 사용자가 지정한 시간에만 이러한 미리 알림이 전송됩니다. 계정의 표준 시간대를 구성할 때까지, 시간은 UTC로 적용됩니다.
+ enabled: 일일 이메일 미리 알림 활성화
+ add_time: 시간 추가
+ remove_time: 시간 제거
+ time_slot_label: 미리 알림 시간(UTC)
+ workdays:
+ title: 해당 요일에 이메일 미리 알림 받기
+ submit_button: 미리 알림 요일 업데이트
+ pause_reminders:
+ title: 이메일 알림 일시 중지
+ enabled: 임시로 일일 이메일 미리 알림 일시 중지
+ date_range: 일시 중지 기간
+ email_alerts:
+ title: 작업 패키지가 아닌 기타 항목에 대한 이메일 알림
+ news_added: 뉴스 추가됨
+ news_commented: 뉴스 항목의 코멘트
+ document_added: 문서 추가됨
+ forum_messages: 포럼 메시지 게시됨
+ wiki_page_added: 위키 페이지 추가됨
+ wiki_page_updated: 위키 페이지 업데이트됨
+ membership_added: 멤버십 추가됨
+ membership_updated: 멤버십 업데이트됨
+ submit_button: 알림 업데이트
+ notifications:
+ participating:
+ title: 참여
+ submit_button: 기본 설정 업데이트
+ mentioned: 멘션됨
+ watched: 지켜보는 중
+ assignee: 담당자
+ responsible: 담당
+ shared: 나와 공유됨
+ date_alerts:
+ title: 날짜 알림
+ submit_button: 날짜 알림 업데이트
+ start_date: 시작 날짜
+ due_date: 완료 날짜
+ overdue: 기한 지남
+ times:
+ same_day: 같은 날
+ one_day_before: 1일 전
+ three_days_before: 3일 전
+ seven_days_before: 7일 전
+ one_day_after: 1일 후
+ three_days_after: 3일 후
+ seven_days_after: 7일 후
+ non_participating:
+ title: 참여하지 않음
+ submit_button: 기본 설정 업데이트
+ work_package_created: 새 작업 패키지
+ work_package_commented: 모든 새로운 코멘트
+ work_package_processed: 모든 상태 변경 사항
+ work_package_prioritized: 모든 우선 순위 변경 사항
+ work_package_scheduled: 모든 날짜 변경 사항
+ project_specific_settings:
+ title: 프로젝트별 알림 설정
+ add_button: 프로젝트별 알림 추가
+ dialog_title: 프로젝트별 알림 추가
+ list_header: 특정 알림이 있는 프로젝트
notifications:
reasons:
assigned: 담당자
@@ -3441,6 +3568,7 @@ ko:
invalid_filter: 잘못된 알림 필터
label_accessibility: 접근성
label_account: 계정
+ label_actions: 작업
label_active: 활성
label_activate_user: 사용자 활성화
label_active_in_new_projects: 새로운 프로젝트에서 활성
@@ -3481,6 +3609,7 @@ ko:
label_ical_access_key_generation_hint: 캘린더 구독 시 자동으로 생성됩니다.
label_ical_access_key_latest: 최신
label_ical_access_key_revoke: 취소
+ label_integrations: 통합
label_add_column: 열 추가
label_applied_status: 적용된 상태
label_archive_project: 프로젝트 아카이브하기
@@ -3731,7 +3860,7 @@ ko:
label_external_links: 외부 링크
label_locale: 언어 및 지역
label_jump_to_a_project: 프로젝트로 이동...
- label_jira_import: Jira 가져오기
+ label_jira_import: Jira Migrator
label_keyword_plural: 키워드
label_language_based: 사용자 언어에 따름
label_last_activity: 마지막 활동
@@ -3769,6 +3898,10 @@ ko:
label_custom_pdf_export_settings: 사용자 지정 PDF 내보내기 설정
label_custom_favicon: 사용자 지정 favicon
label_custom_touch_icon: 사용자 지정 터치 아이콘
+ label_departments: Organization
+ 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).
+
+ '
label_logout: 로그아웃
label_mapping_for: '매핑 대상: %{attribute}'
label_main_menu: 측면 메뉴
@@ -4833,6 +4966,7 @@ ko:
'
setting_app_subtitle: 응용 프로그램 부제목
setting_app_title: 응용 프로그램 제목
+ setting_organization_name: Organization name
setting_attachment_max_size: 첨부 파일 최대 크기
setting_show_work_package_attachments: 기본적으로 파일 탭에 첨부 파일 표시
setting_antivirus_scan_mode: 스캔 모드
@@ -4977,12 +5111,12 @@ ko:
setting_welcome_text: 환영 블록 텍스트
setting_welcome_title: 환영 블록 제목
setting_welcome_on_homescreen: 홈 화면에 환영 블록 표시
- setting_work_packages_identifier_numeric: 인스턴스 전체의 숫자 시퀀스(기본값)
- setting_work_packages_identifier_numeric_caption: '모든 작업 패키지는 1로 시작하는 순차 번호가 있으며, 새로운 패키지마다 순차 번호가 증가합니다. 이 번호는 해당 인스턴스 내에서 고유하므로 작업 패키지가 프로젝트 간에 이동되더라도 동일하게 유지됩니다.
+ setting_work_packages_identifier_classic: 인스턴스 전체의 숫자 시퀀스(기본값)
+ setting_work_packages_identifier_classic_caption: '모든 작업 패키지는 1로 시작하는 순차 번호가 있으며, 새로운 패키지마다 순차 번호가 증가합니다. 이 번호는 해당 인스턴스 내에서 고유하므로 작업 패키지가 프로젝트 간에 이동되더라도 동일하게 유지됩니다.
'
- setting_work_packages_identifier_alphanumeric: 프로젝트 기반 영숫자 식별자
- setting_work_packages_identifier_alphanumeric_caption: '모든 프로젝트에는 작업 패키지 ID 앞에 붙는 고유 식별자가 있습니다. 작업 패키지가 다른 프로젝트로 이동된 경우 새 식별자가 생성되지만 이전 식별자도 계속 작동됩니다.
+ setting_work_packages_identifier_semantic: 프로젝트 기반 시맨틱 식별자
+ setting_work_packages_identifier_semantic_caption: '모든 프로젝트에는 작업 패키지 ID 앞에 붙는 고유 식별자가 있습니다. 작업 패키지가 다른 프로젝트로 이동된 경우 새 식별자가 생성되지만 이전 식별자도 계속 작동됩니다.
'
setting_work_package_list_default_highlighting_mode: 기본 강조 표시 모드
diff --git a/config/locales/crowdin/lt.yml b/config/locales/crowdin/lt.yml
index 87167a5ac92..e6240ff1708 100644
--- a/config/locales/crowdin/lt.yml
+++ b/config/locales/crowdin/lt.yml
@@ -114,7 +114,7 @@ lt:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ lt:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ lt:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ lt:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -399,9 +400,9 @@ lt:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -410,10 +411,14 @@ lt:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -430,7 +435,7 @@ lt:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -697,6 +702,37 @@ lt:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1374,6 +1410,20 @@ lt:
index:
no_results_title_text: Šiuo metu darbo sekų.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1571,6 +1621,9 @@ lt:
dependencies: Priklausomybės
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1579,7 +1632,7 @@ lt:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Rodyti iki
attachment:
@@ -1835,6 +1888,7 @@ lt:
identity_url: Identiteto URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1952,6 +2006,7 @@ lt:
confirmation: nesutampa su %{attribute}.
could_not_be_copied: "%{dependency} negali (pilnai) būti nukopijuota(s)."
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.
@@ -2018,6 +2073,7 @@ lt:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2540,7 +2596,6 @@ lt:
avatar: Nuotrauka
base: 'Bendroji klaida:'
body: Body
- blocks_ids: Blokuotų darbų paketų ID reikšmės
category: Kategorija
comment: Komentaras
comments: Komentaras
@@ -3037,6 +3092,7 @@ lt:
title: Enterprise priedas
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Neribota
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3508,6 +3564,11 @@ lt:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3570,6 +3631,72 @@ lt:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Nežinoma saugykla
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Paskirtas
@@ -3601,6 +3728,7 @@ lt:
invalid_filter: Invalid notification filter
label_accessibility: Prieinamumas
label_account: Paskyra
+ label_actions: Veiksmai
label_active: Aktyvus
label_activate_user: Aktyvus vartotojas
label_active_in_new_projects: Aktyvus naujuose projektuose
@@ -3641,6 +3769,7 @@ lt:
label_ical_access_key_generation_hint: Automatiškai sukurta prenumeruojant kalendorių.
label_ical_access_key_latest: vėliausias
label_ical_access_key_revoke: Atšaukti
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Taikomoji būsena
label_archive_project: Archyvuoti projektą
@@ -3891,7 +4020,7 @@ lt:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Peršokti į projektą...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Raktažodžiai
label_language_based: Paremta vartotojo kalba
label_last_activity: Paskutinė veikla
@@ -3929,6 +4058,10 @@ lt:
label_custom_pdf_export_settings: Savi PDF eksporto nustatymai
label_custom_favicon: Pasirinktinė piktograma
label_custom_touch_icon: Pasirinktinė prisilietimo piktograma
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Atsijungti
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Šoninis meniu
@@ -5007,6 +5140,7 @@ lt:
'
setting_app_subtitle: Programos paantraštė
setting_app_title: Programos pavadinimas
+ setting_organization_name: Organization name
setting_attachment_max_size: Didžiausias prisegamo failo dydis
setting_show_work_package_attachments: Pagal nutylėjimą rodyti priedus failų kortelėje
setting_antivirus_scan_mode: Skenavimo režimas
@@ -5153,12 +5287,12 @@ lt:
setting_welcome_text: Pasisveikinimo bloko tekstas
setting_welcome_title: Pasisveikinimo bloko pavadinimas
setting_welcome_on_homescreen: Rodyti pasisveikinimo bloką namų lange
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Numatytasis paryškinimo būdas
diff --git a/config/locales/crowdin/lv.yml b/config/locales/crowdin/lv.yml
index f9cbd4abdeb..5000c09b4ea 100644
--- a/config/locales/crowdin/lv.yml
+++ b/config/locales/crowdin/lv.yml
@@ -114,7 +114,7 @@ lv:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ lv:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ lv:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ lv:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -393,9 +394,9 @@ lv:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -404,10 +405,14 @@ lv:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
zero: "... %{count} more projects"
one: "... 1 more project"
@@ -423,7 +428,7 @@ lv:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -690,6 +695,37 @@ lv:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1358,6 +1394,20 @@ lv:
index:
no_results_title_text: Pašlaik nav neviena darbuplūsma.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1554,6 +1604,9 @@ lv:
dependencies: Saistītie projekti
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1562,7 +1615,7 @@ lv:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1818,6 +1871,7 @@ lv:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1935,6 +1989,7 @@ lv:
confirmation: neatbilst %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2001,6 +2056,7 @@ lv:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2503,7 +2559,6 @@ lv:
avatar: Avatārs
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Sadaļa
comment: Komentârs
comments: Komentârs
@@ -2980,6 +3035,7 @@ lv:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3450,6 +3506,11 @@ lv:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3512,6 +3573,72 @@ lv:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Pašreizējais atbildīgais
@@ -3543,6 +3670,7 @@ lv:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Konts
+ label_actions: Actions
label_active: Aktīvs
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3583,6 +3711,7 @@ lv:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3833,7 +3962,7 @@ lv:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Pēdējā aktivitāte
@@ -3871,6 +4000,10 @@ lv:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Izrakstīties
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sānu izvēlne
@@ -4948,6 +5081,7 @@ lv:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5094,12 +5228,12 @@ lv:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/mn.yml b/config/locales/crowdin/mn.yml
index d6b5e7ab996..07a26d93042 100644
--- a/config/locales/crowdin/mn.yml
+++ b/config/locales/crowdin/mn.yml
@@ -114,7 +114,7 @@ mn:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ mn:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ mn:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ mn:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ mn:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ mn:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ mn:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ mn:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ mn:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ mn:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ mn:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ mn:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ mn:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ mn:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ mn:
avatar: Аватар
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ mn:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ mn:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ mn:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Даалгагч
@@ -3484,6 +3611,7 @@ mn:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ mn:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ mn:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ mn:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ mn:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ mn:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/ms.yml b/config/locales/crowdin/ms.yml
index e7b986d491f..ed099d1511c 100644
--- a/config/locales/crowdin/ms.yml
+++ b/config/locales/crowdin/ms.yml
@@ -114,7 +114,7 @@ ms:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ms:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ms:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ms:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -381,9 +382,9 @@ ms:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ ms:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ ms:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -674,6 +679,37 @@ ms:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1322,6 +1358,20 @@ ms:
index:
no_results_title_text: Tiada aliran kerja buat masa ini.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1516,6 +1566,9 @@ ms:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1524,7 +1577,7 @@ ms:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Paparkan sehingga
attachment:
@@ -1782,6 +1835,7 @@ ms:
identity_url: Identiti URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1899,6 +1953,7 @@ ms:
confirmation: tidak sepadan dengan %{attribute}.
could_not_be_copied: "%{dependency} tidak dapat disalin (sepenuhnya)."
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.
@@ -1965,6 +2020,7 @@ ms:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2429,7 +2485,6 @@ ms:
avatar: Avatar
base: 'Ralat Umum:'
body: Body
- blocks_ids: ID pakej kerja yang disekat
category: Kategori
comment: Komen
comments: Komen
@@ -2870,6 +2925,7 @@ ms:
title: Alat tambah perusahaan
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Tiada had
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3340,6 +3396,11 @@ ms:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3402,6 +3463,72 @@ ms:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Storan tidak dikenal pasti
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Penerima tugasan
@@ -3433,6 +3560,7 @@ ms:
invalid_filter: Invalid notification filter
label_accessibility: Kebolehcapaian
label_account: Akaun
+ label_actions: Tindakan
label_active: Aktif
label_activate_user: Aktifkan pengguna
label_active_in_new_projects: Aktifkan dalam projek baharu
@@ -3473,6 +3601,7 @@ ms:
label_ical_access_key_generation_hint: Dijanakan secara automatik apabila melanggan kalendar.
label_ical_access_key_latest: terkini
label_ical_access_key_revoke: Batalkan
+ label_integrations: Integrations
label_add_column: Tambah lajur
label_applied_status: Status yang dilaksanakan
label_archive_project: Arkib projek
@@ -3725,7 +3854,7 @@ ms:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Lompat ke projek...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Kata kunci
label_language_based: Berdasarkan bahasa pengguna
label_last_activity: Aktiviti terakhir
@@ -3763,6 +3892,10 @@ ms:
label_custom_pdf_export_settings: Tetapan eksport PDF tersuai
label_custom_favicon: Favicon tersuai
label_custom_touch_icon: Ikon sentuh tersuai
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Daftar keluar
label_mapping_for: 'Pemetaan untuk: %{attribute}'
label_main_menu: Menu Sampingan
@@ -4830,6 +4963,7 @@ ms:
'
setting_app_subtitle: Subtajuk aplikasi
setting_app_title: Tajuk aplikasi
+ setting_organization_name: Organization name
setting_attachment_max_size: Saiz maksimum lampiran
setting_show_work_package_attachments: Paparkan lampiran di tab fail secara default
setting_antivirus_scan_mode: Mod pengimbas
@@ -4976,12 +5110,12 @@ ms:
setting_welcome_text: Teks blok selamat datang
setting_welcome_title: Tajuk blok selamat datang
setting_welcome_on_homescreen: Paparkan blok selamat datang di skrin utama
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Mod penyorotan default
diff --git a/config/locales/crowdin/ne.yml b/config/locales/crowdin/ne.yml
index d97f76fdf04..b7b14fec901 100644
--- a/config/locales/crowdin/ne.yml
+++ b/config/locales/crowdin/ne.yml
@@ -114,7 +114,7 @@ ne:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ne:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ne:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ne:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ ne:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ ne:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ ne:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ ne:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ ne:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ ne:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ ne:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ ne:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ ne:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ ne:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ ne:
avatar: 'अवतार '
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ ne:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ ne:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ ne:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ ne:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: खाता
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ ne:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: रद्द गर्नुहोस्
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ ne:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: शब्दकुञ्जी
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ ne:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ ne:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ ne:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/nl.yml b/config/locales/crowdin/nl.yml
index e2640f523fb..9cafe9b0d07 100644
--- a/config/locales/crowdin/nl.yml
+++ b/config/locales/crowdin/nl.yml
@@ -114,7 +114,7 @@ nl:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ nl:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ nl:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ nl:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ nl:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ nl:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ nl:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -680,6 +685,37 @@ nl:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1339,6 +1375,20 @@ nl:
index:
no_results_title_text: Er zijn momenteel geen workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1534,6 +1584,9 @@ nl:
dependencies: Afhankelijkheden
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1542,7 +1595,7 @@ nl:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Toon tot
attachment:
@@ -1798,6 +1851,7 @@ nl:
identity_url: Identiteit URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1915,6 +1969,7 @@ nl:
confirmation: komt niet overeen met %{attribute}.
could_not_be_copied: "%{dependency} kon niet (volledig) worden gekopieerd."
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.
@@ -1981,6 +2036,7 @@ nl:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2461,7 +2517,6 @@ nl:
avatar: Avatar
base: 'Algemene fout:'
body: Body
- blocks_ids: It's van geblokkeerde werkpakketten
category: Categorie
comment: Reactie
comments: Commentaar
@@ -2918,6 +2973,7 @@ nl:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Onbeperkt
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3387,6 +3443,11 @@ nl:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3449,6 +3510,72 @@ nl:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Onbekende opslag
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Toegewezene
@@ -3480,6 +3607,7 @@ nl:
invalid_filter: Invalid notification filter
label_accessibility: Toegankelijkheid
label_account: Account
+ label_actions: Acties
label_active: Actief
label_activate_user: Gebruiker activeren
label_active_in_new_projects: Actief in nieuwe projecten
@@ -3520,6 +3648,7 @@ nl:
label_ical_access_key_generation_hint: Automatisch gegenereerd bij het abonneren op een kalender.
label_ical_access_key_latest: laatste
label_ical_access_key_revoke: Intrekken
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Toegepaste status
label_archive_project: Project archiveren
@@ -3770,7 +3899,7 @@ nl:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Ga naar een project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Trefwoorden
label_language_based: Op basis van de taal van gebruiker
label_last_activity: Laatste activiteit
@@ -3808,6 +3937,10 @@ nl:
label_custom_pdf_export_settings: Aangepaste PDF-exportinstellingen
label_custom_favicon: Aangepaste favicon
label_custom_touch_icon: Aangepaste touch-pictogram
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Afmelden
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Submenu
@@ -4870,6 +5003,7 @@ nl:
'
setting_app_subtitle: Applicatie ondertitel
setting_app_title: Toepassingsnaam
+ setting_organization_name: Organization name
setting_attachment_max_size: Bijlage max. grootte
setting_show_work_package_attachments: Bijlagen standaard in het tabblad bestanden weergeven
setting_antivirus_scan_mode: Scanmodus
@@ -5016,12 +5150,12 @@ nl:
setting_welcome_text: Welkom blok tekst
setting_welcome_title: Welkom blok titel
setting_welcome_on_homescreen: Toon het Welkom blok op thuisscherm
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Standaardmodus markeren
diff --git a/config/locales/crowdin/no.yml b/config/locales/crowdin/no.yml
index d38d57f689f..927eafc0458 100644
--- a/config/locales/crowdin/no.yml
+++ b/config/locales/crowdin/no.yml
@@ -114,7 +114,7 @@
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1339,6 +1375,20 @@
index:
no_results_title_text: Det er ingen arbeidsflyt for øyeblikket.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1534,6 +1584,9 @@
dependencies: Avhengigheter
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1542,7 +1595,7 @@
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Vise til
attachment:
@@ -1798,6 +1851,7 @@
identity_url: Identitet URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1915,6 +1969,7 @@
confirmation: samsvarer ikke med %{attribute}.
could_not_be_copied: "%{dependency} kunne ikke kopieres (fullstendig)."
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
@@ -1981,6 +2036,7 @@
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2463,7 +2519,6 @@
avatar: Profilbilde
base: 'Generell feil:'
body: Body
- blocks_ids: IDer for blokkerte arbeidspakker
category: Kategori
comment: Kommentar
comments: Kommentar
@@ -2920,6 +2975,7 @@
title: Enterprise programtillegg
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Ubegrenset
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3389,6 +3445,11 @@
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3451,6 +3512,72 @@
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Ukjent lagring
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Deltaker
@@ -3482,6 +3609,7 @@
invalid_filter: Invalid notification filter
label_accessibility: Tilgjengelighet
label_account: Konto
+ label_actions: Handlinger
label_active: Aktiv
label_activate_user: Aktiver bruker
label_active_in_new_projects: Aktiv i nye prosjekter
@@ -3522,6 +3650,7 @@
label_ical_access_key_generation_hint: Automatisk generert ved abonnering på en kalender.
label_ical_access_key_latest: siste
label_ical_access_key_revoke: Tilbakekall
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Tildelt status
label_archive_project: Arkiver prosjekt
@@ -3772,7 +3901,7 @@
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Gå til et prosjekt...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Nøkkelord
label_language_based: Basert på brukerens språk
label_last_activity: Siste aktivitet
@@ -3810,6 +3939,10 @@
label_custom_pdf_export_settings: Egendefinerte PDF eksportinnstillinger
label_custom_favicon: Tilpasset favicon
label_custom_touch_icon: Egendefinert berøringsikon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Logg av
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sidemeny
@@ -4882,6 +5015,7 @@
'
setting_app_subtitle: Undertittel for applikasjon
setting_app_title: Applikasjonsnavn
+ setting_organization_name: Organization name
setting_attachment_max_size: Maksstørrelse for vedlegg
setting_show_work_package_attachments: Vis vedlegg i fil-fanen som standard
setting_antivirus_scan_mode: Skannemodus
@@ -5028,12 +5162,12 @@
setting_welcome_text: Velkommen blokktekst
setting_welcome_title: Velkomst blokk tittel
setting_welcome_on_homescreen: Vis velkomstblokk på hjemskjermen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Standard utheving modus
diff --git a/config/locales/crowdin/pl.yml b/config/locales/crowdin/pl.yml
index 22913448bf3..405ff235df8 100644
--- a/config/locales/crowdin/pl.yml
+++ b/config/locales/crowdin/pl.yml
@@ -114,7 +114,7 @@ pl:
import:
title: Import
jira:
- title: Import Jira
+ title: Migrator Jira
description: To narzędzie służy do importowania danych z wystąpienia usługi Jira. Można skonfigurować wiele hostów usługi Jira i wybrać, co ma być importowane w każdym przebiegu importu.
errors:
cannot_delete_with_imports: Nie można usunąć hosta Jira z istniejącym importem
@@ -125,8 +125,8 @@ pl:
title: Konfiguracja usługi Jira
new: Nowa konfiguracja
banner:
- title: Ograniczony import
- description: 'To narzędzie importu jest obecnie w wersji beta i może importować tylko podstawowe dane: projekty, zgłoszenia problemów (nazwa, tytuł, opis, załączniki), użytkowników (nazwa, adres e-mail, członkostwo w projekcie), statusy i typy. Nie może importować przepływów pracy, pól niestandardowych, relacji między problemami ani uprawnień. Obecnie obsługujemy tylko serwery / centra danych Jira w wersjach 10.x i 11.x. Wystąpienia w chmurze nie są obecnie obsługiwane.'
+ title: Ograniczone możliwości importu
+ description: 'Ten migrator Jira jest obecnie w wersji beta i może importować tylko podstawowe dane: projekty, zgłoszenia problemów (nazwa, tytuł, opis, załączniki), użytkowników (nazwa, adres e-mail, członkostwo w projekcie), statusy i typy. Nie może importować przepływów pracy, pól niestandardowych, relacji między problemami ani uprawnień. Obecnie obsługujemy tylko serwery / centra danych Jira w wersjach 10.x i 11.x. Wystąpienia w chmurze nie są obecnie obsługiwane.'
form:
fields:
name: Nazwa
@@ -154,6 +154,7 @@ pl:
connection_timeout: 'Upłynął limit czasu połączenia z serwerem Jira: %{message}'
parse_error: 'Nie udało się przeanalizować odpowiedzi interfejsu API usługi Jira: %{message}'
api_error: Interfejs API usługi Jira zwrócił status błędu %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projekty
last_change: Ostatnia zmiana
@@ -399,9 +400,9 @@ pl:
notification_text_default: "
Witaj,
Utworzono nowy projekt: projectValue:name
Dziękujemy
\n"
work_packages_identifier:
page_header:
- description: Wybierz między podstawowymi identyfikatorami liczbowymi pakietów roboczych a identyfikatorami specyficznymi dla projektu, które dodają identyfikator projektu jako prefiks do identyfikatora pakietu roboczego.
+ description: Wybierz pomiędzy klasycznymi numerycznymi identyfikatorami pakietów roboczych albo semantycznymi identyfikatorami specyficznymi dla projektu, które dodają identyfikator projektu do identyfikatora pakietu roboczego.
banner:
- existing_identifiers_notice: 'Istniejące identyfikatory %{project_count} projektów nie spełniają wymagań dotyczących identyfikatorów alfanumerycznych opartych na projektach. OpenProject może automatycznie zaktualizować je tak, aby były prawidłowe, jak w poniższych przykładach. Kliknij przycisk „Automatyczne napraw i zapisz”, aby zaktualizować identyfikatory wszystkich projektów w ten sposób i włączyć identyfikatory alfanumeryczne oparte na projektach.
+ existing_identifiers_notice: 'Istniejące identyfikatory %{project_count} projektów nie spełniają wymagań dotyczących identyfikatorów semantycznych opartych na projektach. OpenProject może automatycznie zaktualizować je tak, aby były prawidłowe, jak w poniższych przykładach. Kliknij przycisk „Automatyczne napraw i zapisz”, aby zaktualizować identyfikatory wszystkich projektów w ten sposób i włączyć identyfikatory semantyczne oparte na projektach.
'
box_header:
@@ -410,10 +411,14 @@ pl:
label_autofixed_suggestion: Przyszły identyfikator
label_example_work_package_id: Przykładowy identyfikator pakietu roboczego
autofix_preview:
- error_too_long: Musi składać się z mniej niż 5 znaków
+ error_too_long: Musi składać się z nie więcej niż 10 znaków
+ error_numerical: Nie może być czysto liczbowy
+ error_starts_with_number: Nie może zaczynać się od cyfry
error_special_characters: Znaki specjalne są niedozwolone
+ error_not_fully_uppercased: Musi być pisany wielkimi literami
error_in_use: Już używany jako aktywne dojście innego projektu
error_reserved: Zarezerwowany przez historię dojść innego projektu
+ error_unknown: Wymaga ręcznego sprawdzenia
remaining_projects:
one: "...jeszcze 1 projekt"
few: "...jeszcze %{count} projekty"
@@ -430,7 +435,7 @@ pl:
checkbox_label: Rozumiem, że spowoduje to trwałą zmianę wszystkich identyfikatorów pakietów roboczych
success_banner: Pomyślnie zaktualizowano format identyfikatora pakietu roboczego.
in_progress:
- banner_message: Identyfikatory projektów są obecnie zmieniane na identyfikatory alfanumeryczne oparte na projektach. Może to zająć trochę czasu.
+ banner_message: Identyfikatory projektów są obecnie zmieniane na identyfikatory semantyczne oparte na projektach. Może to zająć trochę czasu.
workflows:
tabs:
default_transitions: Przejścia domyślne
@@ -697,6 +702,37 @@ pl:
danger_dialog:
confirmation_live_message_checked: Przycisk kontynuowania jest już aktywny.
confirmation_live_message_unchecked: Przycisk kontynuowania jest teraz nieaktywny. Aby kontynuować, zaznacz pole wyboru.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginacja
prev: Wstecz
@@ -1373,6 +1409,20 @@ pl:
index:
no_results_title_text: Nie ma jeszcze żadnego obiegu pracy.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1568,6 +1618,9 @@ pl:
dependencies: Zależności
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identyfikator
+ work_package: Pakiet roboczy
jira_import:
projects: Projekty
import/jira:
@@ -1576,7 +1629,7 @@ pl:
personal_access_token: Osobisty token dostępu
import/jira_open_project_reference:
jira: Jira
- jira_import: Import Jira
+ jira_import: Migrator Jira
announcements:
show_until: Wyświetlaj do
attachment:
@@ -1832,6 +1885,7 @@ pl:
identity_url: Adres URL tożsamości
parent: Grupa nadrzędna
organizational_unit: Jednostka organizacyjna
+ group_users: Group users
group_detail:
parent: Grupa nadrzędna
organizational_unit: Jednostka organizacyjna
@@ -1949,6 +2003,7 @@ pl:
confirmation: nie pasuje do %{attribute}.
could_not_be_copied: Nie można było (w pełni) skopiować %{dependency}.
does_not_exist: nie istnieje.
+ user_already_in_department: User %{user_id} is already a member of department %{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."
@@ -2015,6 +2070,7 @@ pl:
attributes:
parent_id:
circular_dependency: spowodowałoby utworzenie cyklicznej hierarchii grup.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2535,7 +2591,6 @@ pl:
avatar: Awatar
base: 'Błąd ogólny:'
body: Treść
- blocks_ids: Identyfikatory zablokowanych pakietów roboczych
category: Kategoria
comment: Typ kosztu
comments: Komentarz
@@ -3032,6 +3087,7 @@ pl:
title: Dodatek wersji Enterprise
plan_title: Dodatek do planu Enterprise %{plan}
plan_name: Plan Enterprise %{plan}
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Dostępne od wersji %{plan_name}.
unlimited: Bez ograniczeń
already_have_token: 'Masz już token? Dodaj go za pomocą poniższego przycisku, aby przejść na zarezerwowany plan Enterprise.
@@ -3501,6 +3557,11 @@ pl:
quick_add:
label: Dodaj…
my_account:
+ notifications_and_email:
+ title: Powiadomienia i wiadomości e-mail
+ tabs:
+ notifications: Ustawienia powiadomień
+ email_reminders: Przypomnienia e-mail
access_tokens:
description: Tokeny dostawcy są wydawane przez OpenProject, co umożliwia dostęp do nich innym aplikacjom. Tokeny klienta są wydawane przez inne aplikacje, co umożliwia dostęp do nich oprogramowaniu OpenProject.
no_results:
@@ -3563,6 +3624,72 @@ pl:
disabled_text: Tokeny RSS nie zostały włączone przez administratora. Aby użyć tej funkcji, skontaktuj się z administratorem.
storages:
unknown_storage: Nieznany magazyn
+ email_reminders:
+ immediate_reminders:
+ title: Wyślij mi przypomnienie e-mail
+ mentioned: Powiadamiaj mnie, gdy ktoś mnie wspomni
+ personal_reminder: Powiadamiaj mnie o osobistych przypomnieniach
+ daily_reminders:
+ title: Wyślij mi codzienne przypomnienia e-mail dla nieprzeczytanych powiadomień
+ caption: Będziesz otrzymywać te przypomnienia tylko w przypadku nieprzeczytanych powiadomień i tylko w określonych przez Ciebie godzinach. Dopóki nie skonfigurujesz strefy czasowej dla swojego konta, godziny będą interpretowane jako UTC.
+ enabled: Włącz codzienne przypomnienia e-mail
+ add_time: Dodaj godzinę
+ remove_time: Usuń godzinę
+ time_slot_label: Czas przypomnienia (UTC)
+ workdays:
+ title: Otrzymuj przypomnienia e-mail w tych dniach
+ submit_button: Zaktualizuj dni przypomnienia
+ pause_reminders:
+ title: Wstrzymaj powiadomienia e-mail
+ enabled: Tymczasowo wstrzymuj codzienne przypomnienia e-mail
+ date_range: Okres wstrzymania
+ email_alerts:
+ title: Powiadomienia e-mail dotyczące innych elementów, które nie są pakietami roboczymi
+ news_added: Wiadomość dodana
+ news_commented: Komentarz do nowości
+ document_added: Dodano dokument
+ forum_messages: Wiadomość na forum
+ wiki_page_added: Dodano stronę wiki
+ wiki_page_updated: Zaktualizowano stronę wiki
+ membership_added: Dodanie członkostwa
+ membership_updated: Aktualizacja członkostwa
+ submit_button: Zaktualizuj alerty
+ notifications:
+ participating:
+ title: Uczestnictwo
+ submit_button: Zaktualizuj preferencje
+ mentioned: Wzmianka
+ watched: Obserwowane
+ assignee: Przypisana osoba
+ responsible: Osoba odpowiedzialna
+ shared: Udostępnione dla mnie
+ date_alerts:
+ title: Alerty dotyczące dat
+ submit_button: Zaktualizuj alerty dotyczące dat
+ start_date: Data rozpoczęcia
+ due_date: Data zakończenia
+ overdue: Przekroczony termin
+ times:
+ same_day: Tego samego dnia
+ one_day_before: 1 dzień przed
+ three_days_before: 3 dni przed
+ seven_days_before: 7 dni przed
+ one_day_after: 1 dzień po
+ three_days_after: 3 dni po
+ seven_days_after: 7 dni po
+ non_participating:
+ title: Brak uczestnictwa
+ submit_button: Zaktualizuj preferencje
+ work_package_created: Nowe pakiety robocze
+ work_package_commented: Wszystkie nowe komentarze
+ work_package_processed: Wszystkie zmiany statusu
+ work_package_prioritized: Wszystkie zmiany priorytetów
+ work_package_scheduled: Wszystkie zmiany daty
+ project_specific_settings:
+ title: Ustawienia powiadomień dla danego projektu
+ add_button: Dodaj powiadomienia specyficzne dla projektu
+ dialog_title: Dodaj powiadomienia specyficzne dla projektu
+ list_header: Projekty z określonymi powiadomieniami
notifications:
reasons:
assigned: Przypisana osoba
@@ -3594,6 +3721,7 @@ pl:
invalid_filter: Nieprawidłowy filtr powiadomień
label_accessibility: Dostępność
label_account: Konto
+ label_actions: Działania
label_active: Aktywne
label_activate_user: Aktywuj użytkownika
label_active_in_new_projects: Aktywne w nowych projektach
@@ -3634,6 +3762,7 @@ pl:
label_ical_access_key_generation_hint: Automatycznie wygenerowano podczas subskrypcji kalendarza.
label_ical_access_key_latest: najnowszy
label_ical_access_key_revoke: Odwołaj
+ label_integrations: Integracje
label_add_column: Dodaj kolumnę
label_applied_status: Nadaj status
label_archive_project: Archiwum projektów
@@ -3884,7 +4013,7 @@ pl:
label_external_links: Linki zewnętrzne
label_locale: Język i region
label_jump_to_a_project: Skok do projektu...
- label_jira_import: Import Jira
+ label_jira_import: Migrator Jira
label_keyword_plural: Słowa kluczowe
label_language_based: Na podstawie języka użytkownika
label_last_activity: Ostatnia aktywność
@@ -3922,6 +4051,10 @@ pl:
label_custom_pdf_export_settings: Niestandardowe ustawienia eksportu w formacie PDF
label_custom_favicon: Własny favicon
label_custom_touch_icon: Własny touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Wyloguj
label_mapping_for: 'Mapowanie dla: %{attribute}'
label_main_menu: Menu boczne
@@ -4996,6 +5129,7 @@ pl:
'
setting_app_subtitle: Podtytuł
setting_app_title: Tytuł
+ setting_organization_name: Organization name
setting_attachment_max_size: Maks. rozmiar załącznika
setting_show_work_package_attachments: Domyślnie pokazuj załączniki na karcie plików
setting_antivirus_scan_mode: Tryb skanowania
@@ -5142,12 +5276,12 @@ pl:
setting_welcome_text: Tekst bloku powitalnego
setting_welcome_title: Tytuł bloku powitalnego
setting_welcome_on_homescreen: Wyświetl wiadomość powitalną na ekranie głównym
- setting_work_packages_identifier_numeric: Sekwencja liczbowa dla całego wystąpienia (domyślnie)
- setting_work_packages_identifier_numeric_caption: 'Każdy pakiet roboczy otrzymuje numer kolejny zaczynający się od 1 i zwiększany z każdym nowym pakietem. Numery są unikalne w ramach tego wystąpienia, więc pozostają takie same, nawet jeśli pakiety robocze są przenoszone między projektami.
+ setting_work_packages_identifier_classic: Sekwencja liczbowa dla całego wystąpienia (domyślnie)
+ setting_work_packages_identifier_classic_caption: 'Każdy pakiet roboczy otrzymuje numer kolejny zaczynający się od 1 i zwiększany z każdym nowym pakietem. Numery są unikalne w ramach tego wystąpienia, więc pozostają takie same, nawet jeśli pakiety robocze są przenoszone między projektami.
'
- setting_work_packages_identifier_alphanumeric: Identyfikatory alfanumeryczne oparte na projektach
- setting_work_packages_identifier_alphanumeric_caption: 'Każdy projekt ma unikalny identyfikator, który jest poprzedzony identyfikatorem pakietu roboczego. Jeśli pakiet roboczy zostanie przeniesiony do innego projektu, generowany jest nowy identyfikator, ale stary nadal działa.
+ setting_work_packages_identifier_semantic: Identyfikatory semantyczne oparte na projektach
+ setting_work_packages_identifier_semantic_caption: 'Każdy projekt ma unikalny identyfikator, który jest poprzedzony identyfikatorem pakietu roboczego. Jeśli pakiet roboczy zostanie przeniesiony do innego projektu, generowany jest nowy identyfikator, ale stary nadal działa.
'
setting_work_package_list_default_highlighting_mode: Domyślny tryb wyróżniania
diff --git a/config/locales/crowdin/pt-BR.yml b/config/locales/crowdin/pt-BR.yml
index 871ae418944..175caf00f3e 100644
--- a/config/locales/crowdin/pt-BR.yml
+++ b/config/locales/crowdin/pt-BR.yml
@@ -114,7 +114,7 @@ pt-BR:
import:
title: Importar
jira:
- title: Importação do Jira
+ title: Migrador do Jira
description: Use esta ferramenta para importar dados da sua instância do Jira. Você pode configurar vários hosts do Jira e escolher o que importar em cada execução de importação.
errors:
cannot_delete_with_imports: Não é possível excluir o host do Jira enquanto houver importações existentes
@@ -125,8 +125,8 @@ pt-BR:
title: Configuração do Jira
new: Nova configuração
banner:
- title: Importação limitada
- description: 'Esta ferramenta de importação está atualmente em versão beta e só consegue importar dados básicos: projetos, tarefas (nome, título, descrição, anexos), usuários (nome, e-mail, participação em projetos), status e tipos. Não é possível importar fluxos de trabalho, campos personalizados, relações entre tarefas ou permissões. No momento, só damos suporte às versões 10.x e 11.x do Jira Server/Data Center. Instâncias Cloud não possuem suporte.'
+ title: Capacidades de importação limitadas
+ description: 'Este Migrador do Jira está atualmente em versão beta e só consegue importar dados básicos: projetos, chamados (nome, título, descrição, anexos), usuários (nome, e-mail, participação em projetos), status e tipos. Ele não consegue importar fluxos de trabalho, campos personalizados, relações entre chamados ou permissões. No momento, só são suportadas as versões Jira Server/Data Center 10.x e 11.x. Instâncias na nuvem (Cloud) não são compatíveis atualmente.'
form:
fields:
name: Nome
@@ -154,6 +154,7 @@ pt-BR:
connection_timeout: 'O tempo de conexão com o servidor Jira esgotou: %{message}'
parse_error: 'Falha ao analisar a resposta da API do Jira: %{message}'
api_error: A API do Jira retornou o status de erro %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projetos
last_change: Última alteração
@@ -387,9 +388,9 @@ pt-BR:
notification_text_default: "
Olá,
Um novo projeto foi criado: projectValue:name
Obrigado
\n"
work_packages_identifier:
page_header:
- description: Escolha entre IDs de pacotes de trabalho numéricos básicos ou IDs específicos do projeto, que adicionam o identificador do projeto ao ID do pacote de trabalho.
+ description: Escolha entre IDs de pacotes de trabalho numéricos clássicos ou IDs semânticos específicos do projeto, que adicionam o identificador do projeto ao ID do pacote de trabalho.
banner:
- existing_identifiers_notice: 'Os identificadores existentes de %{project_count} projetos não atendem aos requisitos para identificadores alfanuméricos baseados em projeto. O OpenProject pode atualizá-los automaticamente para que fiquem válidos, como nos exemplos abaixo. Clique em “Autocorrigir e salvar” para atualizar os identificadores de todos os projetos dessa forma e ativar os Ids alfanuméricos baseados em projeto.
+ existing_identifiers_notice: 'Os identificadores existentes de %{project_count} projetos não atendem aos requisitos para Ids semânticos baseados em projeto. O OpenProject pode atualizá-los automaticamente para que fiquem válidos, como nos exemplos abaixo. Clique em “Autocorrigir e salvar” para atualizar os identificadores de todos os projetos dessa forma e ativar os Ids semânticos baseados em projeto.
'
box_header:
@@ -398,10 +399,14 @@ pt-BR:
label_autofixed_suggestion: Identificador futuro
label_example_work_package_id: Exemplo de ID de pacote de trabalho
autofix_preview:
- error_too_long: Deve ter menos de 5 caracteres
+ error_too_long: Deve conter no máximo 10 caracteres
+ error_numerical: Não pode ser exclusivamente numérico
+ error_starts_with_number: Não pode começar com um número
error_special_characters: Caracteres especiais não são permitidos
+ error_not_fully_uppercased: Deve estar em maiúsculas
error_in_use: Já está em uso como identificador ativo de outro projeto
error_reserved: Reservado pelo histórico de identificadores de outro projeto
+ error_unknown: Requer revisão manual
remaining_projects:
one: "… mais 1 projeto"
other: "… mais %{count} projetos"
@@ -416,7 +421,7 @@ pt-BR:
checkbox_label: Estou ciente de que isso alterará permanentemente todos os IDs dos pacotes de trabalho
success_banner: Formato de identificador de pacote de trabalho atualizado com sucesso.
in_progress:
- banner_message: Os identificadores dos projetos estão sendo atualizados para identificadores alfanuméricos baseados em projeto. Isso pode levar algum tempo.
+ banner_message: Os identificadores dos projetos estão sendo atualizados para identificadores semânticos baseados em projeto. Isso pode levar algum tempo.
workflows:
tabs:
default_transitions: Transições padrão
@@ -682,6 +687,37 @@ pt-BR:
danger_dialog:
confirmation_live_message_checked: O botão para prosseguir agora está ativo.
confirmation_live_message_unchecked: O botão para prosseguir está desativado. É necessário marcar a caixa de seleção para continuar.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginação
prev: Anterior
@@ -1338,6 +1374,20 @@ pt-BR:
index:
no_results_title_text: Atualmente, não há fluxos de trabalho.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1533,6 +1583,9 @@ pt-BR:
dependencies: Dependências
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identificador
+ work_package: Pacote de trabalho
jira_import:
projects: Projetos
import/jira:
@@ -1541,7 +1594,7 @@ pt-BR:
personal_access_token: Token de acesso de pessoal
import/jira_open_project_reference:
jira: Jira
- jira_import: Importação do Jira
+ jira_import: Migrador do Jira
announcements:
show_until: Exibir até
attachment:
@@ -1797,6 +1850,7 @@ pt-BR:
identity_url: URL de identidade
parent: Grupo principal
organizational_unit: Unidade organizacional
+ group_users: Group users
group_detail:
parent: Grupo principal
organizational_unit: Unidade organizacional
@@ -1914,6 +1968,7 @@ pt-BR:
confirmation: não coincide com %{attribute}.
could_not_be_copied: "%{dependency} não pôde ser copiado (completamente)."
does_not_exist: não existe.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1980,6 +2035,7 @@ pt-BR:
attributes:
parent_id:
circular_dependency: criaria uma hierarquia circular de grupos.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2462,7 +2518,6 @@ pt-BR:
avatar: Avatar
base: 'Erro geral:'
body: Mensagem
- blocks_ids: IDs dos pacotes de trabalho bloqueados
category: Categoria
comment: Comentário
comments: Comentário
@@ -2919,6 +2974,7 @@ pt-BR:
title: Complemento empresarial
plan_title: Complemento do %{plan} Enterprise
plan_name: Plano enterprise %{plan}
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Disponível a partir do %{plan_name}.
unlimited: Ilimitado
already_have_token: 'Já possui um token? Adicione-o usando o botão abaixo para fazer o "upgrade" para o plano Enterprise.
@@ -3388,6 +3444,11 @@ pt-BR:
quick_add:
label: Adicionar…
my_account:
+ notifications_and_email:
+ title: Notificação e e-mail
+ tabs:
+ notifications: Configurações de notificação
+ email_reminders: Lembretes por e-mail
access_tokens:
description: Tokens de provedor são emitidos pelo OpenProject, permitindo que outros aplicativos tenham acesso a ele. Tokens de cliente são emitidos por outros aplicativos, permitindo que o OpenProject tenha acesso a eles.
no_results:
@@ -3450,6 +3511,72 @@ pt-BR:
disabled_text: Tokens RSS não estão habilitados pelo administrador. Entre em contato com ele para usar este recurso.
storages:
unknown_storage: Armazenamento desconhecido
+ email_reminders:
+ immediate_reminders:
+ title: Envie-me um lembrete por e-mail
+ mentioned: Avise-me quando eu for mencionado
+ personal_reminder: Notificar-me sobre lembretes pessoais
+ daily_reminders:
+ title: Enviar lembretes diários por e-mail para notificações não lidas
+ caption: Você receberá esses lembretes apenas para notificações não lidas e somente nos horários que você especificar. Até que você configure um fuso horário para sua conta, os horários serão interpretados como UTC.
+ enabled: Ativar lembretes diários por e-mail
+ add_time: Adicionar horário
+ remove_time: Remover horário
+ time_slot_label: Horário do lembrete (UTC)
+ workdays:
+ title: Receber lembretes por e-mail nestes dias
+ submit_button: Atualizar dias do lembrete
+ pause_reminders:
+ title: Pausar notificações por e-mail
+ enabled: Pausar temporariamente os lembretes diários por e-mail
+ date_range: Período de pausa
+ email_alerts:
+ title: Alertas por e-mail para outros itens que não sejam pacotes de trabalho
+ news_added: Notícia adicionada
+ news_commented: Comentar em uma notícia
+ document_added: Documento adicionado
+ forum_messages: Mensagem publicada no fórum
+ wiki_page_added: Página wiki adicionada
+ wiki_page_updated: Página wiki atualizada
+ membership_added: Associação adicionada
+ membership_updated: Associação atualizada
+ submit_button: Atualizar alertas
+ notifications:
+ participating:
+ title: Participando
+ submit_button: Atualizar preferências
+ mentioned: Mencionado
+ watched: Assistindo
+ assignee: Encarregado
+ responsible: Responsável
+ shared: Compartilhados comigo
+ date_alerts:
+ title: Alertas de data
+ submit_button: Atualizar alertas de data
+ start_date: Data de início
+ due_date: Data de conclusão
+ overdue: Atrasado
+ times:
+ same_day: No mesmo dia
+ one_day_before: 1 dia antes
+ three_days_before: 3 dias antes
+ seven_days_before: 7 dias antes
+ one_day_after: 1 dia depois
+ three_days_after: 3 dias depois
+ seven_days_after: 7 dias depois
+ non_participating:
+ title: Não participando
+ submit_button: Atualizar preferências
+ work_package_created: Novos pacotes de trabalho
+ work_package_commented: Todos os novos comentários
+ work_package_processed: Todas as mudanças de status
+ work_package_prioritized: Todas as mudanças de prioridade
+ work_package_scheduled: Todas as mudanças de data
+ project_specific_settings:
+ title: Configurações de notificação específicas de projetos
+ add_button: Adicionar notificações específicas do projeto
+ dialog_title: Adicionar notificações específicas do projeto
+ list_header: Projetos com notificações específicas
notifications:
reasons:
assigned: Cessionário
@@ -3481,6 +3608,7 @@ pt-BR:
invalid_filter: Filtro de notificação inválido
label_accessibility: Acessibilidade
label_account: Conta
+ label_actions: Ações
label_active: Ativo
label_activate_user: Ativar usuário
label_active_in_new_projects: Ativo em novos projetos
@@ -3521,6 +3649,7 @@ pt-BR:
label_ical_access_key_generation_hint: Gerado automaticamente ao assinar um calendário.
label_ical_access_key_latest: último
label_ical_access_key_revoke: Anular
+ label_integrations: Integrações
label_add_column: Adicionar coluna
label_applied_status: Situação aplicada
label_archive_project: Arquivar projeto
@@ -3771,7 +3900,7 @@ pt-BR:
label_external_links: Links externos
label_locale: Idioma e região
label_jump_to_a_project: Saltar para um projeto...
- label_jira_import: Importação do Jira
+ label_jira_import: Migrador do Jira
label_keyword_plural: Palavras-chave
label_language_based: Com base no idioma do usuário
label_last_activity: Última atividade
@@ -3809,6 +3938,10 @@ pt-BR:
label_custom_pdf_export_settings: Configurações de exportação de PDF personalizadas
label_custom_favicon: Ícone personalizado
label_custom_touch_icon: Ícone de toque personalizado
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Desconectar
label_mapping_for: 'Mapeamento para: %{attribute}'
label_main_menu: Menu lateral
@@ -4872,6 +5005,7 @@ pt-BR:
'
setting_app_subtitle: Subtítulo do aplicativo
setting_app_title: Título da aplicação
+ setting_organization_name: Organization name
setting_attachment_max_size: Tamanho máximo dos anexos
setting_show_work_package_attachments: Exibir anexos na aba de arquivos por padrão
setting_antivirus_scan_mode: Modo escanear
@@ -5018,12 +5152,12 @@ pt-BR:
setting_welcome_text: Texto do bloco de boas-vindas
setting_welcome_title: Título do bloco de boas-vindas
setting_welcome_on_homescreen: Exibir bloco de boas-vindas na tela inicial
- setting_work_packages_identifier_numeric: Sequência numérica global da instância (padrão)
- setting_work_packages_identifier_numeric_caption: 'Cada pacote de trabalho recebe um número sequencial começando em 1, que é aumentado a cada novo item. Os números são únicos nesta instância, portanto permanecem os mesmos mesmo que os pacotes de trabalho sejam movidos entre projetos.
+ setting_work_packages_identifier_classic: Sequência numérica global da instância (padrão)
+ setting_work_packages_identifier_classic_caption: 'Cada pacote de trabalho recebe um número sequencial começando em 1, que é aumentado a cada novo item. Os números são únicos nesta instância, portanto permanecem os mesmos mesmo que os pacotes de trabalho sejam movidos entre projetos.
'
- setting_work_packages_identifier_alphanumeric: Identificadores alfanuméricos baseados em projeto
- setting_work_packages_identifier_alphanumeric_caption: 'Cada projeto possui um identificador único que é prefixado ao ID do pacote de trabalho. Se um pacote de trabalho for movido para outro projeto, um novo identificador é gerado, mas o antigo continua funcionando.
+ setting_work_packages_identifier_semantic: Identificadores semânticos baseados em projeto
+ setting_work_packages_identifier_semantic_caption: 'Cada projeto possui um identificador único que é prefixado ao ID do pacote de trabalho. Se um pacote de trabalho for movido para outro projeto, um novo identificador é gerado, mas o antigo continua funcionando.
'
setting_work_package_list_default_highlighting_mode: Modo de destaque padrão
diff --git a/config/locales/crowdin/pt-PT.yml b/config/locales/crowdin/pt-PT.yml
index e55f5bb7117..bd9237afdbd 100644
--- a/config/locales/crowdin/pt-PT.yml
+++ b/config/locales/crowdin/pt-PT.yml
@@ -114,7 +114,7 @@ pt-PT:
import:
title: Importar
jira:
- title: Importação Jira
+ title: Jira Migrator
description: Utilize esta ferramenta para importar dados da sua instância do Jira. Pode configurar vários anfitriões do Jira, e escolher o que importar em cada execução de importação.
errors:
cannot_delete_with_imports: Não é possível eliminar o anfitrião do Jira com importações existentes
@@ -125,8 +125,8 @@ pt-PT:
title: Configuração do Jira
new: Nova configuração
banner:
- title: Importação limitada
- description: 'Esta ferramenta de importação está em fase beta, e só consegue importar dados básicos: projetos, problemas (nome, título, descrição, anexos), utilizadores (nome, e-mail, associação ao projeto), estados e tipos. Não pode importar fluxos de trabalho, campos personalizados, relações de problemas ou permissões. Neste momento, só temos suporte para o servidor/centro de dados Jira nas versões 10.x e 11.x. As instâncias na nuvem não são suportadas agora.'
+ title: Capacidades de importação limitadas
+ description: 'Jira Migrator está em fase beta, e só consegue importar dados básicos: projetos, problemas (nome, título, descrição, anexos), utilizadores (nome, e-mail, associação ao projeto), estados e tipos. Não pode importar fluxos de trabalho, campos personalizados, relações de problemas ou permissões. Neste momento, só temos suporte para o servidor/centro de dados Jira nas versões 10.x e 11.x. As instâncias na nuvem não são suportadas agora.'
form:
fields:
name: Nome
@@ -154,6 +154,7 @@ pt-PT:
connection_timeout: 'O tempo de ligação ao servidor Jira expirou: %{message}'
parse_error: 'Falha na análise da resposta da API do Jira: %{message}'
api_error: A API do Jira devolveu o estado de erro %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projetos
last_change: Última alteração
@@ -162,7 +163,7 @@ pt-PT:
run:
title: Importar execução
history: Histórico
- remove_error: Uma importação do Jira não pode ser removida enquanto está a ser executada
+ remove_error: Uma execução de importação do Jira não pode ser eliminada enquanto estiver em execução
import_blocked_error: Está em curso ou a aguardar revisão outra importação do Jira. Conclua-a ou reverta-a antes de iniciar uma nova importação.
project_identifier_taken: 'Está a tentar importar um projeto com um identificador já utilizado: %{taken_identifier}. Atualize o identificador do projeto no Jira e clique em Tentar novamente.'
blank:
@@ -387,9 +388,9 @@ pt-PT:
notification_text_default: "
Olá,
Foi criado um novo projeto: projectValue:name
Obrigado
\n"
work_packages_identifier:
page_header:
- description: Escolha entre IDs numéricos básicos de pacotes de trabalho ou IDs específicos do projeto que acrescentam o identificador do projeto ao ID do pacote de trabalho.
+ description: Escolha entre IDs de pacotes de trabalho numéricos clássicos ou específicos de projetos semânticos, que acrescentam o identificador do projeto ao ID do pacote de trabalho.
banner:
- existing_identifiers_notice: 'Os identificadores existentes para os projec~tos %{project_count} não cumprem os requisitos para identificadores alfanuméricos baseados em projetos. O OpenProject pode atualizá-los automaticamente para que sejam válidos, como nos exemplos abaixo. Clique em "Corrigir automaticamente e guardar" para atualizar os identificadores de todos os projetos desta forma, e ativar os identificadores alfanuméricos baseados em projetos.
+ existing_identifiers_notice: 'Os identificadores existentes para os projec~tos %{project_count} não cumprem os requisitos para identificadores semânticos baseados em projetos. O OpenProject pode atualizá-los automaticamente para que sejam válidos, como nos exemplos abaixo. Clique em "Corrigir automaticamente e guardar" para atualizar os identificadores de todos os projetos desta forma, e ativar os identificadores semânticos baseados em projetos.
'
box_header:
@@ -398,10 +399,14 @@ pt-PT:
label_autofixed_suggestion: Identificador de futuro
label_example_work_package_id: Exemplo de ID de pacote de trabalho
autofix_preview:
- error_too_long: Tem de ter menos de 5 caracteres
+ error_too_long: Tem de ter 10 caracteres ou menos
+ error_numerical: Não pode ser puramente numérico
+ error_starts_with_number: Não pode começar com um número
error_special_characters: Caracteres especiais não são permitidos
+ error_not_fully_uppercased: Deve estar em maiúsculas
error_in_use: Já está a ser utilizado como identificador ativo de outro projeto
error_reserved: Reservado pelo histórico do identificador de outro projeto
+ error_unknown: Precisa de revisão manual
remaining_projects:
one: "... mais 1 projeto"
other: "... mais %{count} projetos"
@@ -416,7 +421,7 @@ pt-PT:
checkbox_label: Compreendo que isto irá alterar permanentemente todos os IDs dos pacotes de trabalho
success_banner: Formato de identificador de pacote de trabalho atualizado com sucesso.
in_progress:
- banner_message: Os identificadores de projetos estão a ser atualizados para identificadores alfanuméricos baseados em projetos. Este processo pode demorar algum tempo.
+ banner_message: Os identificadores de projetos estão a ser atualizados para identificadores semânticos baseados em projetos. Este processo pode demorar algum tempo.
workflows:
tabs:
default_transitions: Transições padrão
@@ -681,6 +686,37 @@ pt-PT:
danger_dialog:
confirmation_live_message_checked: O botão para prosseguir está agora ativo.
confirmation_live_message_unchecked: O botão para prosseguir está agora inativo. Tem de assinalar a caixa de verificação para continuar.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Paginação
prev: Anterior
@@ -1339,6 +1375,20 @@ pt-PT:
index:
no_results_title_text: Atualmente, não existem ritmos de trabalho.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1534,6 +1584,9 @@ pt-PT:
dependencies: Dependências
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identificador
+ work_package: Pacote de trabalho
jira_import:
projects: Projetos
import/jira:
@@ -1542,7 +1595,7 @@ pt-PT:
personal_access_token: Token de acesso pessoal
import/jira_open_project_reference:
jira: Jira
- jira_import: Importação Jira
+ jira_import: Jira Migrator
announcements:
show_until: Exibir até
attachment:
@@ -1798,6 +1851,7 @@ pt-PT:
identity_url: URL de identidade
parent: Grupo principal
organizational_unit: Unidade organizacional
+ group_users: Group users
group_detail:
parent: Grupo principal
organizational_unit: Unidade organizacional
@@ -1915,6 +1969,7 @@ pt-PT:
confirmation: não coincide %{attribute}.
could_not_be_copied: "%{dependency} não pode ser copiado (completamente)."
does_not_exist: não existe.
+ user_already_in_department: User %{user_id} is already a member of department %{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.
@@ -1981,6 +2036,7 @@ pt-PT:
attributes:
parent_id:
circular_dependency: criaria uma hierarquia circular de grupos.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2463,7 +2519,6 @@ pt-PT:
avatar: Avatar
base: 'Erro geral:'
body: Corpo
- blocks_ids: Identificações de pacotes de trabalho bloqueados
category: Categoria
comment: Comentário
comments: Comentario
@@ -2920,6 +2975,7 @@ pt-PT:
title: Complemento Enterprise
plan_title: Complemento %{plan} Enterprise
plan_name: Plano Enterprise %{plan}
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Disponível a partir do %{plan_name}.
unlimited: Ilimitado
already_have_token: 'Já tem um token? Adicione-o com o botão abaixo para atualizar para o plano Enterprise reservado.
@@ -3389,6 +3445,11 @@ pt-PT:
quick_add:
label: Adicionar…
my_account:
+ notifications_and_email:
+ title: Notificação e e-mail
+ tabs:
+ notifications: Definições de notificações
+ email_reminders: Lembretes por e-mail
access_tokens:
description: Os tokens de fornecedor são emitidos pelo OpenProject e permitem o acesso de outras aplicações. Os tokens de cliente são emitidos por outras aplicações e permitem que o OpenProject lhes aceda.
no_results:
@@ -3451,6 +3512,72 @@ pt-PT:
disabled_text: Os tokens RSS não são ativados pelo administrador. Contacte o seu administrador para utilizar esta funcionalidade.
storages:
unknown_storage: Armazenamento desconhecido
+ email_reminders:
+ immediate_reminders:
+ title: Enviar-me um lembrete por e-mail
+ mentioned: Notificar-me quando eu for mencionado
+ personal_reminder: Notificar-me para receber lembretes pessoais
+ daily_reminders:
+ title: Enviar-me lembretes diários de e-mail para notificações não lidas
+ caption: Receberá estes lembretes apenas para notificações não lidas e apenas nas horas que especificar. Até configurar um fuso horário para a sua conta, as horas serão interpretadas em UTC.
+ enabled: Ativar lembretes diários por e-mail
+ add_time: Adicionar hora
+ remove_time: Remover hora
+ time_slot_label: Hora do lembrete (UTC)
+ workdays:
+ title: Receber lembretes por e-mail nestes dias
+ submit_button: Atualizar dias de lembrete
+ pause_reminders:
+ title: Pausar notificações por e-mail
+ enabled: Pausar temporariamente lembretes de e-mail diários
+ date_range: Período de pausa
+ email_alerts:
+ title: Alertas de e-mail para outros elementos que não pacotes de trabalho
+ news_added: Notícia adicionada
+ news_commented: Comentar numa notícia
+ document_added: Documento adicionado
+ forum_messages: Mensagem do fórum publicada
+ wiki_page_added: Página wiki adicionada
+ wiki_page_updated: Página wiki atualizada
+ membership_added: Adesão adicionada
+ membership_updated: Adesão atualizada
+ submit_button: Atualizar alertas
+ notifications:
+ participating:
+ title: Participante
+ submit_button: Atualizar preferências
+ mentioned: Mencionou
+ watched: A ver
+ assignee: Encarregado
+ responsible: Responsável
+ shared: Partilhado comigo
+ date_alerts:
+ title: Alertas de data
+ submit_button: Atualizar alertas de data
+ start_date: Data de início
+ due_date: Data de término
+ overdue: Em atraso
+ times:
+ same_day: No mesmo dia
+ one_day_before: 1 dia antes
+ three_days_before: 3 dias antes
+ seven_days_before: 7 dias antes
+ one_day_after: 1 dia depois
+ three_days_after: 3 dias depois
+ seven_days_after: 7 dias depois
+ non_participating:
+ title: Não participante
+ submit_button: Atualizar preferências
+ work_package_created: Novos pacotes de trabalho
+ work_package_commented: Todos os novos comentários
+ work_package_processed: Todas as mudanças de estado
+ work_package_prioritized: Todas as mudanças de prioridade
+ work_package_scheduled: Todas as alterações de datas
+ project_specific_settings:
+ title: Definições de notificação específicas do projeto
+ add_button: Adicionar notificações específicas do projeto
+ dialog_title: Adicionar notificações específicas do projeto
+ list_header: Projetos com notificações específicas
notifications:
reasons:
assigned: Pessoa atribuída
@@ -3482,6 +3609,7 @@ pt-PT:
invalid_filter: Filtro de notificação inválido
label_accessibility: Accessibilidade
label_account: Conta
+ label_actions: Ações
label_active: Ativo
label_activate_user: Ativar utilizador
label_active_in_new_projects: Ativo em novos projetos
@@ -3522,6 +3650,7 @@ pt-PT:
label_ical_access_key_generation_hint: Gerado automaticamente ao subscrever um calendário.
label_ical_access_key_latest: recente
label_ical_access_key_revoke: Revogar
+ label_integrations: Integrações
label_add_column: Adicionar coluna
label_applied_status: Status aplicado
label_archive_project: Arquivar projeto
@@ -3772,7 +3901,7 @@ pt-PT:
label_external_links: Links externos
label_locale: Idioma e região
label_jump_to_a_project: Saltar para um projeto...
- label_jira_import: Importação Jira
+ label_jira_import: Jira Migrator
label_keyword_plural: Palavras-chave
label_language_based: Com base no idioma do utilizador
label_last_activity: Última atividade
@@ -3810,6 +3939,10 @@ pt-PT:
label_custom_pdf_export_settings: Configurações de exportação de PDF personalizadas
label_custom_favicon: Favicon personalizado
label_custom_touch_icon: Ícone de toque personalizado
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Terminar Sessão
label_mapping_for: 'Mapeamento para: %{attribute}'
label_main_menu: Menu lateral
@@ -4867,6 +5000,7 @@ pt-PT:
'
setting_app_subtitle: Subtítulo da aplicação
setting_app_title: Título da aplicação
+ setting_organization_name: Organization name
setting_attachment_max_size: Tamanho máx. do anexo
setting_show_work_package_attachments: Mostrar anexos no separador dos ficheiros por padrão
setting_antivirus_scan_mode: Modo de digitalização
@@ -5013,12 +5147,12 @@ pt-PT:
setting_welcome_text: Bloco de texto de boas-vindas
setting_welcome_title: Título de texto de boas-vindas
setting_welcome_on_homescreen: Exibir o bloco de boas-vindas no ecrã inicial
- setting_work_packages_identifier_numeric: Sequência numérica a nível da instância (padrão)
- setting_work_packages_identifier_numeric_caption: 'Cada pacote de trabalho recebe um número sequencial que começa em 1 e aumenta com cada novo pacote. Os números são únicos nesta instância, pelo que permanecem os mesmos, mesmo que os pacotes de trabalho sejam transferidos entre projetos.
+ setting_work_packages_identifier_classic: Sequência numérica a nível da instância (padrão)
+ setting_work_packages_identifier_classic_caption: 'Cada pacote de trabalho recebe um número sequencial que começa em 1 e aumenta com cada novo pacote. Os números são únicos nesta instância, pelo que permanecem os mesmos, mesmo que os pacotes de trabalho sejam transferidos entre projetos.
'
- setting_work_packages_identifier_alphanumeric: Identificadores alfanuméricos baseados em projetos
- setting_work_packages_identifier_alphanumeric_caption: 'Cada projeto tem um identificador único que é prefixado ao ID do pacote de trabalho. Se um pacote de trabalho for transferido para outro projeto, é gerado um novo identificador, mas o antigo continua a funcionar.
+ setting_work_packages_identifier_semantic: Identificadores semânticos baseados em projetos
+ setting_work_packages_identifier_semantic_caption: 'Cada projeto tem um identificador único que é prefixado ao ID do pacote de trabalho. Se um pacote de trabalho for transferido para outro projeto, é gerado um novo identificador, mas o antigo continua a funcionar.
'
setting_work_package_list_default_highlighting_mode: Modo de destaque padrão
diff --git a/config/locales/crowdin/ro.yml b/config/locales/crowdin/ro.yml
index f2e163d0e24..de18dcdbe43 100644
--- a/config/locales/crowdin/ro.yml
+++ b/config/locales/crowdin/ro.yml
@@ -114,7 +114,7 @@ ro:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ ro:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ ro:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ ro:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -393,9 +394,9 @@ ro:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -404,10 +405,14 @@ ro:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -423,7 +428,7 @@ ro:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -690,6 +695,37 @@ ro:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1358,6 +1394,20 @@ ro:
index:
no_results_title_text: În acest moment nu există fluxuri de lucru.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1554,6 +1604,9 @@ ro:
dependencies: Dependenţe
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1562,7 +1615,7 @@ ro:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Afişare până la
attachment:
@@ -1818,6 +1871,7 @@ ro:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1935,6 +1989,7 @@ ro:
confirmation: nu se potrivește cu %{attribute}.
could_not_be_copied: "%{dependency} nu a putut fi copiat (integral)."
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.
@@ -2001,6 +2056,7 @@ ro:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2503,7 +2559,6 @@ ro:
avatar: Avatar
base: 'Eroare generală:'
body: Body
- blocks_ids: ID-urile pachetelor de lucru blocate
category: Categorie
comment: Comentariu
comments: Comentariu
@@ -2980,6 +3035,7 @@ ro:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Nelimitat
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3450,6 +3506,11 @@ ro:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3512,6 +3573,72 @@ ro:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Executant
@@ -3543,6 +3670,7 @@ ro:
invalid_filter: Filtru de notificare invalid
label_accessibility: Accesibilitate
label_account: Cont
+ label_actions: Acțiuni
label_active: Activ
label_activate_user: Activați utilizatorul
label_active_in_new_projects: Activ în proiecte noi
@@ -3583,6 +3711,7 @@ ro:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revocă
+ label_integrations: Integrations
label_add_column: Adaugă coloană
label_applied_status: Stare aplicată
label_archive_project: Arhivează proiect
@@ -3726,7 +3855,7 @@ ro:
label_duplicated_by: dublat de
label_duplicate: duplicat
label_duplicates: dublează
- label_edit: Editează
+ label_edit: Editare
label_edit_x: 'Editare: %{x}'
label_view_x: 'View: %{x}'
label_enable_multi_select: Comutare selecție multiplă
@@ -3783,7 +3912,7 @@ ro:
label_global_roles: Roluri globale
label_git_path: Calea catre directorul .git
label_greater_or_equal: ">="
- label_group_by: Grupează după
+ label_group_by: Grupare după
label_group_new: Grupare nouă
label_group: Grup
label_group_named: Grup %{name}
@@ -3833,7 +3962,7 @@ ro:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Salt la un proiect...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Cuvinte cheie
label_language_based: Bazat pe limba utilizatorului
label_last_activity: Ultima activitate
@@ -3871,6 +4000,10 @@ ro:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Pictogramă personalizată
label_custom_touch_icon: Pictogramă touch personalizată
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Deconectare
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Meniu lateral
@@ -4946,6 +5079,7 @@ ro:
'
setting_app_subtitle: Subtitlu aplicație
setting_app_title: Titlu aplicație
+ setting_organization_name: Organization name
setting_attachment_max_size: Dimensiune maximă atașament
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5092,12 +5226,12 @@ ro:
setting_welcome_text: Text bloc "bun venit"
setting_welcome_title: Titlu bloc "bun venit"
setting_welcome_on_homescreen: Afişare bloc "bun venit" pe ecranul de start
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Mod de evidențiere implicit
diff --git a/config/locales/crowdin/ru.yml b/config/locales/crowdin/ru.yml
index 22b1e90d72e..d298f5f7a2c 100644
--- a/config/locales/crowdin/ru.yml
+++ b/config/locales/crowdin/ru.yml
@@ -114,7 +114,7 @@ ru:
import:
title: Импорт
jira:
- title: Импорт из Jira
+ title: Мигратор Jira
description: Используйте этот инструмент для импорта данных из Вашего экземпляра Jira. Вы можете настроить несколько узлов Jira и выбрать, что импортировать в каждом запуске импорта.
errors:
cannot_delete_with_imports: Невозможно удалить хост Jira с существующими импортами
@@ -125,8 +125,8 @@ ru:
title: Конфигурация Jira
new: Новая конфигурация
banner:
- title: Ограниченный импорт
- description: 'Этот инструмент импорта в настоящее время находится в стадии бета-тестирования и может импортировать только основные данные: проекты, проблемы (имя, название, описание, вложения), пользователей (имя, электронная почта, членство в проекте), статусы и типы. Он не может импортировать рабочие процессы, пользовательские поля, отношения между заданиями или разрешения. В настоящее время мы поддерживаем только Jira Server/Data Center версий 10.x и 11.x. Облачные экземпляры на данный момент не поддерживаются.'
+ title: Ограниченные возможности импорта
+ description: 'Этот мигратор Jira в настоящее время находится в бета-версии и может импортировать только основные данные: проекты, проблемы (имя, заголовок, описание, вложения), пользователей (имя, электронная почта, членство в проекте), статусы и типы. Он не может импортировать рабочие процессы, пользовательские поля, отношения между заданиями или разрешения. В настоящее время мы поддерживаем только Jira Server/Data Center версий 10.x и 11.x. Облачные экземпляры на данный момент не поддерживаются.'
form:
fields:
name: Имя
@@ -154,6 +154,7 @@ ru:
connection_timeout: 'Время подключения к серверу Jira истекло: %{message}'
parse_error: 'Не удалось разобрать ответ Jira API: %{message}'
api_error: Jira API вернул статус ошибки %{status}
+ 401_error: Jira API вернул ошибку 401. Ваш токен аутентификации может быть истёк или не хватает необходимых разрешений. Пожалуйста, убедитесь, что токен принадлежит администратору Jira.
columns:
projects: Проекты
last_change: Последнее изменение
@@ -162,7 +163,7 @@ ru:
run:
title: Выполнение импорта
history: История
- remove_error: Импорт Jira нельзя удалить во время его выполнения
+ remove_error: Запуск импорта Jira не может быть удалён, пока он запущен
import_blocked_error: Другая операция импорта Jira находится в процессе выполнения или ожидает рассмотрения. Пожалуйста, завершите или отмените его, прежде чем начинать новый импорт.
project_identifier_taken: 'Вы пытаетесь импортировать проект с уже использованным идентификатором: %{taken_identifier}. Пожалуйста, обновите идентификатор проекта в Jira, затем нажмите «Повторить».'
blank:
@@ -399,9 +400,9 @@ ru:
notification_text_default: "
Здравствуйте,
Был создан новый проект: projectValue:name
Спасибо
\n"
work_packages_identifier:
page_header:
- description: Выберите между базовыми числовыми идентификаторами пакетов работ или специфическими для проекта, которые добавляют идентификатор проекта к идентификатору пакета работ.
+ description: Выберите между классическими числовыми идентификаторами пакета работ или семантическими, специфичными для проекта, которые добавляют идентификатор проекта к ID пакета работ.
banner:
- existing_identifiers_notice: 'Существующие идентификаторы для %{project_count} проектов не соответствуют требованиям к буквенно-цифровым идентификаторам проектов. OpenProject может автоматически обновить их, чтобы они были действительными, как показано в примерах ниже. Щелкните на ''Исправить и сохранить'', чтобы обновить таким образом идентификаторы для всех проектов и включить буквенно-цифровые идентификаторы на основе проекта.
+ existing_identifiers_notice: 'Существующие идентификаторы для проектов %{project_count} не соответствуют требованиям, предъявляемым к семантическим идентификаторам. OpenProject может автоматически обновить их, чтобы они были действительными, как показано в примерах ниже. Щелкните на ''Исправить и сохранить'', чтобы обновить идентификаторы для всех проектов и включить семантические идентификаторы на основе проекта.
'
box_header:
@@ -410,10 +411,14 @@ ru:
label_autofixed_suggestion: Следующий идентификатор
label_example_work_package_id: Пример ID пакета работ
autofix_preview:
- error_too_long: Должен быть менее 5 символов
+ error_too_long: Должно быть 10 символов или меньше
+ error_numerical: Не может быть чисто числовым
+ error_starts_with_number: Не может начинаться с цифры
error_special_characters: Специальные символы не допускаются
+ error_not_fully_uppercased: Должно быть заглавными
error_in_use: Уже используется в другом проекте
error_reserved: Зарезервировано другим проектом
+ error_unknown: Требуется ручная проверка
remaining_projects:
one: "... еще 1 проект"
few: "... еще %{count} проектов"
@@ -697,6 +702,37 @@ ru:
danger_dialog:
confirmation_live_message_checked: Кнопка для продолжения активна.
confirmation_live_message_unchecked: Кнопка для продолжения неактивна. Чтобы продолжить, поставьте галочку.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Разделение на страницы
prev: Назад
@@ -1376,6 +1412,20 @@ ru:
index:
no_results_title_text: В данный момент рабочих потоков нет.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1575,6 +1625,9 @@ ru:
dependencies: Связи
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Идентификатор
+ work_package: Пакет работ
jira_import:
projects: Проекты
import/jira:
@@ -1583,7 +1636,7 @@ ru:
personal_access_token: Персональный токен доступа
import/jira_open_project_reference:
jira: Jira
- jira_import: Импорт из Jira
+ jira_import: Мигратор Jira
announcements:
show_until: Отобразить до
attachment:
@@ -1839,6 +1892,7 @@ ru:
identity_url: URL идентификации
parent: Родительская группа
organizational_unit: Подразделение организации
+ group_users: Group users
group_detail:
parent: Родительская группа
organizational_unit: Подразделение организации
@@ -1956,6 +2010,7 @@ ru:
confirmation: не совпадает со значением поля %{attribute}.
could_not_be_copied: "%{dependency} не может быть скопировано (полностью)."
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: запись не разрешена.
@@ -2022,6 +2077,7 @@ ru:
attributes:
parent_id:
circular_dependency: создаст круговую иерархию групп.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2546,7 +2602,6 @@ ru:
'
base: 'Общая ошибка:'
body: Сообщение
- blocks_ids: Идентификаторы заблокированных рабочих пакетов
category: Категория
comment: Комментарий
comments: Комментарий
@@ -3043,6 +3098,7 @@ ru:
title: Корпоративное дополнение
plan_title: Дополнение корпоративной версии %{plan}
plan_name: Корпоративная версия %{plan}
+ trial_text: Эта функция включена в Вашу активную пробную версию Enterprise.
plan_text_html: Доступно начиная с %{plan_name}.
unlimited: Без ограничений
already_have_token: 'Уже есть токен? Добавьте его с помощью кнопки ниже, чтобы перейти на корпоративную лицензию.
@@ -3514,6 +3570,11 @@ ru:
quick_add:
label: Добавить…
my_account:
+ notifications_and_email:
+ title: Уведомления и email
+ tabs:
+ notifications: Настройки уведомлений
+ email_reminders: Почтовые напоминания
access_tokens:
description: Провайдерские токены выпускаются OpenProject, позволяя другим приложениям получать к ним доступ. Клиентские токены выпускаются другими приложениями, позволяя OpenProject получить к ним доступ.
no_results:
@@ -3576,6 +3637,72 @@ ru:
disabled_text: Токены RSS не включены администратором. Пожалуйста, обратитесь к администратору, чтобы использовать эту функцию.
storages:
unknown_storage: Неизвестное хранилище
+ email_reminders:
+ immediate_reminders:
+ title: Отправить мне напоминание по электронной почте
+ mentioned: Сообщить мне, когда меня упомянут
+ personal_reminder: Уведомлять меня о личных напоминаниях
+ daily_reminders:
+ title: Отправлять мне ежедневные напоминания по электронной почте о непрочитанных уведомлениях
+ caption: Вы будете получать эти напоминания только для непрочитанных уведомлений и только в указанные Вами часы. Пока Вы не настроите часовой пояс для своей учетной записи, время будет интерпретироваться как UTC.
+ enabled: Включить ежедневные напоминания по электронной почте
+ add_time: Добавить время
+ remove_time: Удалить время
+ time_slot_label: Время напоминания (UTC)
+ workdays:
+ title: Получать напоминания по электронной почте в эти дни
+ submit_button: Обновить дни напоминаний
+ pause_reminders:
+ title: Приостановить уведомления по электронной почте
+ enabled: Временно приостановить ежедневные напоминания по электронной почте
+ date_range: Период приостановки
+ email_alerts:
+ title: Уведомления по электронной почте для других элементов (которые не являются пакетами работ)
+ news_added: Новость добавлена
+ news_commented: Комментарий к новости
+ document_added: Документ добавлен
+ forum_messages: Сообщение на форуме
+ wiki_page_added: Wiki-страница добавлена
+ wiki_page_updated: Wiki-страница обновлена
+ membership_added: Членство добавлено
+ membership_updated: Членство обновлено
+ submit_button: Обновить оповещения
+ notifications:
+ participating:
+ title: Участие
+ submit_button: Обновить настройки
+ mentioned: Упомянутый
+ watched: Отслеживает
+ assignee: Назначенный
+ responsible: Ответственный
+ shared: Доступные мне
+ date_alerts:
+ title: Дата оповещения
+ submit_button: Обновить дату оповещения
+ start_date: Дата начала
+ due_date: Дата окончания
+ overdue: Просрочено
+ times:
+ same_day: В тот же день
+ one_day_before: За 1 день до
+ three_days_before: За 3 дня до
+ seven_days_before: За 7 дней до
+ one_day_after: Через 1 день после
+ three_days_after: Через 3 дня после
+ seven_days_after: Через 7 дней после
+ non_participating:
+ title: Неучастие
+ submit_button: Обновить настройки
+ work_package_created: Новые пакеты работ
+ work_package_commented: Все новые комментарии
+ work_package_processed: Все изменения статуса
+ work_package_prioritized: Все изменения приоритетов
+ work_package_scheduled: Все изменения дат
+ project_specific_settings:
+ title: Настройки уведомлений для конкретного проекта
+ add_button: Добавить уведомления по проекту
+ dialog_title: Добавить уведомления по проекту
+ list_header: Проекты с особыми уведомлениями
notifications:
reasons:
assigned: Исполнитель
@@ -3607,6 +3734,7 @@ ru:
invalid_filter: Неверный фильтр уведомлений
label_accessibility: Спец. возможности
label_account: Учетная запись
+ label_actions: Действия
label_active: Активен
label_activate_user: Активировать пользователя
label_active_in_new_projects: Активное участие в новых проектах
@@ -3647,6 +3775,7 @@ ru:
label_ical_access_key_generation_hint: Автоматически генерируется при подписке на календарь.
label_ical_access_key_latest: последний
label_ical_access_key_revoke: Отозвать
+ label_integrations: Интеграции
label_add_column: Добавить столбец
label_applied_status: Прикладной статус
label_archive_project: Архивировать проект
@@ -3897,7 +4026,7 @@ ru:
label_external_links: Внешние ссылки
label_locale: Язык и регион
label_jump_to_a_project: Перейти к проекту...
- label_jira_import: Импорт из Jira
+ label_jira_import: Мигратор Jira
label_keyword_plural: Ключевые слова
label_language_based: Основанный на языке пользователя
label_last_activity: Последняя активность
@@ -3935,6 +4064,10 @@ ru:
label_custom_pdf_export_settings: Настройки экспорта PDF
label_custom_favicon: Пользовательские иконки
label_custom_touch_icon: Пользовательский значок логотипа
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Выход
label_mapping_for: 'Привязки для: %{attribute}'
label_main_menu: Боковое меню
@@ -5003,6 +5136,7 @@ ru:
'
setting_app_subtitle: Второе название приложения
setting_app_title: Название приложения
+ setting_organization_name: Organization name
setting_attachment_max_size: Максимальный размер вложения
setting_show_work_package_attachments: По умолчанию показывать вложения на вкладке "Файлы".
setting_antivirus_scan_mode: Режим сканирования
@@ -5149,12 +5283,12 @@ ru:
setting_welcome_text: Текст приветствия
setting_welcome_title: Заголовок приветствия
setting_welcome_on_homescreen: Показывать приветствие на домашней странице
- setting_work_packages_identifier_numeric: Числовая последовательность по умолчанию (по умолчанию)
- setting_work_packages_identifier_numeric_caption: 'Каждый пакет работ получает порядковый номер, начинающийся с 1 и увеличивающийся с каждым новым пакетом. Номера уникальны в пределах данного экземпляра, поэтому они остаются неизменными, даже если пакеты работ перемещаются между проектами.
+ setting_work_packages_identifier_classic: Числовая последовательность для всего экземпляра (по умолчанию)
+ setting_work_packages_identifier_classic_caption: 'Каждый пакет работ получает порядковый номер, начинающийся с 1 и увеличивающийся с каждым новым пакетом. Номера уникальны в пределах данного экземпляра, поэтому они остаются неизменными, даже если пакеты работ перемещаются между проектами.
'
- setting_work_packages_identifier_alphanumeric: Семантические идентификаторы на основе проекта
- setting_work_packages_identifier_alphanumeric_caption: 'У каждого проекта есть уникальный идентификатор, префикс идентификатора пакета работ. Если пакет работ перемещен в другой проект, генерируется новый идентификатор, но старый продолжает работать.
+ setting_work_packages_identifier_semantic: Семантические идентификаторы на основе проекта
+ setting_work_packages_identifier_semantic_caption: 'Каждый проект имеет уникальный идентификатор, который является префиксом к идентификатору рабочего пакета. Если рабочий пакет перемещается в другой проект, генерируется новый идентификатор, но старый продолжает функционировать.
'
setting_work_package_list_default_highlighting_mode: Способ выделения по умолчанию
diff --git a/config/locales/crowdin/rw.yml b/config/locales/crowdin/rw.yml
index 7711ffd5f64..74008c195c4 100644
--- a/config/locales/crowdin/rw.yml
+++ b/config/locales/crowdin/rw.yml
@@ -114,7 +114,7 @@ rw:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ rw:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ rw:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ rw:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ rw:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ rw:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ rw:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ rw:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ rw:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ rw:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ rw:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ rw:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ rw:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ rw:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ rw:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ rw:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ rw:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ rw:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ rw:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ rw:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ rw:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ rw:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ rw:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ rw:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/si.yml b/config/locales/crowdin/si.yml
index 9b00ffeec88..020aa93d340 100644
--- a/config/locales/crowdin/si.yml
+++ b/config/locales/crowdin/si.yml
@@ -114,7 +114,7 @@ si:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ si:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ si:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ si:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ si:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ si:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ si:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ si:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ si:
index:
no_results_title_text: දැනට වැඩ ප්රවාහයන් නොමැත.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ si:
dependencies: පරායත්තතා
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ si:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: ප්රදර්ශනය වන තුරු
attachment:
@@ -1800,6 +1853,7 @@ si:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ si:
confirmation: "%{attribute}නොගැලපේ."
could_not_be_copied: "%{dependency} could not be (fully) copied."
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: ලිවීමට උත්සාහ කළ නමුත් එය ලිවිය නොහැක.
@@ -1983,6 +2038,7 @@ si:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ si:
avatar: Avatar
base: 'සාමාන්ය දෝෂය:'
body: Body
- blocks_ids: අවහිර කරන ලද වැඩ පැකේජ වල IDS
category: ප්රවර්ගය
comment: අදහස් දක්වන්න
comments: අදහස් දක්වන්න
@@ -2922,6 +2977,7 @@ si:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ si:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ si:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: අස්ගිනී
@@ -3484,6 +3611,7 @@ si:
invalid_filter: Invalid notification filter
label_accessibility: ප්රවේශ්යතාව
label_account: ගිණුම
+ label_actions: ක්රියාමාර්ග
label_active: ක්රියාකාරී
label_activate_user: පරිශීලකයා සක්රිය කරන්න
label_active_in_new_projects: නව ව්යාපෘතිවල ක්රියාකාරී වේ
@@ -3524,6 +3652,7 @@ si:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: අවලංගු
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: ව්යවහාරික තත්ත්වය
label_archive_project: සංරක්ෂිත ව්යාපෘතිය
@@ -3774,7 +3903,7 @@ si:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: ව්යාපෘතියකට පනින්න...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: මූල පද
label_language_based: පරිශීලකයාගේ භාෂාව මත පදනම්ව
label_last_activity: අවසාන ක්රියාකාරකම්
@@ -3812,6 +3941,10 @@ si:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: අභිරුචි ප්රියතම
label_custom_touch_icon: අභිරුචි ස්පර්ශ අයිකනය
+ label_departments: Organization
+ 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).
+
+ '
label_logout: ලියාපදිංචි වන්න
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: පැති මෙනුව
@@ -4884,6 +5017,7 @@ si:
'
setting_app_subtitle: අයදුම් උප සිරැසි
setting_app_title: අයදුම් මාතෘකාව
+ setting_organization_name: Organization name
setting_attachment_max_size: ඇමුණුමක් උපරිම. ප්රමාණය
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ si:
setting_welcome_text: බ්ලොක් පෙළ සාදරයෙන් පිළිගනිමු
setting_welcome_title: වාරණ මාතෘකාව සාදරයෙන් පිළිගනිමු
setting_welcome_on_homescreen: homescreen මත ප්රදර්ශනය පිළිගැනීමේ වාරණ
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: පෙරනිමි ඉස්මතු මාදිලිය
diff --git a/config/locales/crowdin/sk.yml b/config/locales/crowdin/sk.yml
index bf84e25d6c0..1aacb9cd243 100644
--- a/config/locales/crowdin/sk.yml
+++ b/config/locales/crowdin/sk.yml
@@ -114,7 +114,7 @@ sk:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ sk:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ sk:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ sk:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -399,9 +400,9 @@ sk:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -410,10 +411,14 @@ sk:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -430,7 +435,7 @@ sk:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -698,6 +703,37 @@ sk:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1375,6 +1411,20 @@ sk:
index:
no_results_title_text: Momentálne neexistujú žiadne toky činností.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1572,6 +1622,9 @@ sk:
dependencies: Závislosti
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1580,7 +1633,7 @@ sk:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Zobrazovať, až kým
attachment:
@@ -1836,6 +1889,7 @@ sk:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1953,6 +2007,7 @@ sk:
confirmation: "%{attribute} sa nezhoduje."
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2019,6 +2074,7 @@ sk:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2539,7 +2595,6 @@ sk:
avatar: Avatar
base: 'Všeobecná chyba:'
body: Body
- blocks_ids: Identifikátory blokovaných pracovných balíkov
category: Kategória
comment: Komentár
comments: Komentár
@@ -3036,6 +3091,7 @@ sk:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3507,6 +3563,11 @@ sk:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3569,6 +3630,72 @@ sk:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Priradené
@@ -3600,6 +3727,7 @@ sk:
invalid_filter: Invalid notification filter
label_accessibility: Prístupnosť
label_account: Účet
+ label_actions: Akcie
label_active: Aktívny
label_activate_user: Aktívny užívateľ
label_active_in_new_projects: Aktívny v nových projektoch
@@ -3640,6 +3768,7 @@ sk:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Odvolať
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Aplikovaný stav
label_archive_project: Archivovať projekt
@@ -3890,7 +4019,7 @@ sk:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Skok do projektu...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Kľúčové slová
label_language_based: Založené na jazyku používateľa
label_last_activity: Posledná aktivita
@@ -3928,6 +4057,10 @@ sk:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Vlastná favicon
label_custom_touch_icon: Vlastná dotyková ikona
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Odhlásiť sa
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Vedľajšie ponuky
@@ -5012,6 +5145,7 @@ sk:
'
setting_app_subtitle: Podtitulok aplikácie
setting_app_title: Názov aplikácie
+ setting_organization_name: Organization name
setting_attachment_max_size: Maximálna veľkosť prílohy
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5158,12 +5292,12 @@ sk:
setting_welcome_text: Text pre uvítací blok
setting_welcome_title: Názov uvítacieho bloku
setting_welcome_on_homescreen: Zobraziť uvítací blok na úvodnej obrazovke
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Predvolený režim zvýraznenia
diff --git a/config/locales/crowdin/sl.yml b/config/locales/crowdin/sl.yml
index f066e4f040a..3272b0a4241 100644
--- a/config/locales/crowdin/sl.yml
+++ b/config/locales/crowdin/sl.yml
@@ -116,7 +116,7 @@ sl:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -127,8 +127,8 @@ sl:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -156,6 +156,7 @@ sl:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -164,7 +165,7 @@ sl:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -401,9 +402,9 @@ sl:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -412,10 +413,14 @@ sl:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
two: "... %{count} more projects"
@@ -432,7 +437,7 @@ sl:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -699,6 +704,37 @@ sl:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1376,6 +1412,20 @@ sl:
index:
no_results_title_text: Trenutno ni poslovnih procesov
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1573,6 +1623,9 @@ sl:
dependencies: Odvisnosti
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1581,7 +1634,7 @@ sl:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Prikaži do
attachment:
@@ -1837,6 +1890,7 @@ sl:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1954,6 +2008,7 @@ sl:
confirmation: se ne ujema %{attribute}
could_not_be_copied: "%{dependency} ni bilo mogoče (v celoti) kopirati."
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.
@@ -2020,6 +2075,7 @@ sl:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2548,7 +2604,6 @@ sl:
avatar: Avatar
base: 'Splošna napaka:'
body: Body
- blocks_ids: ID blokiranih delovnih paketov
category: Kategorija
comment: Komentar
comments: Komentar
@@ -2866,8 +2921,8 @@ sl:
- avgust
- september
- oktober
- - november
- - december
+ - November
+ - December
order:
- :leto
- :mesec
@@ -3045,6 +3100,7 @@ sl:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Neomejeno
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3520,6 +3576,11 @@ sl:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3582,6 +3643,72 @@ sl:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Prevzemnik
@@ -3613,6 +3740,7 @@ sl:
invalid_filter: Invalid notification filter
label_accessibility: Dostopnost
label_account: Račun
+ label_actions: Akcije
label_active: Aktivno
label_activate_user: Aktivirajte uporabnika
label_active_in_new_projects: Aktivno v novih projektih
@@ -3653,6 +3781,7 @@ sl:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Prekliči
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Uveljavljeno stanje
label_archive_project: Arhivirani projekti
@@ -3903,7 +4032,7 @@ sl:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Skoči na projekt...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Ključne besede
label_language_based: Glede na uporabnikov jezik
label_last_activity: Zadnja aktivnost
@@ -3941,6 +4070,10 @@ sl:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Prilagodi favicon
label_custom_touch_icon: Ikona za dotik po meri
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Odjava
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Stranski meni
@@ -5029,6 +5162,7 @@ sl:
'
setting_app_subtitle: Podnaslov aplikacije
setting_app_title: Naslov aplikacije
+ setting_organization_name: Organization name
setting_attachment_max_size: Največja velikost priponke
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5181,12 +5315,12 @@ sl:
setting_welcome_text: Dobrodošli blok besedila
setting_welcome_title: Dobrodošli blok naslov
setting_welcome_on_homescreen: Prikažite blok dobrodošlice na osnovnem zaslonu
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Privzeti način osvetlitve
diff --git a/config/locales/crowdin/sr.yml b/config/locales/crowdin/sr.yml
index 329a70a966d..d8a7eb7a63b 100644
--- a/config/locales/crowdin/sr.yml
+++ b/config/locales/crowdin/sr.yml
@@ -114,7 +114,7 @@ sr:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ sr:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ sr:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ sr:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -393,9 +394,9 @@ sr:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -404,10 +405,14 @@ sr:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
few: "... %{count} more projects"
@@ -423,7 +428,7 @@ sr:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -690,6 +695,37 @@ sr:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1358,6 +1394,20 @@ sr:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1554,6 +1604,9 @@ sr:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1562,7 +1615,7 @@ sr:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1818,6 +1871,7 @@ sr:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1935,6 +1989,7 @@ sr:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -2001,6 +2056,7 @@ sr:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2503,7 +2559,6 @@ sr:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2980,6 +3035,7 @@ sr:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3450,6 +3506,11 @@ sr:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3512,6 +3573,72 @@ sr:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Zadužen
@@ -3543,6 +3670,7 @@ sr:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3583,6 +3711,7 @@ sr:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3833,7 +3962,7 @@ sr:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3871,6 +4000,10 @@ sr:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4948,6 +5081,7 @@ sr:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5094,12 +5228,12 @@ sr:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/sv.yml b/config/locales/crowdin/sv.yml
index a3b8b2602e8..a8fcc9c1ca4 100644
--- a/config/locales/crowdin/sv.yml
+++ b/config/locales/crowdin/sv.yml
@@ -114,7 +114,7 @@ sv:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ sv:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ sv:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ sv:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ sv:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ sv:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ sv:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ sv:
danger_dialog:
confirmation_live_message_checked: Knappen för att fortsätta är nu aktiv.
confirmation_live_message_unchecked: Knappen för att fortsätta är nu inaktiv. Du måste markera kryssrutan för att fortsätta.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ sv:
index:
no_results_title_text: Det finns för närvarande inga arbetsflöden.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ sv:
dependencies: Beroenden
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ sv:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Visa fram till
attachment:
@@ -1800,6 +1853,7 @@ sv:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ sv:
confirmation: matchar inte %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ sv:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ sv:
avatar: Avatar
base: 'Allmänt fel:'
body: Body
- blocks_ids: ID:n för blockerade arbetspaket
category: Kategori
comment: Kommentar
comments: Kommentar
@@ -2922,6 +2977,7 @@ sv:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Obegränsad
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ sv:
quick_add:
label: Lägg till…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ sv:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Okänd lagring
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Tilldelad till
@@ -3484,6 +3611,7 @@ sv:
invalid_filter: Invalid notification filter
label_accessibility: Tillgänglighet
label_account: Konto
+ label_actions: Åtgärder
label_active: Aktiv
label_activate_user: Aktivera användare
label_active_in_new_projects: Aktiv i nya projekt
@@ -3524,6 +3652,7 @@ sv:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: senaste
label_ical_access_key_revoke: Återkalla
+ label_integrations: Integrations
label_add_column: Lägg till kolumn
label_applied_status: Tillämpad status
label_archive_project: Arkivera projekt
@@ -3774,7 +3903,7 @@ sv:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Hoppa till projekt...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Nyckelord
label_language_based: Baserat på användarens språk
label_last_activity: Senaste aktivitet
@@ -3812,6 +3941,10 @@ sv:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Anpassad favicon
label_custom_touch_icon: Anpassad touch-ikon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Logga ut
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Sidomenyn
@@ -4872,6 +5005,7 @@ sv:
'
setting_app_subtitle: Undertitel för applikation
setting_app_title: Programnamn
+ setting_organization_name: Organization name
setting_attachment_max_size: Bilaga max. storlek
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5018,12 +5152,12 @@ sv:
setting_welcome_text: Textblock för välkomstmeddelande
setting_welcome_title: Textblock för välkomsttitel
setting_welcome_on_homescreen: Visa välkomstblocket på hemsidan
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Standardläge för markering
diff --git a/config/locales/crowdin/th.yml b/config/locales/crowdin/th.yml
index a8f5aca3495..72371829626 100644
--- a/config/locales/crowdin/th.yml
+++ b/config/locales/crowdin/th.yml
@@ -114,7 +114,7 @@ th:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ th:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ th:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ th:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -381,9 +382,9 @@ th:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ th:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ th:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -674,6 +679,37 @@ th:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1324,6 +1360,20 @@ th:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1518,6 +1568,9 @@ th:
dependencies: ส่วนที่อ้างอิง
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1526,7 +1579,7 @@ th:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1782,6 +1835,7 @@ th:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1899,6 +1953,7 @@ th:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1965,6 +2020,7 @@ th:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2427,7 +2483,6 @@ th:
avatar: รูปโปรไฟล์
base: 'ข้อผิดพลาดทั่วไป:'
body: Body
- blocks_ids: Id ของแพคเกจการทำงานที่ถูกบล็อก
category: ประเภท
comment: ความคิดเห็น
comments: ความคิดเห็น
@@ -2864,6 +2919,7 @@ th:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3332,6 +3388,11 @@ th:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3394,6 +3455,72 @@ th:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: ผู้ได้รับมอบหมาย
@@ -3425,6 +3552,7 @@ th:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: บัญชี
+ label_actions: Actions
label_active: ใช้งานอยู่
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3465,6 +3593,7 @@ th:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: ใช้สถานะ
label_archive_project: Archive project
@@ -3715,7 +3844,7 @@ th:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: ไปยังโครงการ...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: ตามภาษาของผู้ใช้
label_last_activity: Last activity
@@ -3753,6 +3882,10 @@ th:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: ออกจากระบบ
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: เมนูด้านข้าง
@@ -4820,6 +4953,7 @@ th:
'
setting_app_subtitle: หัวข้อย่อยของแอบพลิเคชั่น
setting_app_title: หัวข้อแอบพลิเคชั่น
+ setting_organization_name: Organization name
setting_attachment_max_size: ขนาดสูงสุดของไฟล์แนบ
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -4966,12 +5100,12 @@ th:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/tr.yml b/config/locales/crowdin/tr.yml
index b490ab99604..6fb48551fb9 100644
--- a/config/locales/crowdin/tr.yml
+++ b/config/locales/crowdin/tr.yml
@@ -114,7 +114,7 @@ tr:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ tr:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ tr:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ tr:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ tr:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ tr:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ tr:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -683,6 +688,37 @@ tr:
danger_dialog:
confirmation_live_message_checked: Devam etmek için düğme artık aktif.
confirmation_live_message_unchecked: Devam etmek için düğme artık aktif değil. Devam etmek için işratlemeniz gerekli.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1342,6 +1378,20 @@ tr:
index:
no_results_title_text: Sitemizde şuan iş akışı yok.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1537,6 +1587,9 @@ tr:
dependencies: Bağımlılıklar
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1545,7 +1598,7 @@ tr:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Son yayın tarihi
attachment:
@@ -1801,6 +1854,7 @@ tr:
identity_url: Kimlik URL'si
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1918,6 +1972,7 @@ tr:
confirmation: "%{attribute} eşleşmiyor."
could_not_be_copied: "%{dependency} (tam olarak) kopyalanamadı."
does_not_exist: mevcut değil.
+ 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: erişilemez.
error_readonly: yazılmaya çalışıldı fakat yazılabilir değil.
@@ -1988,6 +2043,7 @@ tr:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2470,7 +2526,6 @@ tr:
avatar: Avatar
base: 'Genel Hata:'
body: Gövde
- blocks_ids: Engellenen iş paketlerinin ID'leri
category: Kategori
comment: Yorum
comments: Yorum
@@ -2927,6 +2982,7 @@ tr:
title: Kurumsal eklenti
plan_title: Kurumsal %{plan} eklentisi
plan_name: "%{plan} kurumsal plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: "%{plan_name} ile başlayarak kullanılabilir."
unlimited: Sınırsız
already_have_token: 'Zaten bir anahtarınız mı var? Rezervasyonlu Enterprise plana yükseltmek için aşağıdaki düğmeyi kullanarak ekleyin.
@@ -3396,6 +3452,11 @@ tr:
quick_add:
label: Ekle…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3458,6 +3519,72 @@ tr:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Bilinmeyen depolama
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Atanan
@@ -3489,6 +3616,7 @@ tr:
invalid_filter: Geçersiz bildirim filtresi
label_accessibility: Erişilebilirlik
label_account: Hesap
+ label_actions: Eylemler
label_active: Aktif
label_activate_user: Aktif kullanıcı
label_active_in_new_projects: Yeni projelerde etkin
@@ -3529,6 +3657,7 @@ tr:
label_ical_access_key_generation_hint: Bir takvime abone olunduğunda otomatik olarak oluşturulur.
label_ical_access_key_latest: en son
label_ical_access_key_revoke: İptal et
+ label_integrations: Integrations
label_add_column: Sütun ekle
label_applied_status: Uygulanan statü
label_archive_project: Projeyi arşivle
@@ -3779,7 +3908,7 @@ tr:
label_external_links: Harici Bağlantılar
label_locale: Dil ve bölge
label_jump_to_a_project: Projeye git...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Anahtar kelimeler
label_language_based: Kullanıcının dili tabanlı
label_last_activity: Son Aktivite
@@ -3817,6 +3946,10 @@ tr:
label_custom_pdf_export_settings: Özel PDF dışa aktarma ayarları
label_custom_favicon: Özel favicon
label_custom_touch_icon: Özel dokunma simgesi
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Oturumu kapat
label_mapping_for: "%{attribute} için eşleme"
label_main_menu: Yan menü
@@ -4888,6 +5021,7 @@ tr:
'
setting_app_subtitle: Uygulama alt başlığı
setting_app_title: Uygulama başlığı
+ setting_organization_name: Organization name
setting_attachment_max_size: En büyük ek boyutu
setting_show_work_package_attachments: Ekleri varsayılan olarak dosyalar sekmesinde göster
setting_antivirus_scan_mode: Tarama modu
@@ -5032,12 +5166,12 @@ tr:
setting_welcome_text: Hoş geldiniz blok metini
setting_welcome_title: Hoş geldiniz blok başlığı
setting_welcome_on_homescreen: Hoşgeldiniz bloğunu ana ekranda göster
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Varsayılan vurgulama modu
diff --git a/config/locales/crowdin/uk.yml b/config/locales/crowdin/uk.yml
index ae2569fde7f..0ed8fee4164 100644
--- a/config/locales/crowdin/uk.yml
+++ b/config/locales/crowdin/uk.yml
@@ -114,7 +114,7 @@ uk:
import:
title: Iмпорт
jira:
- title: Імпорт із Jira
+ title: Jira Migrator
description: Використовуйте цей інструмент для імпорту даних зі свого екземпляра Jira. Ви можете налаштувати кілька хостів Jira й вибрати, що імпортувати в кожному циклі імпорту.
errors:
cannot_delete_with_imports: Не вдається видалити хост Jira з наявними процесами імпорту
@@ -125,8 +125,8 @@ uk:
title: Конфігурація Jira
new: Нова конфігурація
banner:
- title: Обмежений імпорт
- description: 'Цей інструмент зараз доступний лише як бета-версія і може імпортувати тільки основні дані: проєкти, задачі (назву, заголовок, опис, вкладення), користувачів (ім’я, електронну адресу, дані про участь у проєктах), статуси й типи. Він не може імпортувати робочі процеси, користувацькі поля, зв’язки між задачами чи дозволи. Зараз ми підтримуємо лише версії Jira Server / Data Center 10.x і 11.x. Хмарні екземпляри поки що не підтримуються.'
+ title: Обмежені можливості імпорту
+ description: 'Інструмент Jira Migrator зараз доступний лише як бета-версія і може імпортувати тільки основні дані: проєкти, задачі (назву, заголовок, опис, вкладення), користувачів (ім’я, електронну адресу, дані про участь у проєктах), статуси й типи. Він не може імпортувати робочі процеси, користувацькі поля, зв’язки між задачами чи дозволи. Зараз ми підтримуємо лише версії Jira Server / Data Center 10.x і 11.x. Хмарні екземпляри поки що не підтримуються.'
form:
fields:
name: Назва
@@ -154,6 +154,7 @@ uk:
connection_timeout: 'Час очікування на встановлення з’єднання до сервера Jira минув: %{message}'
parse_error: 'Не вдалося проаналізувати відповідь Jira API: %{message}'
api_error: Інтерфейс Jira API повернув статус помилки «%{status}»
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Проєкти
last_change: Остання зміна
@@ -162,7 +163,7 @@ uk:
run:
title: Цикл імпорту
history: Історія
- remove_error: Імпорт Jira не можна видалити, поки він виконується
+ remove_error: Цикл імпорту Jira не можна видалити, поки він виконується
import_blocked_error: Зараз виконується або очікує на перевірку ще один цикл імпорту Jira. Завершіть або скасуйте його, якщо потрібно почати новий імпорт.
project_identifier_taken: 'Ви намагаєтесь імпортувати проєкт з ідентифікатором, який уже використовується: %{taken_identifier}. Будь ласка, оновіть ідентифікатор проєкту в Jira, а потім натисніть на кнопку «Повторити спробу».'
blank:
@@ -399,9 +400,9 @@ uk:
notification_text_default: "
Вітаємо,
Новий проєкт створено: projectValue:name
Дякуємо
\n"
work_packages_identifier:
page_header:
- description: Виберіть звичайні числові ідентифікатори пакетів робіт або ідентифікатори із зазначенням проєкту (до ідентифікатора пакета робіт додається префікс з ідентифікатором проєкту).
+ description: Виберіть класичні числові ідентифікатори пакетів робіт або семантичні із зазначенням проєкту (до ідентифікатора пакета робіт додається префікс з ідентифікатором проєкту).
banner:
- existing_identifiers_notice: 'Наявні ідентифікатори для кількох проєктів (%{project_count}) не відповідають вимогам до буквено-цифрових ідентифікаторів із зазначенням проєктів. OpenProject може автоматично оновити їх, щоб вони стали дійсними, як показано в прикладах нижче. Натисніть кнопку «Виправити й зберегти», щоб оновити в такий спосіб ідентифікатори для всіх проєктів і ввімкнути буквено-цифрові ідентифікатори із зазначенням проєктів.
+ existing_identifiers_notice: 'Наявні ідентифікатори для кількох проєктів (%{project_count}) не відповідають вимогам до семантичних ідентифікаторів із зазначенням проєктів. OpenProject може автоматично оновити їх, щоб вони стали дійсними, як показано в прикладах нижче. Натисніть кнопку «Виправити й зберегти», щоб оновити в такий спосіб ідентифікатори для всіх проєктів і ввімкнути семантичні ідентифікатори із зазначенням проєктів.
'
box_header:
@@ -410,10 +411,14 @@ uk:
label_autofixed_suggestion: Майбутній ідентифікатор
label_example_work_package_id: Приклад ідентифікатора пакета робіт
autofix_preview:
- error_too_long: Має містити менше ніж 5 символів
+ error_too_long: Має містити щонайбільше 10 символів
+ error_numerical: Не може містити лише числа
+ error_starts_with_number: Не може починатись із числа
error_special_characters: Не дозволяється використовувати спеціальні символи
+ error_not_fully_uppercased: Літери мають бути великими
error_in_use: Уже використовується як активний дескриптор іншого проєкту
error_reserved: Зарезервовано в історії дескрипторів іншого проєкту
+ error_unknown: Потребує ручної перевірки
remaining_projects:
one: "… ще 1 проєкт"
few: "… ще %{count} проєкти"
@@ -430,7 +435,7 @@ uk:
checkbox_label: Я розумію, що ця дія назавжди змінить усі ідентифікатори пакетів робіт
success_banner: Формат ідентифікаторів пакетів робіт успішно оновлено.
in_progress:
- banner_message: Ідентифікатори проєктів зараз замінюються на буквено-цифрові ідентифікатори із зазначенням проєктів. Це може зайняти деякий час.
+ banner_message: Ідентифікатори проєктів зараз замінюються на семантичні ідентифікатори із зазначенням проєктів. Це може зайняти деякий час.
workflows:
tabs:
default_transitions: Стандартні переходи
@@ -698,6 +703,37 @@ uk:
danger_dialog:
confirmation_live_message_checked: Кнопка для продовження активна.
confirmation_live_message_unchecked: Кнопка для продовження зараз неактивна. Щоб продовжити, поставте прапорець.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Розбиття на сторінки
prev: Попереднє
@@ -1372,6 +1408,20 @@ uk:
index:
no_results_title_text: Наразі немає робочих процесів.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1567,6 +1617,9 @@ uk:
dependencies: Залежності
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Ідентифікатор
+ work_package: Робочий пакет
jira_import:
projects: Проєкти
import/jira:
@@ -1575,7 +1628,7 @@ uk:
personal_access_token: Персональний маркер доступу
import/jira_open_project_reference:
jira: Jira
- jira_import: Імпорт із Jira
+ jira_import: Jira Migrator
announcements:
show_until: Показувати до
attachment:
@@ -1831,6 +1884,7 @@ uk:
identity_url: URL-адреса ідентичності
parent: Батьківська група
organizational_unit: Організаційний підрозділ
+ group_users: Group users
group_detail:
parent: Батьківська група
organizational_unit: Організаційний підрозділ
@@ -1948,6 +2002,7 @@ uk:
confirmation: не збігається %{attribute}
could_not_be_copied: "%{dependency} не вдалося скопіювати (повністю)."
does_not_exist: не існує.
+ user_already_in_department: User %{user_id} is already a member of department %{department_id}.
error_enterprise_only: "%{action} можна лише у версії OpenProject Enterprise."
error_unauthorized: "– можливо, немає доступу."
error_readonly: "– було здійснено спробу запису, але елемент недоступний для запису."
@@ -2016,6 +2071,7 @@ uk:
attributes:
parent_id:
circular_dependency: призведе до створення ієрархії циклічної групи.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2540,7 +2596,6 @@ uk:
avatar: Аватар
base: 'Загальна помилка:'
body: Текст
- blocks_ids: Ідентифікатори заблокованих робочих пакетів
category: Категорія
comment: Коментар
comments: Коментар
@@ -3037,6 +3092,7 @@ uk:
title: Доповнення версії Enterprise
plan_title: Доповнення версії Enterprise %{plan}
plan_name: Версія Enterprise %{plan}
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Доступно, починаючи з версії %{plan_name}.
unlimited: Без обмежень
already_have_token: 'Уже маєте маркер? Додайте його за допомогою кнопки нижче, щоб перейти на вже замовлений план Enterprise.
@@ -3508,6 +3564,11 @@ uk:
quick_add:
label: Додати…
my_account:
+ notifications_and_email:
+ title: Сповіщення й електронні листи
+ tabs:
+ notifications: Налаштування сповіщень
+ email_reminders: Нагадування електронною поштою
access_tokens:
description: Маркери постачальника послуг випускаються в OpenProject, що дає змогу іншим додаткам отримувати до них доступ. Клієнтські маркери випускаються іншими додатками, що дає змогу OpenProject отримати до них доступ.
no_results:
@@ -3570,6 +3631,72 @@ uk:
disabled_text: Маркери API не ввімкнено адміністратором. Зверніться до нього, якщо вам потрібна ця функція.
storages:
unknown_storage: Невідоме сховище
+ email_reminders:
+ immediate_reminders:
+ title: Надсилати мені нагадування електронною поштою
+ mentioned: Повідомляти мене, коли мене згадують
+ personal_reminder: Повідомляти мене про персональні нагадування
+ daily_reminders:
+ title: Надсилати мені щоденні нагадування електронною поштою про непрочитані сповіщення
+ caption: Ви отримуватимете лише нагадування про непрочитані сповіщення, і вони надходитимуть тільки у вказаний вами час. Доки ви не налаштуєте для свого облікового запису часовий пояс, використовуватиметься UTC.
+ enabled: Увімкнути щоденні нагадування електронною поштою
+ add_time: Додати час
+ remove_time: Вилучити час
+ time_slot_label: Час нагадування (UTC)
+ workdays:
+ title: Отримувати нагадування електронною поштою в ці дні
+ submit_button: Оновити дні нагадувань
+ pause_reminders:
+ title: Призупинити сповіщення електронною поштою
+ enabled: Тимчасово призупинити щоденні нагадування, що надсилаються електронною поштою
+ date_range: Період призупинення
+ email_alerts:
+ title: Сповіщення електронною поштою для інших елементів, які не є пакетами робіт
+ news_added: Новину додано
+ news_commented: Коментар щодо новини
+ document_added: Документ додано
+ forum_messages: Повідомлення на форумі опубліковано
+ wiki_page_added: Wiki-сторінку додано
+ wiki_page_updated: Wiki-сторінку оновлено
+ membership_added: Членство додано
+ membership_updated: Членство оновлено
+ submit_button: Оновити сповіщення
+ notifications:
+ participating:
+ title: Бере участь
+ submit_button: Оновити налаштування
+ mentioned: Вас згадали
+ watched: Відстеження
+ assignee: Виконавець
+ responsible: Відповідальний
+ shared: Доступ надано мені
+ date_alerts:
+ title: Сповіщення про дати
+ submit_button: Оновити сповіщення про дати
+ start_date: Дата початку
+ due_date: Дата завершення
+ overdue: Прострочено
+ times:
+ same_day: Того самого дня
+ one_day_before: За 1 день
+ three_days_before: За 3 дні
+ seven_days_before: За 7 днів
+ one_day_after: Через 1 день
+ three_days_after: Через 3 дні
+ seven_days_after: Через 7 днів
+ non_participating:
+ title: Не бере участі
+ submit_button: Оновити налаштування
+ work_package_created: Нові пакети робіт
+ work_package_commented: Усі нові коментарі
+ work_package_processed: Усі зміни статусу
+ work_package_prioritized: Усі зміни пріоритету
+ work_package_scheduled: Усі зміни дат
+ project_specific_settings:
+ title: Налаштування сповіщень щодо проєктів
+ add_button: Додати сповіщення щодо проєктів
+ dialog_title: Додати сповіщення щодо проєктів
+ list_header: Проєкти зі спеціальними сповіщеннями
notifications:
reasons:
assigned: Виконавець
@@ -3601,6 +3728,7 @@ uk:
invalid_filter: Недійсний фільтр сповіщень
label_accessibility: Розробникам також потрібно оплачувати свої рахунки. З доступністю
label_account: Обліковий запис
+ label_actions: Дії
label_active: Активні
label_activate_user: Активні користувачі
label_active_in_new_projects: Активна участь в нових проектах
@@ -3641,6 +3769,7 @@ uk:
label_ical_access_key_generation_hint: Автоматично створено під час оформлення підписки на календар.
label_ical_access_key_latest: останні
label_ical_access_key_revoke: Анулювати
+ label_integrations: Інтеграції
label_add_column: Додати стовпець
label_applied_status: Застосовний статус
label_archive_project: Архівний проект
@@ -3869,7 +3998,7 @@ uk:
label_index_by_title: Індекс за назвою
label_information: Інформація
label_information_plural: Інформація
- label_installation_guides: Інструкції із встановлення
+ label_installation_guides: Інструкції зі встановлення
label_integer: Ціле число
label_interface: Інтерфейс
label_internal: Власне
@@ -3891,7 +4020,7 @@ uk:
label_external_links: Зовнішні посилання
label_locale: Мова й регіон
label_jump_to_a_project: Перейти до проекту...
- label_jira_import: Імпорт із Jira
+ label_jira_import: Jira Migrator
label_keyword_plural: Ключові слова
label_language_based: На основі мови користувача
label_last_activity: Остання активність
@@ -3929,6 +4058,10 @@ uk:
label_custom_pdf_export_settings: Налаштування експорту PDF
label_custom_favicon: призначені для користувача іконки
label_custom_touch_icon: Призначений для користувача значок логотипу
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Вийти
label_mapping_for: 'Зіставлення для: %{attribute}'
label_main_menu: Бокове меню
@@ -5010,6 +5143,7 @@ uk:
'
setting_app_subtitle: Підзаголовок додатку
setting_app_title: Назва додатку
+ setting_organization_name: Organization name
setting_attachment_max_size: Максимальний розмір вкладення
setting_show_work_package_attachments: За замовчуванням показувати вкладення на вкладці «Файли»
setting_antivirus_scan_mode: Режим перевірки
@@ -5156,12 +5290,12 @@ uk:
setting_welcome_text: Текст блоку привітання
setting_welcome_title: Заголовок вітального блоку
setting_welcome_on_homescreen: Відображати вітальний блок на робочому столі
- setting_work_packages_identifier_numeric: Числова послідовність для всього екземпляра (за умовчанням)
- setting_work_packages_identifier_numeric_caption: 'Кожному пакету робіт присвоюється порядковий номер, який починається з одиниці й збільшується з кожним новим пакетом. Номери є унікальними в межах цього екземпляра, тому залишаються незмінними, навіть якщо пакети робіт переміщуються між проєктами.
+ setting_work_packages_identifier_classic: Числова послідовність для всього екземпляра (за умовчанням)
+ setting_work_packages_identifier_classic_caption: 'Кожному пакету робіт присвоюється порядковий номер, який починається з одиниці й збільшується з кожним новим пакетом. Номери є унікальними в межах цього екземпляра, тому залишаються незмінними, навіть якщо пакети робіт переміщуються між проєктами.
'
- setting_work_packages_identifier_alphanumeric: Буквено-цифрові ідентифікатори із зазначенням проєктів
- setting_work_packages_identifier_alphanumeric_caption: 'Кожен проєкт має унікальний ідентифікатор, який додається як префікс до ідентифікатора пакета робіт. Якщо пакет робіт переміщується в інший проєкт, генерується новий ідентифікатор, однак старий продовжує працювати.
+ setting_work_packages_identifier_semantic: Семантичні ідентифікатори із зазначенням проєктів
+ setting_work_packages_identifier_semantic_caption: 'Кожен проєкт має унікальний ідентифікатор, який додається як префікс до ідентифікатора пакета робіт. Якщо пакет робіт переміщується в інший проєкт, генерується новий ідентифікатор, однак старий продовжує працювати.
'
setting_work_package_list_default_highlighting_mode: Режим виділення за умовчанням
diff --git a/config/locales/crowdin/uz.yml b/config/locales/crowdin/uz.yml
index a89d5fcb699..f841cfed500 100644
--- a/config/locales/crowdin/uz.yml
+++ b/config/locales/crowdin/uz.yml
@@ -114,7 +114,7 @@ uz:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ uz:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ uz:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ uz:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -387,9 +388,9 @@ uz:
notification_text_default: "
Hello,
A new project has been created: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -398,10 +399,14 @@ uz:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -416,7 +421,7 @@ uz:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Default transitions
@@ -682,6 +687,37 @@ uz:
danger_dialog:
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
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1341,6 +1377,20 @@ uz:
index:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1536,6 +1586,9 @@ uz:
dependencies: Dependencies
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1544,7 +1597,7 @@ uz:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Display until
attachment:
@@ -1800,6 +1853,7 @@ uz:
identity_url: Identity URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1917,6 +1971,7 @@ uz:
confirmation: doesn't match %{attribute}.
could_not_be_copied: "%{dependency} could not be (fully) copied."
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.
@@ -1983,6 +2038,7 @@ uz:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2465,7 +2521,6 @@ uz:
avatar: Avatar
base: 'General Error:'
body: Body
- blocks_ids: IDs of blocked work packages
category: Category
comment: Comment
comments: Comment
@@ -2922,6 +2977,7 @@ uz:
title: Enterprise add-on
plan_title: Enterprise %{plan} add-on
plan_name: "%{plan} enterprise plan"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Available starting with the %{plan_name}.
unlimited: Unlimited
already_have_token: 'Already have a token? Add it using the button below to upgrade to the booked Enterprise plan.
@@ -3391,6 +3447,11 @@ uz:
quick_add:
label: Add…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them.
no_results:
@@ -3453,6 +3514,72 @@ uz:
disabled_text: RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature.
storages:
unknown_storage: Unknown storage
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Assignee
@@ -3484,6 +3611,7 @@ uz:
invalid_filter: Invalid notification filter
label_accessibility: Accessibility
label_account: Account
+ label_actions: Actions
label_active: Active
label_activate_user: Activate user
label_active_in_new_projects: Active in new projects
@@ -3524,6 +3652,7 @@ uz:
label_ical_access_key_generation_hint: Automatically generated when subscribing to a calendar.
label_ical_access_key_latest: latest
label_ical_access_key_revoke: Revoke
+ label_integrations: Integrations
label_add_column: Add column
label_applied_status: Applied status
label_archive_project: Archive project
@@ -3774,7 +3903,7 @@ uz:
label_external_links: External links
label_locale: Language and region
label_jump_to_a_project: Jump to a project...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Keywords
label_language_based: Based on user's language
label_last_activity: Last activity
@@ -3812,6 +3941,10 @@ uz:
label_custom_pdf_export_settings: Custom PDF export settings
label_custom_favicon: Custom favicon
label_custom_touch_icon: Custom touch icon
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Sign out
label_mapping_for: 'Mapping for: %{attribute}'
label_main_menu: Side Menu
@@ -4884,6 +5017,7 @@ uz:
'
setting_app_subtitle: Application subtitle
setting_app_title: Application title
+ setting_organization_name: Organization name
setting_attachment_max_size: Attachment max. size
setting_show_work_package_attachments: Show attachments in the files tab by default
setting_antivirus_scan_mode: Scan mode
@@ -5030,12 +5164,12 @@ uz:
setting_welcome_text: Welcome block text
setting_welcome_title: Welcome block title
setting_welcome_on_homescreen: Display welcome block on homescreen
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Default highlighting mode
diff --git a/config/locales/crowdin/vi.yml b/config/locales/crowdin/vi.yml
index 253835d638b..8c27085ad87 100644
--- a/config/locales/crowdin/vi.yml
+++ b/config/locales/crowdin/vi.yml
@@ -114,7 +114,7 @@ vi:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ vi:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ vi:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ vi:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -381,9 +382,9 @@ vi:
notification_text_default: "
Xin chào,
Một dự án mới đã được tạo: projectValue:name
Thank you
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ vi:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ vi:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: Chuyển tiếp mặc định
@@ -676,6 +681,37 @@ vi:
danger_dialog:
confirmation_live_message_checked: Nút để tiếp tục hiện đang hoạt động.
confirmation_live_message_unchecked: Nút để tiếp tục hiện không hoạt động. Bạn cần đánh dấu vào hộp kiểm để tiếp tục.
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1326,6 +1362,20 @@ vi:
index:
no_results_title_text: Hiện tại không có quy trình làm việc nào.
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1520,6 +1570,9 @@ vi:
dependencies: phụ thuộc
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1528,7 +1581,7 @@ vi:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: Hiển thị cho đến khi
attachment:
@@ -1784,6 +1837,7 @@ vi:
identity_url: URL nhận dạng
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1901,6 +1955,7 @@ vi:
confirmation: không khớp %{attribute}.
could_not_be_copied: "%{dependency} không thể sao chép (đầy đủ)."
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.
@@ -1967,6 +2022,7 @@ vi:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2429,9 +2485,8 @@ vi:
avatar: hình đại diện
base: 'Lỗi tổng quan:'
body: cơ thể
- blocks_ids: ID của các work package bị chặn
category: thể loại
- comment: bình luận
+ comment: Nhận xét
comments: bình luận
content: Nội dung
color: màu sắc
@@ -2866,6 +2921,7 @@ vi:
title: Tiện ích bổ sung dành cho doanh nghiệp
plan_title: Tiện ích bổ sung %{plan} dành cho doanh nghiệp
plan_name: "%{plan} kế hoạch doanh nghiệp"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: Có sẵn bắt đầu với %{plan_name}.
unlimited: Không giới hạn
already_have_token: 'Bạn đã có mã thông báo chưa? Thêm nó bằng nút bên dưới để nâng cấp lên gói Enterprise đã đặt.
@@ -3334,6 +3390,11 @@ vi:
quick_add:
label: Thêm vào…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: Mã thông báo của nhà cung cấp được OpenProject phát hành, cho phép các ứng dụng khác truy cập vào nó. Mã thông báo của khách hàng được phát hành bởi các ứng dụng khác, cho phép OpenProject truy cập chúng.
no_results:
@@ -3396,6 +3457,72 @@ vi:
disabled_text: Mã thông báo RSS không được quản trị viên kích hoạt. Vui lòng liên hệ với quản trị viên của bạn để sử dụng tính năng này.
storages:
unknown_storage: Bộ nhớ không xác định
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: Người được chuyển nhượng
@@ -3427,6 +3554,7 @@ vi:
invalid_filter: Bộ lọc thông báo không hợp lệ
label_accessibility: Trợ năng
label_account: tài khoản
+ label_actions: hành động
label_active: Đang hoạt động
label_activate_user: Người dùng kích họat
label_active_in_new_projects: Tích cực trong các dự án mới
@@ -3467,6 +3595,7 @@ vi:
label_ical_access_key_generation_hint: Tự động được tạo khi đăng ký lịch.
label_ical_access_key_latest: mới nhất
label_ical_access_key_revoke: Thu hồi
+ label_integrations: Integrations
label_add_column: Thêm cột
label_applied_status: Tình trạng áp dụng
label_archive_project: Lưu trữ dự án
@@ -3717,7 +3846,7 @@ vi:
label_external_links: Liên kết ngoài
label_locale: Ngôn ngữ và khu vực
label_jump_to_a_project: Chuyển đến một dự án...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: Từ khóa
label_language_based: Dựa trên ngôn ngữ của người dùng
label_last_activity: Hoạt động cuối cùng
@@ -3755,6 +3884,10 @@ vi:
label_custom_pdf_export_settings: Cài đặt xuất PDF tùy chỉnh
label_custom_favicon: Favicon tuỳ chỉnh
label_custom_touch_icon: Tùy chỉnh biểu tượng ICON
+ label_departments: Organization
+ 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).
+
+ '
label_logout: Đăng xuất
label_mapping_for: 'Ánh xạ cho: %{attribute}'
label_main_menu: Menu bên
@@ -4039,7 +4172,7 @@ vi:
label_used_by: Được dùng bởi
label_used_by_types: Được sử dụng bởi các loại
label_used_in_projects: Được sử dụng trong các dự án
- label_user: người dùng
+ label_user: Người dùng
label_user_and_permission: Người dùng và quyền
label_user_named: Người dùng %{name}
label_user_activity_html: "%{value}'s activity"
@@ -4830,6 +4963,7 @@ vi:
'
setting_app_subtitle: phụ đề ứng dụng
setting_app_title: Tiêu đề ứng dụng
+ setting_organization_name: Organization name
setting_attachment_max_size: Tệp đính kèm tối đa. kích cỡ
setting_show_work_package_attachments: Hiển thị tệp đính kèm trong tab tệp theo mặc định
setting_antivirus_scan_mode: Chế độ quét
@@ -4976,12 +5110,12 @@ vi:
setting_welcome_text: Văn bản chặn chào mừng
setting_welcome_title: Tiêu đề khối chào mừng
setting_welcome_on_homescreen: Hiển thị khối chào mừng trên màn hình chính
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: Chế độ đánh dấu mặc định
diff --git a/config/locales/crowdin/zh-CN.seeders.yml b/config/locales/crowdin/zh-CN.seeders.yml
index 30e63f026bc..212a0e3692c 100644
--- a/config/locales/crowdin/zh-CN.seeders.yml
+++ b/config/locales/crowdin/zh-CN.seeders.yml
@@ -97,7 +97,7 @@ zh-CN:
demo-project:
name: 演示项目
status_explanation: 所有任务都按计划进行。相关人员均知晓各自任务。系统已完全建立。
- description: 这是对此演示 Scrum 项目目标的简短摘要。
+ description: 这是对此演示项目目标的简短摘要。
news:
item_0:
title: 欢迎来到您的演示项目
@@ -201,7 +201,7 @@ zh-CN:
scrum-project:
name: Scrum 项目
status_explanation: 所有任务都按计划进行。相关人员均知晓各自任务。系统已完全建立。
- description: 这是对此演示 Scrum 项目目标的简短摘要。
+ description: 这是对此演示Scrum项目目标的简短摘要。
news:
item_0:
title: 欢迎来到您的 Scrum 演示项目
diff --git a/config/locales/crowdin/zh-CN.yml b/config/locales/crowdin/zh-CN.yml
index 3e314bd7d38..be2321e0d20 100644
--- a/config/locales/crowdin/zh-CN.yml
+++ b/config/locales/crowdin/zh-CN.yml
@@ -89,7 +89,7 @@ zh-CN:
token_caption: 要详细了解如何激活企业版,请查阅我们的[文档](docs_url)。
add_token: 上传企业版支持令牌
replace_token: 替换您当前的支持令牌
- order: 订购本地部署版的 Enterprise edition
+ order: 订购本地部署的 Enterprise edition
paste: 粘贴您企业版的支持令牌
required_for_feature: 此功能仅限具激活的企业版支持令牌的订阅者使用。
enterprise_link: 如需了解详细信息,请单击此处。
@@ -114,7 +114,7 @@ zh-CN:
import:
title: 导入
jira:
- title: Jira 导入
+ title: Jira Migrator
description: 使用此工具从您的 Jira 实例中导入数据。您可以配置多个 Jira 主机,并选择每次导入运行要导入的内容。
errors:
cannot_delete_with_imports: 无法删除具有现有导入的 Jira 主机
@@ -125,8 +125,8 @@ zh-CN:
title: Jira 配置
new: 新配置
banner:
- title: 受限导入
- description: 此导入工具目前处于测试阶段,只能导入基本数据:项目、问题(名称、标题、描述、附件)、用户(名称、电子邮件地址、项目成员资格)、状态和类型。不能导入工作流、自定义字段、问题关系或权限。我们目前仅支持 Jira Server/Data Center 版本 10.x 和 11.x。目前不支持云实例。
+ title: 有限导入功能
+ description: Jira Migrator 目前处于测试阶段,只能导入基本数据:项目、问题(名称、标题、描述、附件)、用户(名称、电子邮件地址、项目成员资格)、状态和类型。不能导入工作流、自定义字段、问题关系或权限。我们目前仅支持 Jira Server/Data Center 版本 10.x 和 11.x。目前不支持云实例。
form:
fields:
name: 名称
@@ -154,6 +154,7 @@ zh-CN:
connection_timeout: 与 Jira 服务器的连接超时:%{message}
parse_error: 无法解析 Jira API 响应:%{message}
api_error: Jira API 返回错误状态 %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: 项目
last_change: 上次更改
@@ -162,7 +163,7 @@ zh-CN:
run:
title: 导入运行
history: 历史记录
- remove_error: 无法移除正在运行的 Jira 导入
+ remove_error: 无法移除正在运行的 Jira 导入运行
import_blocked_error: 另一个 Jira 导入运行当前正在执行或等待审核。请先完成或撤消当前运行,然后再开始新的导入。
project_identifier_taken: 您尝试导入的项目所使用的标识符 %{taken_identifier} 已经用过。请在 Jira 中更新项目标识符,然后点击“重试”。
blank:
@@ -381,19 +382,23 @@ zh-CN:
notification_text_default: "
您好!
已创建一个新项目:projectValue:name
谢谢
\n"
work_packages_identifier:
page_header:
- description: 可以选择经典的数字工作包 ID,或者将项目标识符作为工作包 ID 前缀的项目特定工作包 ID。
+ description: 可以选择经典的数字工作包 ID,或者将项目标识符作为工作包 ID 前缀的语义化项目特定工作包 ID。
banner:
- existing_identifiers_notice: "%{project_count} 个项目的现有标识符不符合基于项目的字母数字标识符要求。OpenProject 可以自动更新这些标识符,使其成为如下例中所示的有效格式。点击“自动修正并保存”按钮,以这种方式更新所有项目的标识符,并启用基于项目的字母数字标识符。\n"
+ existing_identifiers_notice: "%{project_count} 个项目的现有标识符不符合基于项目的语义标识符要求。OpenProject 可以自动更新这些标识符,使其成为如下例中所示的有效格式。点击“自动修正并保存”按钮,以这种方式更新所有项目的标识符,并启用基于项目的语义标识符。\n"
box_header:
label_project: 项目
label_previous_identifier: 上一个标识符
label_autofixed_suggestion: 未来标识符
label_example_work_package_id: 示例工作包 ID
autofix_preview:
- error_too_long: 必须少于 5 个字符
+ error_too_long: 必须为 10 个字符或更少字符
+ error_numerical: 不能只包含数字
+ error_starts_with_number: 不能以数字开头
error_special_characters: 不允许使用特殊字符
+ error_not_fully_uppercased: 必须为大写字母
error_in_use: 已用作另一个项目的有效标识名
error_reserved: 由另一个项目的标识名历史保留
+ error_unknown: 需要手动检查
remaining_projects:
other: "…其他 %{count} 个项目"
button_autofix: 自动修正并保存
@@ -407,7 +412,7 @@ zh-CN:
checkbox_label: 我了解此操作将永久更改所有工作包 ID
success_banner: 已成功更新工作包标识符格式。
in_progress:
- banner_message: 项目标识符目前正在更新为基于项目的字母数字标识符。此过程可能需要一些时间。
+ banner_message: 项目标识符目前正在更新为基于项目的语义标识符。此过程可能需要一些时间。
workflows:
tabs:
default_transitions: 默认转换
@@ -671,6 +676,37 @@ zh-CN:
danger_dialog:
confirmation_live_message_checked: 继续按钮现已激活。
confirmation_live_message_unchecked: 继续按钮现已失效。您需要勾选复选框才能继续。
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: 分页
prev: 上一页
@@ -1320,6 +1356,20 @@ zh-CN:
index:
no_results_title_text: 目前没有工作流。
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1514,6 +1564,9 @@ zh-CN:
dependencies: 依赖项
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: 标识符
+ work_package: 工作包
jira_import:
projects: 项目
import/jira:
@@ -1522,7 +1575,7 @@ zh-CN:
personal_access_token: 个人访问令牌
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira 导入
+ jira_import: Jira Migrator
announcements:
show_until: 显示截止日期
attachment:
@@ -1600,7 +1653,7 @@ zh-CN:
page: 页
row_count: 行数
column_count: 列数
- widgets: 微件
+ widgets: 小部件
journal:
notes: 备注
cause_type: Cause 类型
@@ -1778,6 +1831,7 @@ zh-CN:
identity_url: 身份 URL
parent: 父群组
organizational_unit: 组织单元
+ group_users: Group users
group_detail:
parent: 父群组
organizational_unit: 组织单元
@@ -1895,6 +1949,7 @@ zh-CN:
confirmation: 不匹配 %{attribute}。
could_not_be_copied: 无法(完全)复制 %{dependency}。
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: 曾尝试被写入,但不可写。
@@ -1961,6 +2016,7 @@ zh-CN:
attributes:
parent_id:
circular_dependency: 将创建循环群组层次结构。
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2423,7 +2479,6 @@ zh-CN:
avatar: 头像
base: 一般错误:
body: 正文
- blocks_ids: 被工作包阻止的IDs
category: 类别
comment: 注释
comments: 评论
@@ -2860,6 +2915,7 @@ zh-CN:
title: 企业附加组件
plan_title: 企业 %{plan} 附加组件
plan_name: "%{plan} 企业计划"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: 从 %{plan_name} 开始可用。
unlimited: 无限制
already_have_token: '已经有令牌?使用下方按钮添加以升级到预订的企业版方案。
@@ -3328,6 +3384,11 @@ zh-CN:
quick_add:
label: 添加…
my_account:
+ notifications_and_email:
+ title: 通知和电子邮件
+ tabs:
+ notifications: 通知设置
+ email_reminders: 电子邮件提醒
access_tokens:
description: 提供商令牌由 OpenProject 签发,允许其他应用程序访问。客户端令牌由其他应用程序签发,允许 OpenProject 对其进行访问。
no_results:
@@ -3390,6 +3451,72 @@ zh-CN:
disabled_text: 管理员未启用 RSS 令牌。请联系管理员以使用此功能。
storages:
unknown_storage: 未知存储
+ email_reminders:
+ immediate_reminders:
+ title: 向我发送电子邮件提醒
+ mentioned: 当我被提及时通知我
+ personal_reminder: 有个人提醒时通知我
+ daily_reminders:
+ title: 向我发送针对未读通知的每日电子邮件提醒
+ caption: 您仅会收到针对未读通知的提醒,且仅会在您指定的时间收到提醒。在您为帐户配置时区前,时间将解释为采用 UTC 格式。
+ enabled: 启用每日电子邮件提醒
+ add_time: 添加时间
+ remove_time: 移除时间
+ time_slot_label: 提醒时间 (UTC)
+ workdays:
+ title: 在如下日期接收电子邮件提醒
+ submit_button: 更新提醒日期
+ pause_reminders:
+ title: 暂停电子邮件通知
+ enabled: 临时暂停每日电子邮件提醒
+ date_range: 暂停时间段
+ email_alerts:
+ title: 其他条目(非工作包)的电子邮件提醒
+ news_added: 新闻已添加
+ news_commented: 评论新闻条目
+ document_added: 文档已添加
+ forum_messages: 论坛消息已发布
+ wiki_page_added: Wiki 页面已添加
+ wiki_page_updated: Wiki 页面已更新
+ membership_added: 成员资格已添加
+ membership_updated: 成员资格已更新
+ submit_button: 更新提醒
+ notifications:
+ participating:
+ title: 参与
+ submit_button: 更新偏好设置
+ mentioned: 被提及
+ watched: 关注中
+ assignee: 受理人
+ responsible: 负责人
+ shared: 与我共享
+ date_alerts:
+ title: 日期提醒
+ submit_button: 更新日期提醒
+ start_date: 开始日期
+ due_date: 完成日期
+ overdue: 逾期
+ times:
+ same_day: 当天
+ one_day_before: 提前 1 天
+ three_days_before: 提前 3 天
+ seven_days_before: 提前 7 天
+ one_day_after: 推后 1 天
+ three_days_after: 推后 3 天
+ seven_days_after: 推后 7 天
+ non_participating:
+ title: 不参与
+ submit_button: 更新偏好设置
+ work_package_created: 新工作包
+ work_package_commented: 所有新评论
+ work_package_processed: 所有状态更改
+ work_package_prioritized: 所有优先级更改
+ work_package_scheduled: 所有日期更改
+ project_specific_settings:
+ title: 项目特定通知设置
+ add_button: 添加项目特定通知
+ dialog_title: 添加项目特定通知
+ list_header: 具有特定通知的项目
notifications:
reasons:
assigned: 指定人
@@ -3421,6 +3548,7 @@ zh-CN:
invalid_filter: 无效的通知过滤器
label_accessibility: 辅助功能
label_account: 帐户
+ label_actions: 操作
label_active: 激活
label_activate_user: 激活用户
label_active_in_new_projects: 新项目动态
@@ -3461,6 +3589,7 @@ zh-CN:
label_ical_access_key_generation_hint: 订阅日历时自动生成的。
label_ical_access_key_latest: 最近
label_ical_access_key_revoke: 撤消
+ label_integrations: 集成
label_add_column: 添加列
label_applied_status: 应用的状态
label_archive_project: 归档项目
@@ -3711,7 +3840,7 @@ zh-CN:
label_external_links: 外部链接
label_locale: 语言和地区
label_jump_to_a_project: 跳转到一个项目...
- label_jira_import: Jira 导入
+ label_jira_import: Jira Migrator
label_keyword_plural: 关键词
label_language_based: 基于用户的语言
label_last_activity: 最近一次活动
@@ -3749,6 +3878,10 @@ zh-CN:
label_custom_pdf_export_settings: 自定义 PDF 导出设置
label_custom_favicon: 自定义图标
label_custom_touch_icon: 自定义触摸图标
+ label_departments: Organization
+ 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).
+
+ '
label_logout: 注销
label_mapping_for: 映射: %{attribute}
label_main_menu: 侧边菜单
@@ -3951,7 +4084,7 @@ zh-CN:
label_revision_id: 修订版本 %{value}
label_revision_plural: 修订
label_roadmap: 路线图
- label_roadmap_edit: 编辑路线图%{name}
+ label_roadmap_edit: 编辑路线图 %{name}
label_roadmap_due_in: "%{value} 到期"
label_roadmap_no_work_packages: 该版本没有工作包。
label_roadmap_overdue: "%{value} 超时"
@@ -4711,7 +4844,7 @@ zh-CN:
managed: 在 OpenProject 中创建新的存储库
storage:
not_available: 磁盘存储开销不可用于此存储库。
- update_timeout: 在 N 分钟内保留存储库最后所需的磁盘空间信息。由于计算存储库所需的磁盘空间可能增加系统开销,增加该值可以减少性能影响。
+ update_timeout: 在 N 分钟内保留存储库最后所需磁盘空间的信息。由于计算存储库所需的磁盘空间可能增加系统开销,增加该值可以减少性能影响。
oauth_application_details_html: 关闭此窗口后,将无法再次访问客户端密钥值。请将这些值复制到 Nextcloud OpenProject 集成设置中:
oauth_application_details_link_text: 转到设置页面
setup_documentation_details: 如果您在配置新文件存储方面需要帮助,请查看文档:
@@ -4809,6 +4942,7 @@ zh-CN:
'
setting_app_subtitle: 应用副标题
setting_app_title: 应用程序标题
+ setting_organization_name: Organization name
setting_attachment_max_size: 最大的附件大小
setting_show_work_package_attachments: 默认在文件选项卡中显示附件
setting_antivirus_scan_mode: 扫描模式
@@ -4939,7 +5073,7 @@ zh-CN:
setting_session_ttl_hint: 当设置的值低于5时,其作用类似于禁用。
setting_session_ttl_enabled: 会话过期
setting_start_of_week: 一周起始日
- setting_sys_api_enabled: 启用存储库管理网页服务
+ setting_sys_api_enabled: 启用版本库管理 web 服务
setting_sys_api_description: 存储库管理网页服务提供了集成的,用户授权的存储库访问。
setting_time_format: 时间
setting_total_percent_complete_mode: 计算 完成% 层次结构总数
@@ -4955,12 +5089,12 @@ zh-CN:
setting_welcome_text: 欢迎块文本
setting_welcome_title: 欢迎块标题
setting_welcome_on_homescreen: 在主屏幕上显示欢迎信息
- setting_work_packages_identifier_numeric: 实例范围的数字序列(默认)
- setting_work_packages_identifier_numeric_caption: '每个工作包会获得一个从 1 开始的顺序号,每新增一个工作包,编号会加 1。这些编号在此实例中是唯一的,因此即使工作包在项目之间移动,编号也不会改变。
+ setting_work_packages_identifier_classic: 实例范围的数字序列(默认)
+ setting_work_packages_identifier_classic_caption: '每个工作包会获得一个从 1 开始的顺序号,每新增一个工作包,编号会加 1。这些编号在此实例中是唯一的,因此即使工作包在项目之间移动,编号也不会改变。
'
- setting_work_packages_identifier_alphanumeric: 基于项目的字母数字标识符
- setting_work_packages_identifier_alphanumeric_caption: '每个项目都有一个唯一标识符,该标识符会附加到工作包 ID 前面。如果工作包移至另一个项目,则会生成新的标识符,但原标识符仍可继续使用。
+ setting_work_packages_identifier_semantic: 基于项目的语义标识符
+ setting_work_packages_identifier_semantic_caption: '每个项目都有一个唯一标识符,该标识符会附加到工作包 ID 前面。如果工作包移至另一个项目,则会生成新的标识符,但原标识符仍可继续使用。
'
setting_work_package_list_default_highlighting_mode: 默认突出显示模式
@@ -5425,7 +5559,7 @@ zh-CN:
warning_user_limit_reached_admin_html: '添加额外的用户将超出当前限值。请[升级您的方案](upgrade_url),以确保外部用户能够访问此实例。
'
- warning_user_limit_reached_instructions: '您已达到用户限制(%{current}/%{max} 活跃用户)。请联系 sales@openproject.com 升级您的企业版计划以添加额外用户。
+ warning_user_limit_reached_instructions: '您达到了用户限制(%{current}/%{max}活跃用户)。 请联系sales@openproject.com以升级您的Enterprise edition计划并添加其他用户。
'
warning_protocol_mismatch_html: ''
diff --git a/config/locales/crowdin/zh-TW.yml b/config/locales/crowdin/zh-TW.yml
index c46fb37257e..fd9cb8eca7d 100644
--- a/config/locales/crowdin/zh-TW.yml
+++ b/config/locales/crowdin/zh-TW.yml
@@ -114,7 +114,7 @@ zh-TW:
import:
title: Import
jira:
- title: Jira Import
+ title: Jira Migrator
description: Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run.
errors:
cannot_delete_with_imports: Cannot delete Jira host with existing imports
@@ -125,8 +125,8 @@ zh-TW:
title: Jira configuration
new: New configuration
banner:
- title: Limited import
- description: 'This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
+ title: Limited import capabilities
+ description: 'This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time.'
form:
fields:
name: Name
@@ -154,6 +154,7 @@ zh-TW:
connection_timeout: 'Connection to Jira server timed out: %{message}'
parse_error: 'Failed to parse Jira API response: %{message}'
api_error: Jira API returned error status %{status}
+ 401_error: Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator.
columns:
projects: Projects
last_change: Last change
@@ -162,7 +163,7 @@ zh-TW:
run:
title: Import run
history: History
- remove_error: A Jira import cannot be removed while it is running
+ remove_error: A Jira import run cannot be removed while it is running
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:
@@ -381,9 +382,9 @@ zh-TW:
notification_text_default: "
您好,
已建立新專案: projectValue:name
謝謝
\n"
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
- existing_identifiers_notice: 'Existing identifiers for %{project_count} projects don''t meet requirements for project-based alphanumerical identifiers. OpenProject can automatically update these so that they are valid as in the examples below. Click on ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ 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 ''Autofix and save'' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
'
box_header:
@@ -392,10 +393,14 @@ zh-TW:
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
other: "... %{count} more projects"
button_autofix: Autofix and save
@@ -409,7 +414,7 @@ zh-TW:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: 預設轉換
@@ -674,6 +679,37 @@ zh-TW:
danger_dialog:
confirmation_live_message_checked: 繼續的按鈕現已啟用。
confirmation_live_message_unchecked: 繼續的按鈕現在沒有作用。您需要勾選核取方塊才能繼續。
+ departments:
+ edit: Edit department
+ add_user: Add user
+ add_department: Add department
+ 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.
+
+ '
+ add_button: Add
+ detail_blankslate:
+ heading: This department doesn’t have any hierarchy level below
+ description: Add departments or users to create sub-items inside another one.
+ add_button: Add
+ add_department_form:
+ name_label: Department name
+ name_placeholder: Enter department name
+ 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
+ context_menu:
+ add_sub_department: Add sub-department
+ add_user: Add user
+ 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.
+ errors:
+ move_user_failed: Failed to move user between departments.
pagination:
label: Pagination
prev: Previous
@@ -1322,6 +1358,20 @@ zh-TW:
index:
no_results_title_text: 目前沒有工作流程
work_packages:
+ delete_dialog:
+ title: Delete work package
+ heading: Permanently delete this work package?
+ description: Are you sure you want to delete the work package "%{name}"?
+ confirm_descendants_deletion: I acknowledge that ALL descendants of this work package will be recursively removed.
+ cross_project_warning: 'Work packages from the following projects will be deleted: %{projects}'
+ bulk_delete_dialog:
+ title: Delete %{count} work packages
+ heading: Permanently delete these %{count} work packages?
+ description: 'The following work packages, including children and all associated data, will permanently be deleted:'
+ description_with_children: 'The following work packages, including child work packages, and all associated data will be permanently deleted:'
+ confirm_children_deletion: I acknowledge that all selected work packages and their children will be permanently deleted.
+ cross_project_warning: 'These work packages span multiple projects: %{projects}'
+ children_label: 'The following children will also be deleted:'
datepicker_modal:
banner:
description:
@@ -1514,6 +1564,9 @@ zh-TW:
dependencies: 依賴套件
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: Identifier
+ work_package: Work package
jira_import:
projects: Projects
import/jira:
@@ -1522,7 +1575,7 @@ zh-TW:
personal_access_token: Personal access token
import/jira_open_project_reference:
jira: Jira
- jira_import: Jira import
+ jira_import: Jira Migrator
announcements:
show_until: 只顯示到
attachment:
@@ -1778,6 +1831,7 @@ zh-TW:
identity_url: 身份識別 URL
parent: Parent group
organizational_unit: Organizational unit
+ group_users: Group users
group_detail:
parent: Parent group
organizational_unit: Organizational unit
@@ -1895,6 +1949,7 @@ zh-TW:
confirmation: 不吻合 %{attribute}。
could_not_be_copied: "%{dependency} 無法完整複製."
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: 被嘗試寫入但是無法寫入。
@@ -1961,6 +2016,7 @@ zh-TW:
attributes:
parent_id:
circular_dependency: would create a circular group hierarchy.
+ organizational_unit_mismatch: must have the same organizational unit setting as the group.
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2423,7 +2479,6 @@ zh-TW:
avatar: 大頭貼
base: '一般錯誤:'
body: 本體
- blocks_ids: 已被限制的工作套件 IDs
category: 類別
comment: 留言
comments: 留言
@@ -2860,6 +2915,7 @@ zh-TW:
title: 企業版附加元件
plan_title: 企業版 %{plan} 外掛
plan_name: "%{plan} 企業版計畫"
+ trial_text: This feature is included in your active Enterprise trial.
plan_text_html: 需 %{plan_name} 方案以上才可使用。
unlimited: 不限
already_have_token: '已經有令牌了嗎?請使用下方按鈕新增,以升級至預約的 Enterprise 方案。
@@ -3326,6 +3382,11 @@ zh-TW:
quick_add:
label: 新增…
my_account:
+ notifications_and_email:
+ title: Notification and email
+ tabs:
+ notifications: Notification settings
+ email_reminders: Email reminders
access_tokens:
description: 提供者令牌由 OpenProject 發行,允許其他應用程式存取。用戶端識別碼由其他應用程式發行,允許 OpenProject 存取它們。
no_results:
@@ -3388,6 +3449,72 @@ zh-TW:
disabled_text: RSS 令牌並非由管理員啟用。請聯絡您的管理員以使用此功能。
storages:
unknown_storage: 不明的儲存區
+ email_reminders:
+ immediate_reminders:
+ title: Send me an email reminder
+ mentioned: Notify me when I am mentioned
+ personal_reminder: Notify me for personal reminders
+ daily_reminders:
+ title: Send me daily email reminders for unread notifications
+ caption: You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC.
+ enabled: Enable daily email reminders
+ add_time: Add time
+ remove_time: Remove time
+ time_slot_label: Reminder time (UTC)
+ workdays:
+ title: Receive email reminders on these days
+ submit_button: Update reminder days
+ pause_reminders:
+ title: Pause email notifications
+ enabled: Temporarily pause daily email reminders
+ date_range: Pause period
+ email_alerts:
+ title: Email alerts for other items that are not work packages
+ news_added: News added
+ news_commented: Comment on a news item
+ document_added: Document added
+ forum_messages: Forum message posted
+ wiki_page_added: Wiki page added
+ wiki_page_updated: Wiki page updated
+ membership_added: Membership added
+ membership_updated: Membership updated
+ submit_button: Update alerts
+ notifications:
+ participating:
+ title: Participating
+ submit_button: Update preferences
+ mentioned: Mentioned
+ watched: Watching
+ assignee: Assignee
+ responsible: Accountable
+ shared: Shared with me
+ date_alerts:
+ title: Date alerts
+ submit_button: Update date alerts
+ start_date: Start date
+ due_date: Finish date
+ 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
+ non_participating:
+ title: Non-participating
+ submit_button: Update preferences
+ work_package_created: New work packages
+ work_package_commented: All new comments
+ work_package_processed: All status changes
+ work_package_prioritized: All priority changes
+ work_package_scheduled: All date changes
+ project_specific_settings:
+ title: Project-specific notification settings
+ add_button: Add project-specific notifications
+ dialog_title: Add project-specific notifications
+ list_header: Projects with specific notifications
notifications:
reasons:
assigned: 執行者
@@ -3419,6 +3546,7 @@ zh-TW:
invalid_filter: 無效的通知過濾器
label_accessibility: 輔助功能
label_account: 帳號
+ label_actions: 操作
label_active: 啟用
label_activate_user: 啟動使用者
label_active_in_new_projects: 在新專案中啟用
@@ -3459,6 +3587,7 @@ zh-TW:
label_ical_access_key_generation_hint: 訂閱日曆時自動生成的。
label_ical_access_key_latest: 最新
label_ical_access_key_revoke: 撤銷
+ label_integrations: Integrations
label_add_column: 新增欄位
label_applied_status: 套用的狀態
label_archive_project: 封存專案
@@ -3644,7 +3773,7 @@ zh-TW:
label_filter_add: 新增條件
label_filter_by: 篩選條件:
label_filter_any_name_attribute: 名稱屬性
- label_filter_plural: 篩選條件
+ label_filter_plural: 篩選器
label_filters_toggle: 顯示/隱藏篩選條件
label_float: 浮點數
label_folder: 資料夾
@@ -3658,8 +3787,8 @@ zh-TW:
label_global_modules: 全域模組
label_global_roles: 全域角色
label_git_path: ".git 目錄的路徑"
- label_greater_or_equal: 之前
- label_group_by: 分類
+ label_greater_or_equal: ">="
+ label_group_by: 分組依據
label_group_new: 新增群組
label_group: 群組
label_group_named: 群組名稱 %{name}
@@ -3671,7 +3800,7 @@ zh-TW:
label_hierarchy: 階層
label_hierarchy_leaf: 頁面結構頁
label_home: Home
- label_subject_or_id: 名稱或 id
+ label_subject_or_id: 主旨或 id
label_calendar_subscriptions: 訂閱行事曆
label_identifier: 識別碼
label_project_identifier: Project identifier
@@ -3709,7 +3838,7 @@ zh-TW:
label_external_links: 外部連結
label_locale: 語言和地區
label_jump_to_a_project: 前往一個專案...
- label_jira_import: Jira Import
+ label_jira_import: Jira Migrator
label_keyword_plural: 關鍵字
label_language_based: 根據使用者的語言
label_last_activity: 最後的活動
@@ -3723,7 +3852,7 @@ zh-TW:
label_latest_revision_plural: 最新版本
label_ldap_authentication: LDAP 認證
label_learn_more: 了解更多
- label_less_or_equal: 之後
+ label_less_or_equal: "<="
label_less_than_ago: 幾天內
label_link_url: 連結(URL)
label_list: 清單
@@ -3747,6 +3876,10 @@ zh-TW:
label_custom_pdf_export_settings: 匯出PDF設定
label_custom_favicon: 自訂圖示
label_custom_touch_icon: 自訂觸控圖示
+ label_departments: Organization
+ 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).
+
+ '
label_logout: 登出
label_mapping_for: 對應為: %{attribute}
label_main_menu: 側邊選單
@@ -4815,6 +4948,7 @@ zh-TW:
'
setting_app_subtitle: 應用程式副標題
setting_app_title: 應用程式標題
+ setting_organization_name: Organization name
setting_attachment_max_size: 附件最大容量
setting_show_work_package_attachments: 默認在文件選項卡中顯示附件
setting_antivirus_scan_mode: 掃描模式
@@ -4961,12 +5095,12 @@ zh-TW:
setting_welcome_text: 歡迎區塊文字
setting_welcome_title: 歡迎區塊標題
setting_welcome_on_homescreen: 在主頁面上顯示歡迎區塊
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: 'Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
'
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: 'Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
'
setting_work_package_list_default_highlighting_mode: 預設顯示模式
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 8987cd93c14..da07c8eae12 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -121,7 +121,7 @@ en:
import:
title: "Import"
jira:
- title: "Jira Import"
+ title: "Jira Migrator"
description: "Use this tool to import data from your Jira instance. You can configure multiple Jira hosts and choose what to import in each import run."
errors:
cannot_delete_with_imports: "Cannot delete Jira host with existing imports"
@@ -132,8 +132,8 @@ en:
title: "Jira configuration"
new: "New configuration"
banner:
- title: "Limited import"
- description: "This import tool is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time."
+ title: "Limited import capabilities"
+ description: "This Jira Migrator is currently in beta and can only import basic data: projects, issues (name, title, description, attachments), users (name, email, project membership), statuses, and types. It cannot import workflows, custom fields, issue relations, or permissions. We currently only support Jira Server/Data Center versions 10.x and 11.x. Cloud instances are not supported at this time."
form:
fields:
name: "Name"
@@ -161,6 +161,7 @@ en:
connection_timeout: "Connection to Jira server timed out: %{message}"
parse_error: "Failed to parse Jira API response: %{message}"
api_error: "Jira API returned error status %{status}"
+ 401_error: "Jira API returned a 401 error. Your authentication token may have expired or lack the required permissions. Please ensure the token belongs to a Jira administrator."
columns:
projects: "Projects"
last_change: "Last change"
@@ -169,8 +170,8 @@ en:
run:
title: "Import run"
history: "History"
- remove_error: "A Jira import cannot be removed while it is running"
- import_blocked_error: "Another Jira import run is currently in progress or awaiting review. Please complete or revert it before starting a new import."
+ remove_error: "A Jira import run cannot be removed while it is running"
+ 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:
title: "No import runs set up yet"
@@ -399,22 +400,26 @@ en:
Thank you
work_packages_identifier:
page_header:
- description: Choose between basic numerical work packages IDs or project-specific ones that prepend the project identifier to the work package ID.
+ description: Choose between classic numerical work package IDs or semantic project-specific ones that prepend the project identifier to the work package ID.
banner:
existing_identifiers_notice: >
- Existing identifiers for %{project_count} projects don't meet requirements for project-based alphanumerical identifiers.
+ 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 'Autofix and save' to update identifiers for all projects in this manner and enable project-based alphanumerical identifiers.
+ Click on 'Autofix and save' to update identifiers for all projects in this manner and enable project-based semantic identifiers.
box_header:
label_project: Project
label_previous_identifier: Previous identifier
label_autofixed_suggestion: Future identifier
label_example_work_package_id: Example work package ID
autofix_preview:
- error_too_long: Has to be fewer than 5 characters
+ error_too_long: Has to be 10 characters or fewer
+ error_numerical: Cannot be purely numerical
+ error_starts_with_number: Cannot start with a number
error_special_characters: Special characters not allowed
+ error_not_fully_uppercased: Must be uppercase
error_in_use: Already in use as another project's active handle
error_reserved: Reserved by another project's handle history
+ error_unknown: Needs manual review
remaining_projects:
one: "... 1 more project"
other: "... %{count} more projects"
@@ -430,7 +435,7 @@ en:
checkbox_label: I understand that this will permanently change all work package IDs
success_banner: Successfully updated work package identifier format.
in_progress:
- banner_message: Project identifiers are currently being updated to project-based alphanumerical identifiers. This may take some time.
+ banner_message: Project identifiers are currently being updated to project-based semantic identifiers. This may take some time.
workflows:
tabs:
default_transitions: "Default transitions"
@@ -717,6 +722,38 @@ en:
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"
+ 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.
+ add_button: "Add"
+ detail_blankslate:
+ heading: "This department doesn’t have any hierarchy level below"
+ description: "Add departments or users to create sub-items inside another one."
+ add_button: "Add"
+ add_department_form:
+ name_label: "Department name"
+ name_placeholder: "Enter department name"
+ 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"
+ context_menu:
+ add_sub_department: "Add sub-department"
+ add_user: "Add user"
+ 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."
+ errors:
+ move_user_failed: "Failed to move user between departments."
+
pagination:
label: "Pagination"
prev: "Previous"
@@ -1412,6 +1449,20 @@ en:
no_results_title_text: There are currently no workflows.
work_packages:
+ delete_dialog:
+ title: "Delete work package"
+ heading: "Permanently delete this work package?"
+ description: 'Are you sure you want to delete the work package "%{name}"?'
+ confirm_descendants_deletion: "I acknowledge that ALL descendants of this work package will be recursively removed."
+ cross_project_warning: "Work packages from the following projects will be deleted: %{projects}"
+ bulk_delete_dialog:
+ title: "Delete %{count} work packages"
+ heading: "Permanently delete these %{count} work packages?"
+ description: "The following work packages, including children and all associated data, will permanently be deleted:"
+ description_with_children: "The following work packages, including child work packages, and all associated data will be permanently deleted:"
+ confirm_children_deletion: "I acknowledge that all selected work packages and their children will be permanently deleted."
+ cross_project_warning: "These work packages span multiple projects: %{projects}"
+ children_label: "The following children will also be deleted:"
datepicker_modal:
banner:
description:
@@ -1619,6 +1670,9 @@ en:
activerecord:
attributes:
+ work_package_semantic_alias:
+ identifier: "Identifier"
+ work_package: "Work package"
jira_import:
projects: "Projects"
"import/jira":
@@ -1627,7 +1681,7 @@ en:
personal_access_token: "Personal access token"
"import/jira_open_project_reference":
jira: "Jira"
- jira_import: "Jira import"
+ jira_import: "Jira Migrator"
announcements:
show_until: "Display until"
attachment:
@@ -1883,6 +1937,7 @@ en:
identity_url: "Identity URL"
parent: "Parent group"
organizational_unit: "Organizational unit"
+ group_users: "Group users"
group_detail:
parent: "Parent group"
organizational_unit: "Organizational unit"
@@ -2001,6 +2056,7 @@ en:
confirmation: "doesn't match %{attribute}."
could_not_be_copied: "%{dependency} could not be (fully) copied."
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."
@@ -2066,6 +2122,7 @@ en:
attributes:
parent_id:
circular_dependency: "would create a circular group hierarchy."
+ organizational_unit_mismatch: "must have the same organizational unit setting as the group."
ldap_auth_source:
attributes:
tls_certificate_string:
@@ -2554,7 +2611,6 @@ en:
avatar: "Avatar"
base: "General Error:"
body: "Body"
- blocks_ids: "IDs of blocked work packages"
category: "Category"
comment: "Comment"
comments: "Comment"
@@ -3033,6 +3089,7 @@ en:
title: "Enterprise add-on"
plan_title: "Enterprise %{plan} add-on"
plan_name: "%{plan} enterprise plan"
+ trial_text: "This feature is included in your active Enterprise trial."
plan_text_html: "Available starting with the %{plan_name}."
unlimited: "Unlimited"
already_have_token: >
@@ -3526,6 +3583,11 @@ en:
label: "Add…"
my_account:
+ notifications_and_email:
+ title: "Notification and email"
+ tabs:
+ notifications: "Notification settings"
+ email_reminders: "Email reminders"
access_tokens:
description: "Provider tokens are issued by OpenProject, allowing other applications to access it. Client tokens are issued by other applications, allowing OpenProject to access them."
no_results:
@@ -3588,6 +3650,72 @@ en:
disabled_text: "RSS tokens are not enabled by the administrator. Please contact your administrator to use this feature."
storages:
unknown_storage: "Unknown storage"
+ email_reminders:
+ immediate_reminders:
+ title: "Send me an email reminder"
+ mentioned: "Notify me when I am mentioned"
+ personal_reminder: "Notify me for personal reminders"
+ daily_reminders:
+ title: "Send me daily email reminders for unread notifications"
+ caption: "You will receive these reminders only for unread notifications and only at hours you specify. Until you configure a time zone for your account, the times will be interpreted to be in UTC."
+ enabled: "Enable daily email reminders"
+ add_time: "Add time"
+ remove_time: "Remove time"
+ time_slot_label: "Reminder time (UTC)"
+ workdays:
+ title: "Receive email reminders on these days"
+ submit_button: "Update reminder days"
+ pause_reminders:
+ title: "Pause email notifications"
+ enabled: "Temporarily pause daily email reminders"
+ date_range: "Pause period"
+ email_alerts:
+ title: "Email alerts for other items that are not work packages"
+ news_added: "News added"
+ news_commented: "Comment on a news item"
+ document_added: "Document added"
+ forum_messages: "Forum message posted"
+ wiki_page_added: "Wiki page added"
+ wiki_page_updated: "Wiki page updated"
+ membership_added: "Membership added"
+ membership_updated: "Membership updated"
+ submit_button: "Update alerts"
+ notifications:
+ participating:
+ title: "Participating"
+ submit_button: "Update preferences"
+ mentioned: "Mentioned"
+ watched: "Watching"
+ assignee: "Assignee"
+ responsible: "Accountable"
+ shared: "Shared with me"
+ date_alerts:
+ title: "Date alerts"
+ submit_button: "Update date alerts"
+ start_date: "Start date"
+ due_date: "Finish date"
+ 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"
+ non_participating:
+ title: "Non-participating"
+ submit_button: "Update preferences"
+ work_package_created: "New work packages"
+ work_package_commented: "All new comments"
+ work_package_processed: "All status changes"
+ work_package_prioritized: "All priority changes"
+ work_package_scheduled: "All date changes"
+ project_specific_settings:
+ title: "Project-specific notification settings"
+ add_button: "Add project-specific notifications"
+ dialog_title: "Add project-specific notifications"
+ list_header: "Projects with specific notifications"
notifications:
reasons:
@@ -3621,6 +3749,7 @@ en:
label_accessibility: "Accessibility"
label_account: "Account"
+ label_actions: "Actions"
label_active: "Active"
label_activate_user: "Activate user"
label_active_in_new_projects: "Active in new projects"
@@ -3661,6 +3790,7 @@ en:
label_ical_access_key_generation_hint: "Automatically generated when subscribing to a calendar."
label_ical_access_key_latest: "latest"
label_ical_access_key_revoke: "Revoke"
+ label_integrations: "Integrations"
label_add_column: "Add column"
label_applied_status: "Applied status"
label_archive_project: "Archive project"
@@ -3911,7 +4041,7 @@ en:
label_external_links: "External links"
label_locale: "Language and region"
label_jump_to_a_project: "Jump to a project..."
- label_jira_import: "Jira Import"
+ label_jira_import: "Jira Migrator"
label_keyword_plural: "Keywords"
label_language_based: "Based on user's language"
label_last_activity: "Last activity"
@@ -3949,6 +4079,11 @@ en:
label_custom_pdf_export_settings: "Custom PDF export settings"
label_custom_favicon: "Custom favicon"
label_custom_touch_icon: "Custom touch icon"
+ label_departments: "Organization"
+ 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).
label_logout: "Sign out"
label_mapping_for: "Mapping for: %{attribute}"
label_main_menu: "Side Menu"
@@ -5042,6 +5177,7 @@ en:
APIs of OpenProject, such as APIv3 and MCP.
setting_app_subtitle: "Application subtitle"
setting_app_title: "Application title"
+ setting_organization_name: "Organization name"
setting_attachment_max_size: "Attachment max. size"
setting_show_work_package_attachments: "Show attachments in the files tab by default"
setting_antivirus_scan_mode: "Scan mode"
@@ -5201,11 +5337,11 @@ en:
setting_welcome_text: "Welcome block text"
setting_welcome_title: "Welcome block title"
setting_welcome_on_homescreen: "Display welcome block on homescreen"
- setting_work_packages_identifier_numeric: Instance-wide numerical sequence (default)
- setting_work_packages_identifier_numeric_caption: >
+ setting_work_packages_identifier_classic: Instance-wide numerical sequence (default)
+ setting_work_packages_identifier_classic_caption: >
Every work package gets a sequential number starting with 1 and incremented with every new one. The numbers are unique within this instance so they remain the same even if work packages are moved between projects.
- setting_work_packages_identifier_alphanumeric: Project-based alphanumerical identifiers
- setting_work_packages_identifier_alphanumeric_caption: >
+ setting_work_packages_identifier_semantic: Project-based semantic identifiers
+ setting_work_packages_identifier_semantic_caption: >
Every project has a unique identifier that is prefixed to the work package ID. If a work package moved to another project, a new identifier is generated but the old one continues to function.
setting_work_package_list_default_highlighting_mode: "Default highlighting mode"
setting_work_package_list_default_highlighted_attributes: "Default inline highlighted attributes"
diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml
index 6e8a9765fc0..50545ecb125 100644
--- a/config/locales/js-en.yml
+++ b/config/locales/js-en.yml
@@ -551,12 +551,6 @@ en:
sidebar_arrow: "Use the return arrow in the top left corner to return to the project’s main menu."
welcome: "Take a three-minute introduction tour to learn the most important features. We recommend completing the steps until the end. You can restart the tour any time."
wiki: "Within the wiki you can document and share knowledge together with your team."
- backlogs:
- overview: "Manage your work in the backlogs view."
- sprints: "On the right you have the product backlog and the bug backlog, on the left you have the respective sprints. Here you can create epics, user stories, and bugs, prioritize via drag & drop and add them to a sprint."
- task_board_arrow: "To see your task board, open the sprint drop-down..."
- task_board_select: "...and select the task board entry."
- task_board: "The task board visualizes the progress for this sprint. Click on the plus (+) icon next to a user story to add new tasks or impediments. The status can be updated by drag and drop."
boards:
overview: "Select boards to shift the view and manage your project using the agile boards view."
lists_kanban: "Here you can create multiple lists (columns) within your board. This feature allows you to create a Kanban board, for example."
@@ -631,49 +625,6 @@ en:
settings:
change_notification_settings: 'You can modify your notification settings to ensure you never miss an important update.'
title: "Notification settings"
- notify_me: "Notify me"
- reminders:
- no_notification: No notification
- timeframes:
- normal:
- PT0S: same day
- P1D: 1 day before
- P3D: 3 days before
- P7D: a week before
- overdue:
- P1D: every day
- P3D: every 3 days
- P7D: every week
- reasons:
- mentioned:
- title: "Mentioned"
- description: "Receive a notification every time someone mentions me anywhere"
- assignee: "Assignee"
- responsible: "Accountable"
- shared: "Shared"
- watched: "Watcher"
- work_package_commented: "All new comments"
- work_package_created: "New work packages"
- work_package_processed: "All status changes"
- work_package_prioritized: "All priority changes"
- work_package_scheduled: "All date changes"
- global:
- immediately:
- title: "Participating"
- description: "Notifications for all activities in work packages you are involved in (assignee, accountable or watcher)."
- delayed:
- title: "Non-participating"
- description: "Additional notifications for activities in all projects."
- date_alerts:
- title: "Date alerts"
- description: "Automatic notifications when important dates are approaching for open work packages you are involved in (assignee, accountable or watcher)."
- overdue: When overdue
- project_specific:
- title: "Project-specific notification settings"
- description: "These project-specific settings override default settings above."
- add: "Add setting for project"
- already_selected: "This project is already selected"
- remove: "Remove project settings"
pagination:
no_other_page: "You are on the only page."
@@ -701,40 +652,6 @@ en:
Please choose a project to create the work package in to see all attributes.
You can only select projects which have the type above activated.
- reminders:
- settings:
- daily:
- add_time: "Add time"
- enable: "Enable daily email reminders"
- explanation: "You will receive these reminders only for unread notifications and only at hours you specify. %{no_time_zone}"
- no_time_zone: "Until you configure a time zone for your account, the times will be interpreted to be in UTC."
- time_label: "Time %{counter}:"
- title: "Send me daily email reminders for unread notifications"
- workdays:
- title: "Receive email reminders on these days"
- immediate:
- title: "Send me an email reminder"
- mentioned: "Immediately when someone @mentions me"
- personal_reminder: "Immediately when I receive a personal reminder"
- alerts:
- title: "Email alerts for other items (that are not work packages)"
- explanation: >
- Notifications today are limited to work packages.
- You can choose to continue receiving email alerts for these events until they are included in notifications:
- news_added: "News added"
- news_commented: "Comment on a news item"
- document_added: "Documents added"
- forum_messages: "New forum messages"
- wiki_page_added: "Wiki page added"
- wiki_page_updated: "Wiki page updated"
- membership_added: "Membership added"
- membership_updated: "Membership updated"
- title: "Email reminders"
- pause:
- label: "Temporarily pause daily email reminders"
- first_day: "First day"
- last_day: "Last day"
-
text_are_you_sure: "Are you sure?"
text_are_you_sure_to_cancel: "You have unsaved changes on this page. Are you sure you want to discard them?"
breadcrumb: "Breadcrumb"
@@ -1123,13 +1040,6 @@ en:
form_submit:
title: "Confirm to continue"
text: "Are you sure you want to perform this action?"
- destroy_work_package:
- title: "Confirm deletion of %{label}"
- single_text: "Are you sure you want to delete the work package"
- bulk_text: "Are you sure you want to delete the following %{label}?"
- has_children: "The work package has %{childUnits}:"
- confirm_deletion_children: "I acknowledge that ALL descendants of the listed work packages will be recursively removed."
- deletes_children: "All child work packages and their descendants will also be recursively deleted."
destroy_time_entry:
title: "Confirm deletion of time entry"
text: "Are you sure you want to delete the following time entry?"
diff --git a/config/routes.rb b/config/routes.rb
index ad657256f9a..cdb2dd4b32f 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -801,6 +801,32 @@ Rails.application.routes.draw do
post :delete_token
end
end
+
+ resources :departments,
+ only: %i[index show edit update destroy],
+ constraints: lambda { |_request| OpenProject::FeatureDecisions.departments_active? } do
+ member do
+ get :new_user
+ post :add_user
+ delete "remove_user/:user_id" => "departments#remove_user", as: :remove_user
+ get :change_parent, action: :change_parent_dialog
+ post :change_parent
+
+ # old routes for old group style management, might remove when new interface
+ patch "/memberships:membership_id" => "departments#edit_membership", as: "membership_of"
+ put "/memberships:membership_id" => "departments#edit_membership"
+ delete "/memberships:membership_id" => "departments#destroy_membership"
+ post "/memberships" => "departments#create_memberships", as: "memberships_of"
+ end
+
+ collection do
+ get :new_department
+ post :add_department
+ get :edit_organization_name
+ patch :cancel_edit_organization_name
+ patch :update_organization_name
+ end
+ end
end
resources :workflows, only: %i[index edit update], param: :type_id do
@@ -821,6 +847,7 @@ Rails.application.routes.draw do
resource :bulk, controller: "bulk", only: %i[edit update destroy] do
collection do
match :reassign, via: %i[get delete]
+ get :delete_dialog
end
end
end
@@ -950,6 +977,17 @@ Rails.application.routes.draw do
get "/change_status/:change_action" => "users#change_status_info", as: "change_status_info"
post :change_status
post :resend_invitation
+ patch :update_reminders
+ patch :update_workdays
+ patch :update_email_alerts
+ patch :update_participating
+ patch :update_non_participating
+ patch :update_date_alerts
+ get "project_notifications/new" => "users#new_project_settings", as: "new_project_settings"
+ post "project_notifications" => "users#create_project_settings", as: "project_notifications"
+ get "project_notifications/:project_id/edit" => "users#edit_project_settings", as: "edit_project_settings"
+ patch "project_notifications/:project_id" => "users#update_project_settings", as: "project_setting"
+ delete "project_notifications/:project_id" => "users#destroy_project_settings"
get :deletion_info
end
end
@@ -1039,13 +1077,23 @@ Rails.application.routes.draw do
get "/my/locale", action: "locale"
get "/my/interface", action: "interface"
get "/my/notifications", action: "notifications"
- get "/my/reminders", action: "reminders"
get "/my/working_hours", action: "working_hours"
get "/my/non_working_times", action: "non_working_times"
patch "/my/account", action: "update_account"
patch "/my/settings", action: "update_settings"
+ patch "/my/workdays", action: "update_workdays"
+ patch "/my/email_alerts", action: "update_email_alerts"
+ patch "/my/participating", action: "update_participating"
+ patch "/my/non_participating", action: "update_non_participating"
+ patch "/my/date_alerts", action: "update_date_alerts"
+
+ get "/my/project_notifications/new", action: "new_project_settings", as: "new_my_project_settings"
+ post "/my/project_notifications", action: "create_project_settings", as: "my_project_notifications"
+ get "/my/project_notifications/:project_id/edit", action: "edit_project_settings", as: "edit_my_project_settings"
+ patch "/my/project_notifications/:project_id", action: "update_project_settings", as: "my_project_setting"
+ delete "/my/project_notifications/:project_id", action: "destroy_project_settings"
end
scope controller: "onboarding" do
diff --git a/config/static_links.yml b/config/static_links.yml
index 03c503d8288..43d936ca817 100644
--- a/config/static_links.yml
+++ b/config/static_links.yml
@@ -153,6 +153,9 @@ security_badge_documentation:
shortcuts:
href: https://www.openproject.org/docs/user-guide/keyboard-shortcuts-access-keys/
label: homescreen.links.shortcuts
+wiki_docs:
+ xwiki_setup:
+ href: https://www.openproject.org/docs/system-admin-guide/integrations/
storage_docs:
health_status:
href: https://www.openproject.org/docs/system-admin-guide/files/external-file-storages/health-status/
diff --git a/db/migrate/20260319120000_add_case_insensitive_uniqueness_for_project_identifiers.rb b/db/migrate/20260319120000_add_case_insensitive_uniqueness_for_project_identifiers.rb
new file mode 100644
index 00000000000..f9a794eabd1
--- /dev/null
+++ b/db/migrate/20260319120000_add_case_insensitive_uniqueness_for_project_identifiers.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class AddCaseInsensitiveUniquenessForProjectIdentifiers < ActiveRecord::Migration[8.0]
+ disable_ddl_transaction!
+
+ def up
+ deduplicate_case_colliding_identifiers
+ remove_index :projects, :identifier, unique: true, algorithm: :concurrently, if_exists: true
+ add_index :projects, "LOWER(identifier)",
+ unique: true,
+ name: "index_projects_on_lower_identifier",
+ algorithm: :concurrently,
+ if_not_exists: true
+ end
+
+ # Note: does not undo identifier renames from deduplication. Suffixed identifiers
+ # (e.g. "FOO_2") remain valid and unique under the restored case-sensitive index.
+ def down
+ remove_index :projects, name: "index_projects_on_lower_identifier", algorithm: :concurrently, if_exists: true
+ add_index :projects, :identifier, unique: true, algorithm: :concurrently
+ end
+
+ private
+
+ # Resolves any existing case-colliding identifiers (e.g. "Foo" and "foo") so that
+ # the unique LOWER(identifier) index can be created without violation errors.
+ # The oldest project (by id) keeps its identifier; duplicates get a "_N" suffix.
+ #
+ # The NOT EXISTS guard skips rows where the suffixed identifier would itself collide.
+ # In practice this is extremely unlikely (requires both case-colliding identifiers
+ # AND a pre-existing "_N" variant). If it occurs, the subsequent index creation
+ # will fail, surfacing the issue for manual resolution.
+ def deduplicate_case_colliding_identifiers
+ execute <<~SQL.squish
+ UPDATE projects SET identifier = projects.identifier || '_' || counter.rn
+ FROM (
+ SELECT id, row_number() OVER (PARTITION BY LOWER(identifier) ORDER BY id) AS rn
+ FROM projects
+ ) AS counter
+ WHERE projects.id = counter.id AND counter.rn > 1
+ AND NOT EXISTS (
+ SELECT 1 FROM projects p2
+ WHERE LOWER(p2.identifier) = LOWER(projects.identifier || '_' || counter.rn)
+ );
+ SQL
+ end
+end
diff --git a/db/migrate/20260328120000_rename_work_packages_identifier_setting_values.rb b/db/migrate/20260328120000_rename_work_packages_identifier_setting_values.rb
new file mode 100644
index 00000000000..907b45b74e6
--- /dev/null
+++ b/db/migrate/20260328120000_rename_work_packages_identifier_setting_values.rb
@@ -0,0 +1,45 @@
+# 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.root.join("db/migrate/migration_utils/setting_renamer")
+
+class RenameWorkPackagesIdentifierSettingValues < ActiveRecord::Migration[8.0]
+ SETTING_NAME = "work_packages_identifier"
+
+ def up
+ Migration::MigrationUtils::SettingRenamer.rename_value(SETTING_NAME, "numeric", "classic")
+ Migration::MigrationUtils::SettingRenamer.rename_value(SETTING_NAME, "alphanumeric", "semantic")
+ end
+
+ def down
+ Migration::MigrationUtils::SettingRenamer.rename_value(SETTING_NAME, "classic", "numeric")
+ Migration::MigrationUtils::SettingRenamer.rename_value(SETTING_NAME, "semantic", "alphanumeric")
+ end
+end
diff --git a/db/migrate/20260330100000_create_work_package_semantic_ids.rb b/db/migrate/20260330100000_create_work_package_semantic_ids.rb
new file mode 100644
index 00000000000..0b9111137cd
--- /dev/null
+++ b/db/migrate/20260330100000_create_work_package_semantic_ids.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+
+class CreateWorkPackageSemanticIds < ActiveRecord::Migration[8.1]
+ def up
+ # Atomic counter for per-project WP sequence allocation
+ add_column :projects, :wp_sequence_counter, :integer, default: 0, null: false, if_not_exists: true
+
+ # Per-project sequence number for semantic identifiers (e.g. PROJ-42)
+ add_column :work_packages, :sequence_number, :integer, if_not_exists: true
+ # Current semantic identifier stored directly on the work package (e.g. "PROJ-42")
+ add_column :work_packages, :identifier, :string, if_not_exists: true
+
+ create_table :work_package_semantic_aliases, if_not_exists: true do |t|
+ t.string :identifier, null: false
+ t.references :work_package, null: false, foreign_key: true
+ t.timestamps
+ end
+
+ # Unique identifier across all WPs (past and present)
+ add_index :work_package_semantic_aliases, :identifier, unique: true, if_not_exists: true
+
+ # Fast lookup and uniqueness of the current semantic identifier (partial: excludes pre-backfill NULLs)
+ add_index :work_packages, :identifier,
+ unique: true,
+ where: "identifier IS NOT NULL",
+ if_not_exists: true
+
+ # Enforce uniqueness of sequence numbers within a project (partial: excludes pre-backfill NULLs)
+ add_index :work_packages, %i[project_id sequence_number],
+ unique: true,
+ where: "sequence_number IS NOT NULL",
+ if_not_exists: true
+ end
+
+ def down
+ drop_table :work_package_semantic_aliases, if_exists: true
+ remove_index :work_packages, %i[project_id sequence_number], if_exists: true
+ remove_column :work_packages, :identifier, if_exists: true
+ remove_column :work_packages, :sequence_number, if_exists: true
+ remove_column :projects, :wp_sequence_counter, if_exists: true
+ end
+end
diff --git a/db/migrate/20260402094525_add_group_detail_index_for_ous.rb b/db/migrate/20260402094525_add_group_detail_index_for_ous.rb
new file mode 100644
index 00000000000..ed448582527
--- /dev/null
+++ b/db/migrate/20260402094525_add_group_detail_index_for_ous.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddGroupDetailIndexForOus < ActiveRecord::Migration[8.1]
+ def change
+ add_index :group_details, :organizational_unit
+ end
+end
diff --git a/db/migrate/migration_utils/setting_renamer.rb b/db/migrate/migration_utils/setting_renamer.rb
index 5591f5038eb..3a188a444fc 100644
--- a/db/migrate/migration_utils/setting_renamer.rb
+++ b/db/migrate/migration_utils/setting_renamer.rb
@@ -34,13 +34,21 @@ module Migration
# define all the following methods as class methods
class << self
def rename(source_name, target_name)
- ActiveRecord::Base.connection.execute <<-SQL.squish
+ ActiveRecord::Base.connection.execute <<~SQL.squish
UPDATE #{settings_table}
SET name = #{quote_value(target_name)}
WHERE name = #{quote_value(source_name)}
SQL
end
+ def rename_value(setting_name, from, to)
+ ActiveRecord::Base.connection.execute <<~SQL.squish
+ UPDATE #{settings_table}
+ SET value = #{quote_value(to)}
+ WHERE name = #{quote_value(setting_name)} AND value = #{quote_value(from)}
+ SQL
+ end
+
private
def settings_table
diff --git a/db/migrate/tables/base.rb b/db/migrate/tables/base.rb
index d5622b4663a..afeec9fa31c 100644
--- a/db/migrate/tables/base.rb
+++ b/db/migrate/tables/base.rb
@@ -56,6 +56,6 @@ class Tables::Base
end
def self.table(_migration)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
diff --git a/db/migrate/tables/projects.rb b/db/migrate/tables/projects.rb
index 2b95ea20d0b..9d7d2d57559 100644
--- a/db/migrate/tables/projects.rb
+++ b/db/migrate/tables/projects.rb
@@ -49,7 +49,7 @@ class Tables::Projects < Tables::Base
t.index :lft, name: "index_projects_on_lft"
t.index :rgt, name: "index_projects_on_rgt"
- t.index :identifier, unique: true
+ t.index "LOWER(identifier)", unique: true, name: "index_projects_on_lower_identifier"
t.index %i[lft rgt]
end
end
diff --git a/docker/dev/backend/Dockerfile b/docker/dev/backend/Dockerfile
index e2a04a60889..8e6a5df6bc6 100644
--- a/docker/dev/backend/Dockerfile
+++ b/docker/dev/backend/Dockerfile
@@ -1,4 +1,4 @@
-FROM ruby:4.0.1-trixie AS develop
+FROM ruby:4.0.2-trixie AS develop
LABEL org.opencontainers.image.authors="operations@openproject.com"
ARG DEV_UID=1000
diff --git a/docker/dev/xwiki/README.md b/docker/dev/xwiki/README.md
index 4935b6d3109..7832c8e3e63 100644
--- a/docker/dev/xwiki/README.md
+++ b/docker/dev/xwiki/README.md
@@ -1,7 +1,6 @@
# Setup guide
-A minimal setup guide for using a local XWiki inside a docker stack. The example compose file is connected to the
-standard setup of the TLS-ready stack with `traefik`.
+A minimal setup guide for using a local XWiki inside a docker stack. The example compose file is connected to the standard setup of the [TLS-ready](https://www.openproject.org/docs/development/development-environment/docker/#tls-support) stack with `traefik`.
## First steps
@@ -9,4 +8,37 @@ standard setup of the TLS-ready stack with `traefik`.
- Go to https://xwiki.local
- Wait for initialisation to succeed
- Create admin user
-- Select XWiki standard flavor and install it
+- Select XWiki standard flavor and install it — **this is highly recommended** as many XWiki
+ features and the OpenProject plugin depend on it
+
+## Recommended extensions
+
+For integration with OpenProject, install the following after the standard flavor is set up:
+
+- **[OpenProject Integration](https://store.xwiki.com/xwiki/bin/view/Extension/OpenProjectIntegration)** — connects XWiki with OpenProject
+
+Install it via the Extension Manager (Administration → Extensions → search for "OpenProject Integration").
+
+## Updating XWiki
+
+To update XWiki to a newer version, pull the latest image and recreate the container:
+
+```bash
+docker compose --project-directory docker/dev/xwiki/ pull
+docker compose --project-directory docker/dev/xwiki/ up -d
+```
+
+After the container starts, go to — XWiki will detect the new version and
+present an upgrade wizard. Follow it to completion before using XWiki again.
+
+## Certificates
+
+### Trusting the local CA in XWiki (for outbound HTTPS calls)
+
+XWiki runs on Java/Tomcat which has its own certificate truststore, independent of the system CA
+bundle. If XWiki needs to make HTTPS requests to OpenProject (e.g. for OAuth), it must trust the
+local step-ca root certificate.
+
+Copy `docker-compose.override.example.yml` to `docker-compose.override.yml` — it wraps the XWiki
+entrypoint to automatically import the step-ca certificate into Java's truststore on every container
+start, including after recreations. Requires the TLS stack (`docker/dev/tls`) to be running.
diff --git a/docker/dev/xwiki/docker-compose.override.example.yml b/docker/dev/xwiki/docker-compose.override.example.yml
new file mode 100644
index 00000000000..39b8877bbc4
--- /dev/null
+++ b/docker/dev/xwiki/docker-compose.override.example.yml
@@ -0,0 +1,22 @@
+services:
+ web:
+ volumes:
+ - step-certs:/step:ro
+ # Automatically imports the local step-ca root certificate into Java's truststore on every
+ # container start, so XWiki can make HTTPS calls to OpenProject without certificate errors.
+ # Requires the TLS stack (docker/dev/tls) to be running.
+ entrypoint:
+ - /bin/bash
+ - -c
+ - |
+ keytool -import -trustcacerts \
+ -keystore /opt/java/openjdk/lib/security/cacerts \
+ -storepass changeit -noprompt \
+ -alias step-ca \
+ -file /step/certs/root_ca.crt 2>/dev/null || true
+ exec docker-entrypoint.sh xwiki
+
+volumes:
+ step-certs:
+ external: true
+ name: tls_step # volume created by the TLS stack (docker/dev/tls)
diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile
index 2a9177b642a..6f13a27e083 100755
--- a/docker/prod/Dockerfile
+++ b/docker/prod/Dockerfile
@@ -1,4 +1,4 @@
-ARG RUBY_VERSION="4.0.1"
+ARG RUBY_VERSION="4.0.2"
ARG DEBIAN_BASE="trixie"
# Add SBOM scan context for intermediate steps
ARG BUILDKIT_SBOM_SCAN_CONTEXT=true
diff --git a/docs/api/apiv3/components/examples/meeting_create_request.yml b/docs/api/apiv3/components/examples/meeting_create_request.yml
new file mode 100644
index 00000000000..44572a181fc
--- /dev/null
+++ b/docs/api/apiv3/components/examples/meeting_create_request.yml
@@ -0,0 +1,12 @@
+# Example: Meeting create request
+---
+description: Request to create a basic meeting
+value:
+ title: "Weekly Standup"
+ location: "Conference Room A"
+ startTime: "2026-06-01T10:00:00Z"
+ duration: "PT1H"
+ _links:
+ project:
+ href: "/api/v3/projects/10"
+ title: "Death Star"
diff --git a/docs/api/apiv3/components/examples/meeting_update_request.yml b/docs/api/apiv3/components/examples/meeting_update_request.yml
new file mode 100644
index 00000000000..219f1973f36
--- /dev/null
+++ b/docs/api/apiv3/components/examples/meeting_update_request.yml
@@ -0,0 +1,7 @@
+# Example: Meeting update request
+---
+description: Example request body to update the title and location of a meeting.
+value:
+ title: "Updated Standup"
+ location: "Room B"
+ lockVersion: 13
diff --git a/docs/api/apiv3/components/schemas/meeting_agenda_item_collection_model.yml b/docs/api/apiv3/components/schemas/meeting_agenda_item_collection_model.yml
new file mode 100644
index 00000000000..d469ebae6e6
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_agenda_item_collection_model.yml
@@ -0,0 +1,39 @@
+# Schema: MeetingAgendaItemCollectionModel
+---
+type: object
+required:
+ - _type
+ - count
+ - total
+ - _embedded
+ - _links
+properties:
+ _type:
+ type: string
+ enum:
+ - Collection
+ count:
+ type: integer
+ total:
+ type: integer
+ _embedded:
+ type: object
+ required:
+ - elements
+ properties:
+ elements:
+ type: array
+ items:
+ $ref: './meeting_agenda_item_model.yml'
+ _links:
+ type: object
+ required:
+ - self
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The link to this agenda item collection resource
+
+ **Resource**: MeetingAgendaItemCollection
diff --git a/docs/api/apiv3/components/schemas/meeting_agenda_item_model.yml b/docs/api/apiv3/components/schemas/meeting_agenda_item_model.yml
new file mode 100644
index 00000000000..3da594f9198
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_agenda_item_model.yml
@@ -0,0 +1,99 @@
+# Schema: MeetingAgendaItemModel
+---
+type: object
+required:
+ - _type
+ - id
+ - title
+ - itemType
+ - position
+ - createdAt
+ - updatedAt
+properties:
+ _type:
+ type: string
+ enum:
+ - MeetingAgendaItem
+ id:
+ type: integer
+ description: Identifier of this agenda item
+ minimum: 1
+ title:
+ type: string
+ description: The agenda item's title. Required for simple items.
+ notes:
+ $ref: "./formattable.yml"
+ position:
+ type: integer
+ description: The position of the agenda item within its section.
+ durationInMinutes:
+ type:
+ - integer
+ - "null"
+ description: The agenda item's duration in minutes.
+ itemType:
+ type: string
+ description: |-
+ The type of this agenda item. Possible values:
+
+ - *simple*: a simple text agenda item
+ - *work_package*: an agenda item linked to a work package
+ enum:
+ - simple
+ - work_package
+ lockVersion:
+ type: integer
+ description: The version of the item as used for optimistic locking.
+ createdAt:
+ type: string
+ format: date-time
+ description: Time of creation.
+ updatedAt:
+ type: string
+ format: date-time
+ description: Time of the most recent change.
+ _links:
+ type: object
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ This agenda item
+
+ **Resource**: MeetingAgendaItem
+ meeting:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The meeting this agenda item belongs to
+
+ **Resource**: Meeting
+ author:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The user who created this agenda item
+
+ **Resource**: User
+ presenter:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The user presenting this agenda item
+
+ **Resource**: User
+ workPackage:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The linked work package (for work_package type items)
+
+ **Resource**: WorkPackage
+ section:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The section this agenda item belongs to
+
+ **Resource**: MeetingSection
diff --git a/docs/api/apiv3/components/schemas/meeting_agenda_item_write_model.yml b/docs/api/apiv3/components/schemas/meeting_agenda_item_write_model.yml
new file mode 100644
index 00000000000..0bfa4b7d88d
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_agenda_item_write_model.yml
@@ -0,0 +1,47 @@
+# Schema: MeetingAgendaItemWriteModel
+---
+type: object
+properties:
+ title:
+ type: string
+ description: The agenda item's title.
+ notes:
+ $ref: "./formattable.yml"
+ durationInMinutes:
+ type:
+ - integer
+ - "null"
+ description: The agenda item's duration in minutes.
+ itemType:
+ type: string
+ description: The type of this agenda item (simple or work_package).
+ enum:
+ - simple
+ - work_package
+ lockVersion:
+ type: integer
+ description: The version of the item as used for optimistic locking. Required for PATCH operations.
+ _links:
+ type: object
+ properties:
+ workPackage:
+ allOf:
+ - $ref: "./link.yml"
+ - description: |-
+ The linked work package (for work_package type items)
+
+ **Resource**: WorkPackage
+ presenter:
+ allOf:
+ - $ref: "./link.yml"
+ - description: |-
+ The user presenting this agenda item
+
+ **Resource**: User
+ section:
+ allOf:
+ - $ref: "./link.yml"
+ - description: |-
+ The section this agenda item belongs to
+
+ **Resource**: MeetingSection
diff --git a/docs/api/apiv3/components/schemas/meeting_model.yml b/docs/api/apiv3/components/schemas/meeting_model.yml
index 0b518a1d20e..66f35a97841 100644
--- a/docs/api/apiv3/components/schemas/meeting_model.yml
+++ b/docs/api/apiv3/components/schemas/meeting_model.yml
@@ -36,10 +36,45 @@ properties:
endTime:
type: string
format: date-time
- description: The scheduled meeting start time.
+ description: The scheduled meeting end time.
duration:
- type: number
+ type: string
+ format: duration
description: The meeting duration in hours.
+ state:
+ type: string
+ description: |-
+ The current state of the meeting. Possible values:
+
+ - *open*: the meeting is open
+ - *draft*: the meeting is in draft state
+ - *in_progress*: the meeting is currently in progress
+ - *cancelled*: the meeting has been cancelled
+ - *closed*: the meeting is closed
+ enum:
+ - open
+ - draft
+ - in_progress
+ - cancelled
+ - closed
+ sharing:
+ type: string
+ description: |-
+ How the meeting template is shared. Only applicable for one-time templates. Possible values:
+
+ - *none*: not shared
+ - *descendants*: shared with descendant projects
+ - *system*: shared globally
+ enum:
+ - none
+ - descendants
+ - system
+ template:
+ type: boolean
+ description: Whether this meeting is a template.
+ notify:
+ type: boolean
+ description: Whether to send email notifications to participants.
createdAt:
type: string
format: date-time
@@ -70,6 +105,40 @@ properties:
This meeting
**Resource**: Meeting
+ schema:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The meeting schema
+
+ **Resource**: Schema
+ update:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ Form endpoint to update this meeting
+
+ # Conditions
+
+ **Permission**: edit meetings
+ updateImmediately:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ Directly update this meeting
+
+ # Conditions
+
+ **Permission**: edit meetings
+ delete:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ Delete this meeting
+
+ # Conditions
+
+ **Permission**: delete meetings
author:
allOf:
- $ref: './link.yml'
@@ -88,7 +157,7 @@ properties:
allOf:
- $ref: './link.yml'
- description: |-
- The attachment collection of this grid.
+ The attachment collection of this meeting.
**Resource**: AttachmentCollection
addAttachment:
@@ -99,4 +168,4 @@ properties:
# Conditions
- **Permission**: edit meeting
+ **Permission**: edit meetings
diff --git a/docs/api/apiv3/components/schemas/meeting_section_collection_model.yml b/docs/api/apiv3/components/schemas/meeting_section_collection_model.yml
new file mode 100644
index 00000000000..cb623c6f122
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_section_collection_model.yml
@@ -0,0 +1,39 @@
+# Schema: MeetingSectionCollectionModel
+---
+type: object
+required:
+ - _type
+ - count
+ - total
+ - _embedded
+ - _links
+properties:
+ _type:
+ type: string
+ enum:
+ - Collection
+ count:
+ type: integer
+ total:
+ type: integer
+ _embedded:
+ type: object
+ required:
+ - elements
+ properties:
+ elements:
+ type: array
+ items:
+ $ref: './meeting_section_model.yml'
+ _links:
+ type: object
+ required:
+ - self
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The link to this section collection resource
+
+ **Resource**: MeetingSectionCollection
diff --git a/docs/api/apiv3/components/schemas/meeting_section_model.yml b/docs/api/apiv3/components/schemas/meeting_section_model.yml
new file mode 100644
index 00000000000..d749e3ee1ca
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_section_model.yml
@@ -0,0 +1,50 @@
+# Schema: MeetingSectionModel
+---
+type: object
+required:
+ - _type
+ - id
+ - title
+ - position
+ - createdAt
+ - updatedAt
+properties:
+ _type:
+ type: string
+ enum:
+ - MeetingSection
+ id:
+ type: integer
+ description: Identifier of this section
+ minimum: 1
+ title:
+ type: string
+ description: The section's title.
+ position:
+ type: integer
+ description: The position of the section within the meeting.
+ createdAt:
+ type: string
+ format: date-time
+ description: Time of creation.
+ updatedAt:
+ type: string
+ format: date-time
+ description: Time of the most recent change.
+ _links:
+ type: object
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ This section
+
+ **Resource**: MeetingSection
+ meeting:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The meeting this section belongs to
+
+ **Resource**: Meeting
diff --git a/docs/api/apiv3/components/schemas/meeting_section_write_model.yml b/docs/api/apiv3/components/schemas/meeting_section_write_model.yml
new file mode 100644
index 00000000000..814ab4e51c7
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_section_write_model.yml
@@ -0,0 +1,7 @@
+# Schema: MeetingSectionWriteModel
+---
+type: object
+properties:
+ title:
+ type: string
+ description: The section's title.
diff --git a/docs/api/apiv3/components/schemas/meeting_write_model.yml b/docs/api/apiv3/components/schemas/meeting_write_model.yml
new file mode 100644
index 00000000000..60c6f7acf4c
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/meeting_write_model.yml
@@ -0,0 +1,64 @@
+# Schema: MeetingWriteModel
+---
+type: object
+properties:
+ title:
+ type: string
+ description: The meeting's title
+ location:
+ type: string
+ description: The meeting's location
+ startTime:
+ type: string
+ format: date-time
+ description: The scheduled meeting start time.
+ duration:
+ type: string
+ description: |-
+ The meeting duration as an ISO 8601 duration (e.g. `PT1H` for 1 hour, `PT1H30M` for 1.5 hours).
+ state:
+ type: string
+ description: |-
+ The current state of the meeting. Possible values:
+
+ - *open*
+ - *draft*
+ - *in_progress*
+ - *cancelled*
+ - *closed*
+ enum:
+ - open
+ - draft
+ - in_progress
+ - cancelled
+ - closed
+ sharing:
+ type: string
+ description: |-
+ How the meeting template is shared. Only applicable for one-time templates.
+ enum:
+ - none
+ - descendants
+ - system
+ template:
+ type: boolean
+ description: Whether this meeting is a template.
+ notify:
+ type: boolean
+ description: Whether to send email notifications to participants.
+ lockVersion:
+ type: integer
+ description: |-
+ The version of the item as used for optimistic locking.
+
+ Required for PATCH operations to detect concurrent modifications.
+ _links:
+ type: object
+ properties:
+ project:
+ allOf:
+ - $ref: "./link.yml"
+ - description: |-
+ The project the meeting belongs to. Required on creation.
+
+ **Resource**: Project
diff --git a/docs/api/apiv3/components/schemas/recurring_meeting_collection_model.yml b/docs/api/apiv3/components/schemas/recurring_meeting_collection_model.yml
new file mode 100644
index 00000000000..107ffdf21fb
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/recurring_meeting_collection_model.yml
@@ -0,0 +1,30 @@
+# Schema: RecurringMeetingCollectionModel
+---
+allOf:
+ - $ref: './paginated_collection_model.yml'
+ - type: object
+ required:
+ - _embedded
+ - _links
+ properties:
+ _embedded:
+ type: object
+ required:
+ - elements
+ properties:
+ elements:
+ type: array
+ items:
+ $ref: './recurring_meeting_model.yml'
+ _links:
+ type: object
+ required:
+ - self
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The link to this recurring meeting collection resource
+
+ **Resource**: RecurringMeetingCollection
diff --git a/docs/api/apiv3/components/schemas/recurring_meeting_model.yml b/docs/api/apiv3/components/schemas/recurring_meeting_model.yml
new file mode 100644
index 00000000000..4bdfcbfc387
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/recurring_meeting_model.yml
@@ -0,0 +1,171 @@
+# Schema: RecurringMeetingModel
+---
+type: object
+required:
+ - _type
+ - id
+ - title
+ - frequency
+ - interval
+ - endAfter
+ - startTime
+ - createdAt
+ - updatedAt
+properties:
+ _type:
+ type: string
+ enum:
+ - RecurringMeeting
+ id:
+ type: integer
+ description: Identifier of this recurring meeting
+ minimum: 1
+ title:
+ type: string
+ description: The recurring meeting's title
+ frequency:
+ type: string
+ description: |-
+ The recurrence frequency. Possible values:
+
+ - *daily*: repeats every day (or every N days depending on interval)
+ - *working_days*: repeats on working days only
+ - *weekly*: repeats every week (or every N weeks depending on interval)
+ enum:
+ - daily
+ - working_days
+ - weekly
+ interval:
+ type: integer
+ description: |-
+ The interval between occurrences. For example, an interval of 2 with a weekly frequency
+ means the meeting occurs every 2 weeks. Not applicable for working_days frequency.
+ minimum: 1
+ endAfter:
+ type: string
+ description: |-
+ How the recurrence ends. Possible values:
+
+ - *specific_date*: ends on a specific date
+ - *iterations*: ends after a specific number of occurrences
+ - *never*: never ends
+ enum:
+ - specific_date
+ - iterations
+ - never
+ endDate:
+ type:
+ - 'string'
+ - 'null'
+ format: date
+ description: |-
+ The date on which the recurrence ends. Only present when endAfter is `specific_date`.
+ iterations:
+ type:
+ - 'integer'
+ - 'null'
+ description: |-
+ The number of occurrences after which the recurrence ends.
+ Only present when endAfter is `iterations`.
+ minimum: 1
+ timeZone:
+ type: string
+ description: The time zone in which the recurring meeting is scheduled (e.g. "Europe/Berlin").
+ startTime:
+ type: string
+ format: date-time
+ description: The scheduled start time of the recurring meeting.
+ location:
+ type: string
+ description: The meeting's location (inherited from the template meeting).
+ duration:
+ type: number
+ description: The meeting duration in hours (inherited from the template meeting).
+ notify:
+ type: boolean
+ description: Whether to send email notifications to participants (inherited from the template meeting).
+ createdAt:
+ type: string
+ format: date-time
+ description: Time of creation.
+ updatedAt:
+ type: string
+ format: date-time
+ description: Time of the most recent change to the recurring meeting.
+ _links:
+ type: object
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ This recurring meeting
+
+ **Resource**: RecurringMeeting
+ updateImmediately:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ Directly update this recurring meeting
+
+ # Conditions
+
+ **Permission**: edit meetings
+ delete:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ Delete this recurring meeting
+
+ # Conditions
+
+ **Permission**: delete meetings
+ template:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The template meeting associated with this recurring meeting
+
+ **Resource**: Meeting
+ project:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The project the recurring meeting belongs to
+
+ **Resource**: Project
+ author:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The user who created this recurring meeting
+
+ **Resource**: User
+ occurrencesUpcoming:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The upcoming occurrences of this recurring meeting
+
+ **Resource**: MeetingOccurrenceCollection
+ occurrencesPast:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The past occurrences of this recurring meeting
+
+ **Resource**: MeetingOccurrenceCollection
+ occurrencesCancelled:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The cancelled occurrences of this recurring meeting
+
+ **Resource**: MeetingOccurrenceCollection
+ occurrencesOpen:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The open (instantiated) occurrences of this recurring meeting
+
+ **Resource**: MeetingOccurrenceCollection
diff --git a/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_collection_model.yml b/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_collection_model.yml
new file mode 100644
index 00000000000..ba00903bc96
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_collection_model.yml
@@ -0,0 +1,30 @@
+# Schema: RecurringMeetingOccurrenceCollectionModel
+---
+allOf:
+ - $ref: './collection_model.yml'
+ - type: object
+ required:
+ - _links
+ - _embedded
+ properties:
+ _links:
+ type: object
+ required:
+ - self
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ This occurrence collection
+
+ **Resource**: MeetingOccurrenceCollection
+ _embedded:
+ type: object
+ required:
+ - elements
+ properties:
+ elements:
+ type: array
+ items:
+ $ref: './recurring_meeting_occurrence_model.yml'
diff --git a/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_model.yml b/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_model.yml
new file mode 100644
index 00000000000..7139f25c980
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/recurring_meeting_occurrence_model.yml
@@ -0,0 +1,52 @@
+# Schema: RecurringMeetingOccurrenceModel
+---
+type: object
+required:
+ - _type
+ - startTime
+ - state
+properties:
+ _type:
+ type: string
+ enum:
+ - MeetingOccurrence
+ startTime:
+ type: string
+ format: date-time
+ description: The start time of this occurrence.
+ state:
+ type: string
+ description: |-
+ The current state of the occurrence. Possible values:
+
+ - *open*: the occurrence has been instantiated as a meeting
+ - *cancelled*: the occurrence has been cancelled
+ - *scheduled*: the occurrence is scheduled but not yet instantiated
+ enum:
+ - open
+ - cancelled
+ - scheduled
+ _links:
+ type: object
+ properties:
+ self:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ This occurrence
+
+ **Resource**: MeetingOccurrence
+ meeting:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The instantiated meeting for this occurrence, if it exists.
+
+ **Resource**: Meeting
+ recurringMeeting:
+ allOf:
+ - $ref: './link.yml'
+ - description: |-
+ The recurring meeting this occurrence belongs to
+
+ **Resource**: RecurringMeeting
diff --git a/docs/api/apiv3/components/schemas/recurring_meeting_write_model.yml b/docs/api/apiv3/components/schemas/recurring_meeting_write_model.yml
new file mode 100644
index 00000000000..b6e9c44c335
--- /dev/null
+++ b/docs/api/apiv3/components/schemas/recurring_meeting_write_model.yml
@@ -0,0 +1,74 @@
+# Schema: RecurringMeetingWriteModel
+---
+type: object
+properties:
+ title:
+ type: string
+ description: The recurring meeting's title
+ frequency:
+ type: string
+ description: |-
+ The recurrence frequency. Possible values:
+
+ - *daily*
+ - *working_days*
+ - *weekly*
+ enum:
+ - daily
+ - working_days
+ - weekly
+ interval:
+ type: integer
+ description: |-
+ The interval between occurrences. Not applicable for working_days frequency.
+ minimum: 1
+ endAfter:
+ type: string
+ description: |-
+ How the recurrence ends. Possible values:
+
+ - *specific_date*
+ - *iterations*
+ - *never*
+ enum:
+ - specific_date
+ - iterations
+ - never
+ endDate:
+ type:
+ - 'string'
+ - 'null'
+ format: date
+ description: |-
+ The date on which the recurrence ends. Required when endAfter is `specific_date`.
+ iterations:
+ type:
+ - 'integer'
+ - 'null'
+ description: |-
+ The number of occurrences after which the recurrence ends.
+ Required when endAfter is `iterations`.
+ minimum: 1
+ startTime:
+ type: string
+ format: date-time
+ description: The scheduled start time of the recurring meeting.
+ location:
+ type: string
+ description: The meeting's location.
+ duration:
+ type: number
+ description: The meeting duration in hours.
+ notify:
+ type: boolean
+ description: Whether to send email notifications to participants.
+ _links:
+ type: object
+ properties:
+ project:
+ allOf:
+ - $ref: "./link.yml"
+ - description: |-
+ The project the recurring meeting belongs to. Required on creation.
+
+ **Resource**: Project
diff --git a/docs/api/apiv3/components/schemas/work_package_model.yml b/docs/api/apiv3/components/schemas/work_package_model.yml
index 2343dcb7555..0caf6b15f71 100644
--- a/docs/api/apiv3/components/schemas/work_package_model.yml
+++ b/docs/api/apiv3/components/schemas/work_package_model.yml
@@ -12,6 +12,14 @@ allOf:
description: Work package id
readOnly: true
minimum: 1
+ displayId:
+ type: string
+ description: |-
+ The user-facing identifier for the work package.
+ Its format depends on the `work_packages_identifier` setting.
+ When set to `semantic`: the project-based identifier (e.g. "PROJ-42").
+ When set to `classic`: the numeric ID as a string (e.g. "123").
+ readOnly: true
lockVersion:
type: integer
description: The version of the item as used for optimistic locking
diff --git a/docs/api/apiv3/openapi-spec.yml b/docs/api/apiv3/openapi-spec.yml
index 36fbb00300d..2a50ea44013 100644
--- a/docs/api/apiv3/openapi-spec.yml
+++ b/docs/api/apiv3/openapi-spec.yml
@@ -270,8 +270,22 @@ paths:
"$ref": "./paths/meetings.yml"
"/api/v3/meetings/{id}":
"$ref": "./paths/meeting.yml"
+ "/api/v3/meetings/{id}/agenda_items":
+ "$ref": "./paths/meeting_agenda_items.yml"
+ "/api/v3/meetings/{meeting_id}/agenda_items/{id}":
+ "$ref": "./paths/meeting_agenda_item.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"
+ "/api/v3/meetings/{meeting_id}/sections/{id}":
+ "$ref": "./paths/meeting_section.yml"
+ "/api/v3/meetings/form":
+ "$ref": "./paths/meetings_form.yml"
+ "/api/v3/meetings/schema":
+ "$ref": "./paths/meeting_schema.yml"
"/api/v3/memberships":
"$ref": "./paths/memberships.yml"
"/api/v3/memberships/available_projects":
@@ -420,6 +434,22 @@ paths:
"$ref": "./paths/query_star.yml"
"/api/v3/queries/{id}/unstar":
"$ref": "./paths/query_unstar.yml"
+ "/api/v3/recurring_meetings":
+ "$ref": "./paths/recurring_meetings.yml"
+ "/api/v3/recurring_meetings/{id}":
+ "$ref": "./paths/recurring_meeting.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/upcoming":
+ "$ref": "./paths/recurring_meeting_occurrences_upcoming.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/past":
+ "$ref": "./paths/recurring_meeting_occurrences_past.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/cancelled":
+ "$ref": "./paths/recurring_meeting_occurrences_cancelled.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/open":
+ "$ref": "./paths/recurring_meeting_occurrences_open.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/{start_time}":
+ "$ref": "./paths/recurring_meeting_occurrence.yml"
+ "/api/v3/recurring_meetings/{id}/occurrences/{start_time}/init":
+ "$ref": "./paths/recurring_meeting_occurrence_init.yml"
"/api/v3/relations":
"$ref": "./paths/relations.yml"
"/api/v3/relations/{id}":
@@ -609,6 +639,10 @@ components:
$ref: "./components/examples/meeting_collection_simple_response.yml"
MeetingSimpleResponse:
$ref: "./components/examples/meeting_simple_response.yml"
+ MeetingCreateRequest:
+ $ref: "./components/examples/meeting_create_request.yml"
+ MeetingUpdateRequest:
+ $ref: "./components/examples/meeting_update_request.yml"
MembershipCreateRequestCustomMessage:
$ref: "./components/examples/membership-create-request-custom-message.yml"
MembershipCreateRequestGlobalRole:
@@ -851,10 +885,24 @@ components:
"$ref": "./components/schemas/list_of_news_model.yml"
List_workspaces_by_versionModel:
"$ref": "./components/schemas/list_workspaces_by_version_model.yml"
+ MeetingAgendaItemModel:
+ "$ref": "./components/schemas/meeting_agenda_item_model.yml"
+ MeetingAgendaItemWriteModel:
+ "$ref": "./components/schemas/meeting_agenda_item_write_model.yml"
+ MeetingAgendaItemCollectionModel:
+ "$ref": "./components/schemas/meeting_agenda_item_collection_model.yml"
MeetingCollectionModel:
"$ref": "./components/schemas/meeting_collection_model.yml"
MeetingModel:
"$ref": "./components/schemas/meeting_model.yml"
+ MeetingSectionModel:
+ "$ref": "./components/schemas/meeting_section_model.yml"
+ MeetingSectionWriteModel:
+ "$ref": "./components/schemas/meeting_section_write_model.yml"
+ MeetingSectionCollectionModel:
+ "$ref": "./components/schemas/meeting_section_collection_model.yml"
+ MeetingWriteModel:
+ "$ref": "./components/schemas/meeting_write_model.yml"
MarkdownModel:
"$ref": "./components/schemas/markdown_model.yml"
MembershipCollectionModel:
@@ -955,6 +1003,16 @@ components:
"$ref": "./components/schemas/query_sort_by_model.yml"
Query_Update_Form:
"$ref": "./components/schemas/query_update_form.yml"
+ RecurringMeetingCollectionModel:
+ "$ref": "./components/schemas/recurring_meeting_collection_model.yml"
+ RecurringMeetingModel:
+ "$ref": "./components/schemas/recurring_meeting_model.yml"
+ RecurringMeetingWriteModel:
+ "$ref": "./components/schemas/recurring_meeting_write_model.yml"
+ RecurringMeetingOccurrenceCollectionModel:
+ "$ref": "./components/schemas/recurring_meeting_occurrence_collection_model.yml"
+ RecurringMeetingOccurrenceModel:
+ "$ref": "./components/schemas/recurring_meeting_occurrence_model.yml"
RelationCollectionModel:
"$ref": "./components/schemas/relation_collection_model.yml"
RelationReadModel:
diff --git a/docs/api/apiv3/paths/meeting.yml b/docs/api/apiv3/paths/meeting.yml
index e0ec3ef46f9..5ba946d8f45 100644
--- a/docs/api/apiv3/paths/meeting.yml
+++ b/docs/api/apiv3/paths/meeting.yml
@@ -38,4 +38,131 @@ get:
description: |-
Returned if the meeting does not exist or the client does not have sufficient permissions to see it.
- **Required permission:** view meetings in the page's project
+ **Required permission:** view meetings in the meeting's project
+
+patch:
+ summary: Update meeting
+ operationId: update_meeting
+ tags:
+ - Meetings
+ description: |-
+ Updates the given meeting by applying the attributes provided in the body.
+ parameters:
+ - description: Meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_write_model.yml"
+ examples:
+ 'update meeting':
+ $ref: "../components/examples/meeting_update_request.yml"
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_model.yml"
+ examples:
+ response:
+ $ref: "../components/examples/meeting_simple_response.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:** edit meetings in the meeting's project
+ '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 in the meeting's project
+ '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 meeting
+ operationId: delete_meeting
+ tags:
+ - Meetings
+ description: Deletes the meeting. Participants will be notified of the cancellation.
+ parameters:
+ - description: Meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ responses:
+ '204':
+ description: Returned if the meeting 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:** delete meetings
+ '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 in the meeting's project
+ '406':
+ $ref: "../components/responses/missing_content_type.yml"
+ '415':
+ $ref: "../components/responses/unsupported_media_type.yml"
diff --git a/docs/api/apiv3/paths/meeting_agenda_item.yml b/docs/api/apiv3/paths/meeting_agenda_item.yml
new file mode 100644
index 00000000000..4c11743260b
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_agenda_item.yml
@@ -0,0 +1,169 @@
+# /api/v3/meetings/{meeting_id}/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.
+ 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.
+
+patch:
+ summary: Update a meeting agenda item
+ operationId: update_meeting_agenda_item
+ tags:
+ - 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
+ name: id
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_agenda_item_write_model.yml"
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_agenda_item_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 agendas
+ '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.
+ '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 agenda item
+ operationId: delete_meeting_agenda_item
+ tags:
+ - 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
+ name: id
+ required: true
+ schema:
+ type: integer
+ responses:
+ '204':
+ description: Returned if the agenda item 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 agendas
+ '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.
diff --git a/docs/api/apiv3/paths/meeting_agenda_items.yml b/docs/api/apiv3/paths/meeting_agenda_items.yml
new file mode 100644
index 00000000000..590180f157d
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_agenda_items.yml
@@ -0,0 +1,104 @@
+# /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
+
+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
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_agenda_item_write_model.yml"
+ responses:
+ '201':
+ description: Created
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_agenda_item_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 agendas
+ '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.
+ '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_form.yml b/docs/api/apiv3/paths/meeting_form.yml
new file mode 100644
index 00000000000..f354e2b5027
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_form.yml
@@ -0,0 +1,42 @@
+# /api/v3/meetings/{id}/form
+---
+post:
+ summary: Meeting update form
+ operationId: meeting_update_form
+ tags:
+ - Meetings
+ description: ''
+ parameters:
+ - description: Meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ responses:
+ '200':
+ description: OK
+ headers: {}
+ '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:** edit meetings in the meeting's project
+ headers: {}
+ '406':
+ $ref: "../components/responses/missing_content_type.yml"
+ '415':
+ $ref: "../components/responses/unsupported_media_type.yml"
diff --git a/docs/api/apiv3/paths/meeting_schema.yml b/docs/api/apiv3/paths/meeting_schema.yml
new file mode 100644
index 00000000000..28dc2d01491
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_schema.yml
@@ -0,0 +1,29 @@
+# /api/v3/meetings/schema
+---
+get:
+ summary: Get meeting schema
+ operationId: get_meeting_schema
+ tags:
+ - Meetings
+ description: |-
+ Retrieves the schema for meetings, providing information about which properties are writable,
+ their types, and constraints.
+ responses:
+ '200':
+ description: OK
+ headers: {}
+ '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:** view meetings in any project
diff --git a/docs/api/apiv3/paths/meeting_section.yml b/docs/api/apiv3/paths/meeting_section.yml
new file mode 100644
index 00000000000..79c167db431
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_section.yml
@@ -0,0 +1,169 @@
+# /api/v3/meetings/{meeting_id}/sections/{id}
+---
+get:
+ summary: Get a meeting section
+ operationId: get_meeting_section
+ 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.
+
+patch:
+ summary: Update a meeting section
+ operationId: update_meeting_section
+ tags:
+ - Meetings
+ description: Updates the given section.
+ 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
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_section_write_model.yml"
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_section_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 agendas
+ '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.
+ '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 section
+ operationId: delete_meeting_section
+ tags:
+ - Meetings
+ description: Deletes the section and all its agenda items.
+ 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:
+ '204':
+ description: Returned if the section 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 agendas
+ '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.
diff --git a/docs/api/apiv3/paths/meeting_sections.yml b/docs/api/apiv3/paths/meeting_sections.yml
new file mode 100644
index 00000000000..5d5bf04218a
--- /dev/null
+++ b/docs/api/apiv3/paths/meeting_sections.yml
@@ -0,0 +1,104 @@
+# /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
+
+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
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_section_write_model.yml"
+ responses:
+ '201':
+ description: Created
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_section_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 agendas
+ '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.
+ '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/meetings.yml b/docs/api/apiv3/paths/meetings.yml
index 8550f7ebabe..6901a7126c1 100644
--- a/docs/api/apiv3/paths/meetings.yml
+++ b/docs/api/apiv3/paths/meetings.yml
@@ -5,7 +5,7 @@ get:
operationId: list_meetings
tags:
- Meetings
- description: |-
+ description: |-
Retrieve a paginated collection of meetings visible to the authenticated user.
responses:
'200':
@@ -17,3 +17,58 @@ get:
$ref: "../components/examples/meeting_collection_simple_response.yml"
schema:
$ref: "../components/schemas/meeting_collection_model.yml"
+
+post:
+ summary: Create meeting
+ operationId: create_meeting
+ tags:
+ - Meetings
+ description: |-
+ Creates a new meeting applying the attributes provided in the body.
+
+ You can use the form and schema to retrieve the valid attribute values and by that be guided towards
+ successful creation.
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/meeting_write_model.yml"
+ examples:
+ 'create meeting':
+ $ref: '../components/examples/meeting_create_request.yml'
+ responses:
+ '201':
+ description: Created
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_model.yml"
+ examples:
+ response:
+ $ref: '../components/examples/meeting_simple_response.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:** create meetings
+ '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/meetings_form.yml b/docs/api/apiv3/paths/meetings_form.yml
new file mode 100644
index 00000000000..f3fb3c2b7e4
--- /dev/null
+++ b/docs/api/apiv3/paths/meetings_form.yml
@@ -0,0 +1,34 @@
+# /api/v3/meetings/form
+---
+post:
+ summary: Meeting create form
+ operationId: meeting_create_form
+ tags:
+ - Meetings
+ description: ''
+ responses:
+ '200':
+ description: OK
+ headers: {}
+ '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:** create meetings in any project
+ headers: {}
+ '406':
+ $ref: "../components/responses/missing_content_type.yml"
+ '415':
+ $ref: "../components/responses/unsupported_media_type.yml"
diff --git a/docs/api/apiv3/paths/recurring_meeting.yml b/docs/api/apiv3/paths/recurring_meeting.yml
new file mode 100644
index 00000000000..340f0dafc7e
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting.yml
@@ -0,0 +1,164 @@
+# /api/v3/recurring_meetings/{id}
+---
+get:
+ summary: Get a recurring meeting
+ operationId: get_recurring_meeting
+ tags:
+ - Recurring Meetings
+ description: Retrieve an individual recurring meeting series as identified by the id parameter.
+ parameters:
+ - description: Recurring 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/recurring_meeting_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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
+
+patch:
+ summary: Update recurring meeting
+ operationId: update_recurring_meeting
+ tags:
+ - Recurring Meetings
+ description: |-
+ Updates the given recurring meeting series by applying the attributes provided in the body.
+ If schedule-related attributes (frequency, interval, startTime, endAfter, etc.) are changed,
+ the meeting schedule is automatically recalculated.
+ parameters:
+ - description: Recurring meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_write_model.yml"
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_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:** edit meetings in the recurring meeting's project
+ '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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
+ '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 recurring meeting
+ operationId: delete_recurring_meeting
+ tags:
+ - Recurring Meetings
+ description: |-
+ Deletes the entire recurring meeting series, including the template meeting and all
+ scheduled occurrences that have not yet been instantiated. Already-created meeting
+ instances are not deleted.
+ parameters:
+ - description: Recurring meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ responses:
+ '204':
+ description: Returned if the recurring meeting 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:** delete meetings
+ '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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
+ '406':
+ $ref: "../components/responses/missing_content_type.yml"
+ '415':
+ $ref: "../components/responses/unsupported_media_type.yml"
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrence.yml b/docs/api/apiv3/paths/recurring_meeting_occurrence.yml
new file mode 100644
index 00000000000..7e1bf67e5ea
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrence.yml
@@ -0,0 +1,76 @@
+# /api/v3/recurring_meetings/{id}/occurrences/{start_time}
+---
+delete:
+ summary: Cancel an occurrence
+ operationId: cancel_recurring_meeting_occurrence
+ tags:
+ - Recurring Meetings
+ description: |-
+ Cancels the occurrence at the given `start_time` for this recurring meeting series.
+ A `ScheduledMeeting` record is created (or updated) with `cancelled: true`.
+
+ An occurrence that has already been instantiated as a meeting cannot be cancelled via this
+ endpoint — delete the meeting directly via `DELETE /api/v3/meetings/{id}` instead.
+ parameters:
+ - description: Recurring meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ - description: The ISO 8601 start time of the occurrence to cancel (e.g. `2025-06-02T10:00:00Z`)
+ example: "2025-06-02T10:00:00Z"
+ in: path
+ name: start_time
+ required: true
+ schema:
+ type: string
+ format: date-time
+ responses:
+ '204':
+ description: Returned if the occurrence was successfully cancelled.
+ '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:** edit meetings in the recurring meeting's project
+ '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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
+ '409':
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/error_response.yml"
+ examples:
+ response:
+ value:
+ _type: Error
+ errorIdentifier: urn:openproject-org:api:v3:errors:Conflict
+ message: Cannot cancel an already instantiated occurrence. Delete the meeting instead.
+ description: |-
+ Returned if the occurrence has already been instantiated as a meeting.
+ Delete the meeting directly via `DELETE /api/v3/meetings/{id}` instead.
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrence_init.yml b/docs/api/apiv3/paths/recurring_meeting_occurrence_init.yml
new file mode 100644
index 00000000000..8f7d024a47c
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrence_init.yml
@@ -0,0 +1,68 @@
+# /api/v3/recurring_meetings/{id}/occurrences/{start_time}/init
+---
+post:
+ summary: Instantiate an occurrence
+ operationId: init_recurring_meeting_occurrence
+ tags:
+ - Recurring Meetings
+ description: |-
+ Instantiates the occurrence at the given `start_time` by creating a real meeting from
+ the recurring meeting's template. Returns the newly created `Meeting` resource.
+ parameters:
+ - description: Recurring meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ - description: The ISO 8601 start time of the occurrence to instantiate (e.g. `2025-06-02T10:00:00Z`)
+ example: "2025-06-02T10:00:00Z"
+ in: path
+ name: start_time
+ required: true
+ schema:
+ type: string
+ format: date-time
+ responses:
+ '201':
+ description: Created — the occurrence was successfully instantiated as a meeting.
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/meeting_model.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:** create meetings in the recurring meeting's project
+ '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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
+ '422':
+ description: |-
+ Returned if:
+
+ * a constraint for a property was violated (`PropertyConstraintViolation`)
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrences_cancelled.yml b/docs/api/apiv3/paths/recurring_meeting_occurrences_cancelled.yml
new file mode 100644
index 00000000000..9b54e7e4dfe
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrences_cancelled.yml
@@ -0,0 +1,40 @@
+# /api/v3/recurring_meetings/{id}/occurrences/cancelled
+---
+get:
+ summary: List cancelled occurrences of a recurring meeting
+ operationId: list_recurring_meeting_occurrences_cancelled
+ tags:
+ - Recurring Meetings
+ description: |-
+ Returns a collection of cancelled occurrences for the given recurring meeting.
+ Only persisted `ScheduledMeeting` records with `cancelled: true` are returned.
+ parameters:
+ - description: Recurring 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/recurring_meeting_occurrence_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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrences_open.yml b/docs/api/apiv3/paths/recurring_meeting_occurrences_open.yml
new file mode 100644
index 00000000000..35fd2dddad0
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrences_open.yml
@@ -0,0 +1,40 @@
+# /api/v3/recurring_meetings/{id}/occurrences/open
+---
+get:
+ summary: List open occurrences of a recurring meeting
+ operationId: list_recurring_meeting_occurrences_open
+ tags:
+ - Recurring Meetings
+ description: |-
+ Returns a collection of open (instantiated, non-cancelled) occurrences for the given recurring meeting.
+ Only persisted `ScheduledMeeting` records that have an associated meeting and are not cancelled are returned.
+ parameters:
+ - description: Recurring 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/recurring_meeting_occurrence_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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrences_past.yml b/docs/api/apiv3/paths/recurring_meeting_occurrences_past.yml
new file mode 100644
index 00000000000..f85e8b54b6d
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrences_past.yml
@@ -0,0 +1,40 @@
+# /api/v3/recurring_meetings/{id}/occurrences/past
+---
+get:
+ summary: List past occurrences of a recurring meeting
+ operationId: list_recurring_meeting_occurrences_past
+ tags:
+ - Recurring Meetings
+ description: |-
+ Returns a collection of past, non-cancelled occurrences for the given recurring meeting.
+ Only persisted `ScheduledMeeting` records with a `start_time` in the past are returned.
+ parameters:
+ - description: Recurring 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/recurring_meeting_occurrence_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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
diff --git a/docs/api/apiv3/paths/recurring_meeting_occurrences_upcoming.yml b/docs/api/apiv3/paths/recurring_meeting_occurrences_upcoming.yml
new file mode 100644
index 00000000000..f063b3f910c
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meeting_occurrences_upcoming.yml
@@ -0,0 +1,51 @@
+# /api/v3/recurring_meetings/{id}/occurrences/upcoming
+---
+get:
+ summary: List upcoming occurrences of a recurring meeting
+ operationId: list_recurring_meeting_occurrences_upcoming
+ tags:
+ - Recurring Meetings
+ description: |-
+ Returns a collection of upcoming occurrences for the given recurring meeting.
+ The list merges computed occurrences from the recurrence schedule (via IceCube) with
+ any persisted `ScheduledMeeting` records, including already-instantiated open meetings.
+
+ Occurrences are ordered chronologically and limited by the `limit` parameter.
+ parameters:
+ - description: Recurring meeting identifier
+ example: 1
+ in: path
+ name: id
+ required: true
+ schema:
+ type: integer
+ - description: Maximum number of occurrences to return. Defaults to 20.
+ example: 20
+ in: query
+ name: limit
+ required: false
+ schema:
+ type: integer
+ default: 20
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_occurrence_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 recurring meeting does not exist or the client does not have sufficient permissions to see it.
+
+ **Required permission:** view meetings in the recurring meeting's project
diff --git a/docs/api/apiv3/paths/recurring_meetings.yml b/docs/api/apiv3/paths/recurring_meetings.yml
new file mode 100644
index 00000000000..f007b219a92
--- /dev/null
+++ b/docs/api/apiv3/paths/recurring_meetings.yml
@@ -0,0 +1,63 @@
+# /api/v3/recurring_meetings
+---
+get:
+ summary: List all visible recurring meetings
+ operationId: list_recurring_meetings
+ tags:
+ - Recurring Meetings
+ description: |-
+ Retrieve a paginated collection of recurring meetings visible to the authenticated user.
+ responses:
+ '200':
+ description: OK
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_collection_model.yml"
+
+post:
+ summary: Create recurring meeting
+ operationId: create_recurring_meeting
+ tags:
+ - Recurring Meetings
+ description: |-
+ Creates a new recurring meeting series applying the attributes provided in the body.
+ A template meeting is automatically created alongside the recurring meeting.
+ requestBody:
+ content:
+ application/json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_write_model.yml"
+ responses:
+ '201':
+ description: Created
+ content:
+ application/hal+json:
+ schema:
+ $ref: "../components/schemas/recurring_meeting_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:** create meetings in the given project
+ '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/development/code-review-guidelines/README.md b/docs/development/code-review-guidelines/README.md
index 7b389298cd5..4c3756dffe6 100644
--- a/docs/development/code-review-guidelines/README.md
+++ b/docs/development/code-review-guidelines/README.md
@@ -16,7 +16,10 @@ The same is true for eslint. Your editor will likely have support for eslint che
**Lefthook**
-For automatically linting your files on committing them, please have a look at [Lefthook](https://github.com/evilmartians/lefthook). You can install these rules by using `bundle exec lefthook install`.
+For automatically linting your files on committing them, please have a look
+at [Lefthook](https://github.com/evilmartians/lefthook). You can install these rules by using `lefthook install`. There
+are several options on how to install `lefthook` on your system, including using `brew`, `apt`, `bundle`, or `npm`. For
+example, one can add a `Gemfile.local` and thus the `lefthook` to the bundle.
### Structure of commit messages
diff --git a/docs/development/development-environment/docker/README.md b/docs/development/development-environment/docker/README.md
index 5c7ccab5ba8..406091f884b 100644
--- a/docs/development/development-environment/docker/README.md
+++ b/docs/development/development-environment/docker/README.md
@@ -63,10 +63,10 @@ You can run tests inside the `backend-test` container. You can run specific test
```shell
# Run all tests (not recommended)
-docker compose run --rm backend-test bundle exec rspec
+bin/compose rspec
# Run the specified test
-docker compose run --rm backend-test bundle exec rspec spec/features/work_package_show_spec.rb
+bin/compose rspec spec/features/work_package_show_spec.rb
```
***
diff --git a/docs/development/development-environment/linux/README.md b/docs/development/development-environment/linux/README.md
index 223026715eb..8b405235892 100644
--- a/docs/development/development-environment/linux/README.md
+++ b/docs/development/development-environment/linux/README.md
@@ -40,10 +40,10 @@ sudo apt-get install git curl build-essential zlib1g-dev libyaml-dev libssl-dev
Use [rbenv](https://github.com/rbenv/rbenv) and [ruby-build](https://github.com/rbenv/ruby-build#readme) to install
Ruby.
You can check available ruby versions with `rbenv install --list`.
-At the time of this writing, the latest stable version is `4.0.1`, which we also require.
+At the time of this writing, the latest stable version is `4.0.2`, which we also require.
We suggest you install the version we require in [.ruby-version](https://github.com/opf/openproject/blob/dev/.ruby-version).
-Read the first line e.g. `4.0.1` and install that version.
+Read the first line e.g. `4.0.2` and install that version.
#### Install rbenv and ruby-build
@@ -80,18 +80,18 @@ With both installed, we can now install ruby.
You can check available ruby versions with `rbenv install --list`.
We suggest you install the version we require in [.ruby-version](https://github.com/opf/openproject/blob/dev/.ruby-version).
-Read the first line e.g. `4.0.1` and install that version.
+Read the first line e.g. `4.0.2` and install that version.
```shell
# Install the required version as read from the .ruby-version file
-rbenv install 4.0.1
+rbenv install 4.0.2
```
This might take a while depending on whether ruby is built from source. After it is complete, you need to tell rbenv to
globally activate this version
```shell
-rbenv global 4.0.1
+rbenv global 4.0.2
rbenv rehash
```
@@ -181,10 +181,10 @@ You should now have an active ruby and node installation. Verify that it works w
```shell
ruby --version
-ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin25]
+ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]
bundler --version
-4.0.3
+4.0.9
node --version
v22.21.0
diff --git a/docs/development/development-environment/macos/README.md b/docs/development/development-environment/macos/README.md
index ba6694a3e7e..b38a65a01ba 100644
--- a/docs/development/development-environment/macos/README.md
+++ b/docs/development/development-environment/macos/README.md
@@ -28,7 +28,7 @@ their homepage.
Use [rbenv](https://github.com/rbenv/rbenv) and [ruby-build](https://github.com/rbenv/ruby-build#readme) to install
Ruby. We always require the latest ruby versions, and you can check which version is required
by [checking the Gemfile](https://github.com/opf/openproject/blob/dev/Gemfile#L31) for the `ruby "~> X.Y"` statement. At
-the time of writing, this version is "4.0.1"
+the time of writing, this version is "4.0.2"
#### Install rbenv and ruby-build
@@ -48,18 +48,18 @@ With both installed, we can now install the actual ruby version.
You can check available ruby versions with `rbenv install --list`.
We suggest you install the version we require in [.ruby-version](https://github.com/opf/openproject/blob/dev/.ruby-version).
-Read the first line e.g. `4.0.1` and install that version.
+Read the first line e.g. `4.0.2` and install that version.
```shell
# Install the required version as read from the .ruby-version file
-rbenv install 4.0.1
+rbenv install 4.0.2
```
This might take a while depending on whether ruby is built from source. After it is complete, you need to tell rbenv to
globally activate this version
```shell
-rbenv global 4.0.1
+rbenv global 4.0.2
```
You also need to install [bundler](https://github.com/bundler/bundler/), the ruby gem bundler.
@@ -134,7 +134,7 @@ You should now have an active ruby and node installation. Verify that it works w
```shell
$ ruby --version
-ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin25]
+ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]
$ bundler --version
4.0.3
@@ -196,7 +196,7 @@ automatically loaded to the application's environment.
> [!TIP]
> Instead of using the `gssencmode` flag in `config/database.yml`, you can add `export PGGSSENCMODE="disable"` to your
-> Shell profile (`~/.zprofile` by default). This will prevent Ruby crashes for *all* of your projects.
+> Shell profile (`~/.zprofile` by default). This will prevent Ruby crashes for _all_ of your projects.
Some users report Ruby crashes despite having set this flag to disable. If this is the case for you as well,
try adding `export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=yes` to your Shell profile.
@@ -328,7 +328,7 @@ sudo ln -sfn $(brew --prefix)/opt/openjdk/libexec/openjdk.jdk /Library/Java/Java
#### Subversion
To test the integration with Subversion repositories, we rely on the `svnadmin` command to be available. If subversion
-is not installed, the tests *will be skipped*. To run the tests, install subversion with
+is not installed, the tests _will be skipped_. To run the tests, install subversion with
```shell
brew install subversion
diff --git a/docs/installation-and-operations/installation/manual/README.md b/docs/installation-and-operations/installation/manual/README.md
index 2092086ffbf..ccc9758556d 100644
--- a/docs/installation-and-operations/installation/manual/README.md
+++ b/docs/installation-and-operations/installation/manual/README.md
@@ -10,16 +10,16 @@ sidebar_navigation: false
Please be aware that:
-* This guide **requires** that you have a clean **Ubuntu 18.04** **x64** installation
-with administrative rights (i.e. you must be able to `sudo`). We have tested
-the installation guide on an Ubuntu Server image, but it should work on any
-derivative. You may need to alter some of the commands to match your
-derivative.
+- This guide **requires** that you have a clean **Ubuntu 18.04** **x64** installation
+ with administrative rights (i.e. you must be able to `sudo`). We have tested
+ the installation guide on an Ubuntu Server image, but it should work on any
+ derivative. You may need to alter some of the commands to match your
+ derivative.
-* OpenProject will be installed with a **PostgreSQL** database.
+- OpenProject will be installed with a **PostgreSQL** database.
-* OpenProject will be served in a production environment with the **Apache** server
-(this guide should work similarly with other servers, like nginx and others)
+- OpenProject will be served in a production environment with the **Apache** server
+ (this guide should work similarly with other servers, like nginx and others)
> **NOTE:** We have highlighted commands to execute like this
@@ -106,19 +106,19 @@ Please be aware that the actual installation of a specific Ruby version takes so
```
We suggest you install the version we require in [.ruby-version](https://github.com/opf/openproject/blob/dev/.ruby-version).
-Read the first line e.g. `4.0.1` and install that version.
+Read the first line e.g. `4.0.2` and install that version.
```shell
-[openproject@host] rbenv install 4.0.1
+[openproject@host] rbenv install 4.0.2
[openproject@host] rbenv rehash
-[openproject@host] rbenv global 4.0.1
+[openproject@host] rbenv global 4.0.2
```
To check our Ruby installation we run `ruby --version`. It should output
something very similar to:
```text
-ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [arm64-darwin25]
+ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]
```
## Installation of Node
@@ -216,7 +216,6 @@ rails_cache_store: :memcache
```
> **NOTE:** You should validate your `yml` files, for example with [yamlchecker.com](https://yamlchecker.com/). Both, the `database.yml` and `configuration.yml` file are sensitive to whitespace. It is pretty easy to write invalid `yml` files without seeing the error. Validating those files prevents you from such errors.
->
To configure the environment variables such as the number of web server threads `OPENPROJECT_WEB_WORKERS`, copy the `.env.example` to `.env` and add the environment variables you want to configure. The variables will be automatically loaded to the application's environment.
@@ -428,7 +427,7 @@ If you need to restart the server (for example after a configuration change), do
## Frequently asked questions (FAQ)
-* **I followed the installation guide faithfully and OpenProject is running. Now, how do I log in?**
+- **I followed the installation guide faithfully and OpenProject is running. Now, how do I log in?**
The `db:seed` command listed above creates a default admin-user. The username is `admin` and the default password is `admin`. You are forced to change the admin password on the first login.
If you cannot login as the admin user, make sure that you have executed the `db:seed` command.
@@ -437,18 +436,18 @@ If you need to restart the server (for example after a configuration change), do
[openproject@all] RAILS_ENV="production" ./bin/rake db:seed
```
-* **When accessing OpenProject, I get an error page. How do I find out what went wrong?**
+- **When accessing OpenProject, I get an error page. How do I find out what went wrong?**
Things can go wrong on different levels. You can find the apache error logs here: `/var/log/apache2/error.log`
The OpenProject log can be found here: `/home/openproject/openproject/log/production.log`
-* **I cannot solve an error, not even with the log files. How do I get help?**
+- **I cannot solve an error, not even with the log files. How do I get help?**
You can find help in [the OpenProject forums](https://community.openproject.org/projects/openproject/boards). Please tell us, if possible, what you have done (e.g. which guide you have used to install OpenProject), how to reproduce the error, and provide the appropriate error logs.
It often helps to have a look at the already answered questions, or to search the Internet for the error. Most likely someone else has already solved the same problem.
-* **I get errors, since I have installed an OpenProject plug-in**
+- **I get errors, since I have installed an OpenProject plug-in**
With each new OpenProject core version, the plug-ins might need to be updated. Please make sure that the plug-in versions of all you plug-ins works with the OpenProject version you use.
Many plug-ins follow the OpenProject version with their version number (So, if you have installed OpenProject version 4.1.0, the plug-in should also have the version 4.1.0).
diff --git a/docs/user-guide/keyboard-shortcuts-access-keys/README.md b/docs/user-guide/keyboard-shortcuts-access-keys/README.md
index f068312b85a..ce8aa0d63df 100644
--- a/docs/user-guide/keyboard-shortcuts-access-keys/README.md
+++ b/docs/user-guide/keyboard-shortcuts-access-keys/README.md
@@ -73,7 +73,7 @@ OpenProject (since version 3.0) offers useful keyboard shortcuts to enhance you
------
-### OS X
+### macOS
- Firefox: Ctrl + Opt + <access key number>
- Google Chrome: Ctrl + Opt + <access key number>
diff --git a/frontend/.mcp.json b/frontend/.mcp.json
new file mode 100644
index 00000000000..d8562ee2149
--- /dev/null
+++ b/frontend/.mcp.json
@@ -0,0 +1,8 @@
+{
+ "mcpServers": {
+ "angular-cli": {
+ "command": "npx",
+ "args": ["-y", "@angular/cli@21.1.5", "mcp"]
+ }
+ }
+}
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index f011d32b7a0..73538ba4860 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -67,7 +67,6 @@
"@stimulus-components/auto-submit": "^6.0.0",
"@stimulus-components/reveal": "^5.0.0",
"@tiptap/extensions": "^3.20.0",
- "@types/jquery.cookie": "^1.4.36",
"@uirouter/angular": "^17.0.0",
"@uirouter/core": "^6.1.0",
"@uirouter/rx": "^1.0.0",
@@ -93,7 +92,6 @@
"idiomorph": "^0.7.4",
"jquery": "^3.7.1",
"jquery.caret": "^0.3.1",
- "jquery.cookie": "^1.4.1",
"json5": "^2.2.2",
"lit-html": "^3.3.2",
"lodash": "^4.17.23",
@@ -126,8 +124,7 @@
"turbo_power": "^0.7.1",
"typedjson": "^1.5.1",
"urijs": "^1.19.11",
- "uuid": "^13.0.0",
- "zone.js": "~0.15.1"
+ "uuid": "^13.0.0"
},
"devDependencies": {
"@angular-builders/custom-esbuild": "^21.0.3",
@@ -139,8 +136,8 @@
"@angular-eslint/template-parser": "20.7.0",
"@angular/language-service": "21.1.6",
"@eslint/js": "^9.39.2",
- "@html-eslint/eslint-plugin": "^0.57.1",
- "@html-eslint/parser": "^0.57.1",
+ "@html-eslint/eslint-plugin": "^0.58.1",
+ "@html-eslint/parser": "^0.58.1",
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
"@stylistic/eslint-plugin": "^5.7.1",
"@types/codemirror": "5.60.5",
@@ -173,7 +170,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^17.3.0",
- "jasmine-core": "~6.0.1",
+ "jasmine-core": "~6.1.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
@@ -4804,19 +4801,6 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@eslint/css-tree": {
- "version": "3.6.9",
- "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-3.6.9.tgz",
- "integrity": "sha512-3D5/OHibNEGk+wKwNwMbz63NMf367EoR4mVNNpxddCHKEb2Nez7z62J2U6YjtErSsZDoY0CsccmoUpdEbkogNA==",
- "dev": true,
- "dependencies": {
- "mdn-data": "2.23.0",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
"node_modules/@eslint/eslintrc": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
@@ -5269,9 +5253,9 @@
}
},
"node_modules/@hono/node-server": {
- "version": "1.19.10",
- "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.10.tgz",
- "integrity": "sha512-hZ7nOssGqRgyV3FVVQdfi+U4q02uB23bpnYpdvNXkYTRRyWx84b7yf1ans+dnJ/7h41sGL3CeQTfO+ZGxuO+Iw==",
+ "version": "1.19.13",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.13.tgz",
+ "integrity": "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ==",
"engines": {
"node": ">=18.14.1"
},
@@ -5302,13 +5286,12 @@
}
},
"node_modules/@html-eslint/core": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/core/-/core-0.57.0.tgz",
- "integrity": "sha512-X/cKrOmXrxZSdgyKwtbaCuuJ1k/u82MK58Q6p1TzfwPatwIYx+icfBv1Vp1dLui0L0y1fwBW4H+TKhBf7mMKmg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/core/-/core-0.58.1.tgz",
+ "integrity": "sha512-GHYDt2Q3ws9aa0/bmMhkv21ExQJnrjKY/iByjdBVp3lBq49wlzIzvAfcx4Bsp+RMV3oPZhzlnLhPpXLuVYt2mQ==",
"dev": true,
"dependencies": {
- "@html-eslint/types": "^0.57.0",
- "eslint": "^9.39.1",
+ "@html-eslint/types": "^0.58.1",
"html-standard": "^0.0.13"
},
"engines": {
@@ -5316,17 +5299,17 @@
}
},
"node_modules/@html-eslint/eslint-plugin": {
- "version": "0.57.1",
- "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.57.1.tgz",
- "integrity": "sha512-IDfdk3V27eebNpdXD2NLy/lnTSbUuKrro/6YJICBn/9aiXPXagNqWJB38qcSWEoxADbXfSSn17DJWcXvQTkHBg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.58.1.tgz",
+ "integrity": "sha512-aizTTKbNF2sW+lXWP+uWBoo5Ud9xtUkr70+0pYhItwJF0yhRqLQ91PhW+9afC0daymQjn13MunzDPwGPG0seDg==",
"dev": true,
"dependencies": {
"@eslint/plugin-kit": "^0.4.1",
- "@html-eslint/core": "^0.57.0",
- "@html-eslint/parser": "^0.57.1",
- "@html-eslint/template-parser": "^0.57.0",
- "@html-eslint/template-syntax-parser": "^0.57.0",
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/core": "^0.58.1",
+ "@html-eslint/parser": "^0.58.1",
+ "@html-eslint/template-parser": "^0.58.1",
+ "@html-eslint/template-syntax-parser": "^0.58.1",
+ "@html-eslint/types": "^0.58.1",
"@rviscomi/capo.js": "^2.1.0",
"html-standard": "^0.0.13"
},
@@ -5338,47 +5321,45 @@
}
},
"node_modules/@html-eslint/parser": {
- "version": "0.57.1",
- "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.57.1.tgz",
- "integrity": "sha512-nQ5vw7Os+Snjxq9hLLBak2bv502Obn77BNOWfGK2+GIrShxtGd8w1ehlKW3EB5/RQzqBk6VDK8nPfexlR3M7kg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.58.1.tgz",
+ "integrity": "sha512-a87peH9HcVDrKZZIYdfMlPZ+72nIktAitKcdoHQevuaXWsgvDtClKihJyy5dZS9md6hIbCh62Og5gQRhl85ZMg==",
"dev": true,
"dependencies": {
- "@eslint/css-tree": "^3.6.9",
- "@html-eslint/template-syntax-parser": "^0.57.0",
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/template-syntax-parser": "^0.58.1",
+ "@html-eslint/types": "^0.58.1",
"css-tree": "^3.1.0",
"es-html-parser": "0.3.1"
}
},
"node_modules/@html-eslint/template-parser": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/template-parser/-/template-parser-0.57.0.tgz",
- "integrity": "sha512-tddyBo4dEl4W4Ehxuyd6H4jsSqvsfL5F7Bj9/aFfdQyv36q7BGWM2BRHb6FMmYKAPGZ3VzyEbUlcqIwXpDkY3w==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/template-parser/-/template-parser-0.58.1.tgz",
+ "integrity": "sha512-qo6jTc4Y6vVgwPc2w+EQigH7uCAn+LExxE5oG1URRT98UiJ7dItX0Qk44r/+5XQwSS1TsdvBNLxM2NAktETSWA==",
"dev": true,
"dependencies": {
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/types": "^0.58.1",
"es-html-parser": "0.3.1"
}
},
"node_modules/@html-eslint/template-syntax-parser": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/template-syntax-parser/-/template-syntax-parser-0.57.0.tgz",
- "integrity": "sha512-vHp5y4TR+HhgMDi3rAkgm90LBptSZaQUJudZSj+WdvnSBjLe/fgJC4aVjtLVHTS9ynORrFio8AmH1Bz20kYk4g==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/template-syntax-parser/-/template-syntax-parser-0.58.1.tgz",
+ "integrity": "sha512-P1ZhxIPm9qFWSees2/EZ7Etg1OXziqzRZEuI9goO91fJS6dmdT4JnHLugN06FLL706RwpvenBUlE0iZA9/MXdg==",
"dev": true,
"dependencies": {
- "@html-eslint/types": "^0.57.0"
+ "@html-eslint/types": "^0.58.1"
}
},
"node_modules/@html-eslint/types": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/types/-/types-0.57.0.tgz",
- "integrity": "sha512-wZAHc9FHZRVAcKyx1NdMNGpw1Jo/Anh+9y+bTQ/cKjh5MHJlbs8ogthIG8efBVFIVlIgzxEA8yrX+DPXmuWisA==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/types/-/types-0.58.1.tgz",
+ "integrity": "sha512-1F2A5XXpgfHQ8dm14E/EztyERoVldT91VGMZCJECZpidf5Cbc21vxeHLT6/POTJm0ICJOmyBlocF62i/rkoVEQ==",
"dev": true,
"dependencies": {
"@types/css-tree": "^2.3.11",
"@types/estree": "^1.0.6",
- "es-html-parser": "0.3.1",
- "eslint": "^9.39.1"
+ "es-html-parser": "0.3.1"
}
},
"node_modules/@humanfs/core": {
@@ -9404,18 +9385,11 @@
"version": "3.5.33",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz",
"integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==",
+ "dev": true,
"dependencies": {
"@types/sizzle": "*"
}
},
- "node_modules/@types/jquery.cookie": {
- "version": "1.4.36",
- "resolved": "https://registry.npmjs.org/@types/jquery.cookie/-/jquery.cookie-1.4.36.tgz",
- "integrity": "sha512-qtTnH4jHqFWyYX4deNBklWoaK5myKm0WtKf7LbGQB7DUKt6tdAVWfYQ4Kl8Hw/7eNth864Jjts5rBsHjNveR4Q==",
- "dependencies": {
- "@types/jquery": "*"
- }
- },
"node_modules/@types/jqueryui": {
"version": "1.12.24",
"resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.24.tgz",
@@ -9601,7 +9575,8 @@
"node_modules/@types/sizzle": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
- "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
+ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
+ "dev": true
},
"node_modules/@types/sockjs": {
"version": "0.3.36",
@@ -15765,9 +15740,9 @@
}
},
"node_modules/hono": {
- "version": "4.12.7",
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
- "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw==",
+ "version": "4.12.14",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz",
+ "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w==",
"engines": {
"node": ">=16.9.0"
}
@@ -17030,9 +17005,9 @@
}
},
"node_modules/jasmine-core": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.0.1.tgz",
- "integrity": "sha512-gUtzV5ASR0MLBwDNqri4kBsgKNCcRQd9qOlNw/w/deavD0cl3JmWXXfH8JhKM4LTg6LPTt2IOQ4px3YYfgh2Xg==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.1.0.tgz",
+ "integrity": "sha512-p/tjBw58O6vxKIWMlrU+yys8lqR3+l3UrqwNTT7wpj+dQ7N4etQekFM8joI+cWzPDYqZf54kN+hLC1+s5TvZvg==",
"dev": true
},
"node_modules/jasmine-spec-reporter": {
@@ -17102,12 +17077,6 @@
"resolved": "https://registry.npmjs.org/jquery.caret/-/jquery.caret-0.3.1.tgz",
"integrity": "sha512-nS2mjMZzP4e4tIOgeTLSs+jFhUsUVZUPgkUMpi4DlJq9SgKEg6w2jf7q8joMJp6v+voJHXrH8rzAnbyxWHwAeA=="
},
- "node_modules/jquery.cookie": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jquery.cookie/-/jquery.cookie-1.4.1.tgz",
- "integrity": "sha512-c/hZOOL+8VSw/FkTVH637gS1/6YzMSCROpTZ2qBYwJ7s7sHajU7uBkSSiE5+GXWwrfCCyO+jsYjUQ7Hs2rIxAA==",
- "license": "MIT"
- },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -17967,9 +17936,9 @@
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="
},
"node_modules/lodash-es": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
- "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
+ "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A=="
},
"node_modules/lodash.clonedeep": {
"version": "4.5.0",
@@ -18578,12 +18547,6 @@
"url": "https://opencollective.com/unified"
}
},
- "node_modules/mdn-data": {
- "version": "2.23.0",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.23.0.tgz",
- "integrity": "sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==",
- "dev": true
- },
"node_modules/mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
@@ -20702,9 +20665,9 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"node_modules/path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
+ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
"dev": true
},
"node_modules/picocolors": {
@@ -22187,9 +22150,9 @@
}
},
"node_modules/router/node_modules/path-to-regexp": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
- "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz",
+ "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
@@ -25956,11 +25919,6 @@
"zod": "^3.25.0 || ^4.0.0"
}
},
- "node_modules/zone.js": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz",
- "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w=="
- },
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
@@ -28761,16 +28719,6 @@
"@types/json-schema": "^7.0.15"
}
},
- "@eslint/css-tree": {
- "version": "3.6.9",
- "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-3.6.9.tgz",
- "integrity": "sha512-3D5/OHibNEGk+wKwNwMbz63NMf367EoR4mVNNpxddCHKEb2Nez7z62J2U6YjtErSsZDoY0CsccmoUpdEbkogNA==",
- "dev": true,
- "requires": {
- "mdn-data": "2.23.0",
- "source-map-js": "^1.0.1"
- }
- },
"@eslint/eslintrc": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz",
@@ -29107,9 +29055,9 @@
}
},
"@hono/node-server": {
- "version": "1.19.10",
- "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.10.tgz",
- "integrity": "sha512-hZ7nOssGqRgyV3FVVQdfi+U4q02uB23bpnYpdvNXkYTRRyWx84b7yf1ans+dnJ/7h41sGL3CeQTfO+ZGxuO+Iw=="
+ "version": "1.19.13",
+ "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.13.tgz",
+ "integrity": "sha512-TsQLe4i2gvoTtrHje625ngThGBySOgSK3Xo2XRYOdqGN1teR8+I7vchQC46uLJi8OF62YTYA3AhSpumtkhsaKQ=="
},
"@hotwired/stimulus": {
"version": "3.2.2",
@@ -29131,74 +29079,71 @@
}
},
"@html-eslint/core": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/core/-/core-0.57.0.tgz",
- "integrity": "sha512-X/cKrOmXrxZSdgyKwtbaCuuJ1k/u82MK58Q6p1TzfwPatwIYx+icfBv1Vp1dLui0L0y1fwBW4H+TKhBf7mMKmg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/core/-/core-0.58.1.tgz",
+ "integrity": "sha512-GHYDt2Q3ws9aa0/bmMhkv21ExQJnrjKY/iByjdBVp3lBq49wlzIzvAfcx4Bsp+RMV3oPZhzlnLhPpXLuVYt2mQ==",
"dev": true,
"requires": {
- "@html-eslint/types": "^0.57.0",
- "eslint": "^9.39.1",
+ "@html-eslint/types": "^0.58.1",
"html-standard": "^0.0.13"
}
},
"@html-eslint/eslint-plugin": {
- "version": "0.57.1",
- "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.57.1.tgz",
- "integrity": "sha512-IDfdk3V27eebNpdXD2NLy/lnTSbUuKrro/6YJICBn/9aiXPXagNqWJB38qcSWEoxADbXfSSn17DJWcXvQTkHBg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/eslint-plugin/-/eslint-plugin-0.58.1.tgz",
+ "integrity": "sha512-aizTTKbNF2sW+lXWP+uWBoo5Ud9xtUkr70+0pYhItwJF0yhRqLQ91PhW+9afC0daymQjn13MunzDPwGPG0seDg==",
"dev": true,
"requires": {
"@eslint/plugin-kit": "^0.4.1",
- "@html-eslint/core": "^0.57.0",
- "@html-eslint/parser": "^0.57.1",
- "@html-eslint/template-parser": "^0.57.0",
- "@html-eslint/template-syntax-parser": "^0.57.0",
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/core": "^0.58.1",
+ "@html-eslint/parser": "^0.58.1",
+ "@html-eslint/template-parser": "^0.58.1",
+ "@html-eslint/template-syntax-parser": "^0.58.1",
+ "@html-eslint/types": "^0.58.1",
"@rviscomi/capo.js": "^2.1.0",
"html-standard": "^0.0.13"
}
},
"@html-eslint/parser": {
- "version": "0.57.1",
- "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.57.1.tgz",
- "integrity": "sha512-nQ5vw7Os+Snjxq9hLLBak2bv502Obn77BNOWfGK2+GIrShxtGd8w1ehlKW3EB5/RQzqBk6VDK8nPfexlR3M7kg==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/parser/-/parser-0.58.1.tgz",
+ "integrity": "sha512-a87peH9HcVDrKZZIYdfMlPZ+72nIktAitKcdoHQevuaXWsgvDtClKihJyy5dZS9md6hIbCh62Og5gQRhl85ZMg==",
"dev": true,
"requires": {
- "@eslint/css-tree": "^3.6.9",
- "@html-eslint/template-syntax-parser": "^0.57.0",
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/template-syntax-parser": "^0.58.1",
+ "@html-eslint/types": "^0.58.1",
"css-tree": "^3.1.0",
"es-html-parser": "0.3.1"
}
},
"@html-eslint/template-parser": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/template-parser/-/template-parser-0.57.0.tgz",
- "integrity": "sha512-tddyBo4dEl4W4Ehxuyd6H4jsSqvsfL5F7Bj9/aFfdQyv36q7BGWM2BRHb6FMmYKAPGZ3VzyEbUlcqIwXpDkY3w==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/template-parser/-/template-parser-0.58.1.tgz",
+ "integrity": "sha512-qo6jTc4Y6vVgwPc2w+EQigH7uCAn+LExxE5oG1URRT98UiJ7dItX0Qk44r/+5XQwSS1TsdvBNLxM2NAktETSWA==",
"dev": true,
"requires": {
- "@html-eslint/types": "^0.57.0",
+ "@html-eslint/types": "^0.58.1",
"es-html-parser": "0.3.1"
}
},
"@html-eslint/template-syntax-parser": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/template-syntax-parser/-/template-syntax-parser-0.57.0.tgz",
- "integrity": "sha512-vHp5y4TR+HhgMDi3rAkgm90LBptSZaQUJudZSj+WdvnSBjLe/fgJC4aVjtLVHTS9ynORrFio8AmH1Bz20kYk4g==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/template-syntax-parser/-/template-syntax-parser-0.58.1.tgz",
+ "integrity": "sha512-P1ZhxIPm9qFWSees2/EZ7Etg1OXziqzRZEuI9goO91fJS6dmdT4JnHLugN06FLL706RwpvenBUlE0iZA9/MXdg==",
"dev": true,
"requires": {
- "@html-eslint/types": "^0.57.0"
+ "@html-eslint/types": "^0.58.1"
}
},
"@html-eslint/types": {
- "version": "0.57.0",
- "resolved": "https://registry.npmjs.org/@html-eslint/types/-/types-0.57.0.tgz",
- "integrity": "sha512-wZAHc9FHZRVAcKyx1NdMNGpw1Jo/Anh+9y+bTQ/cKjh5MHJlbs8ogthIG8efBVFIVlIgzxEA8yrX+DPXmuWisA==",
+ "version": "0.58.1",
+ "resolved": "https://registry.npmjs.org/@html-eslint/types/-/types-0.58.1.tgz",
+ "integrity": "sha512-1F2A5XXpgfHQ8dm14E/EztyERoVldT91VGMZCJECZpidf5Cbc21vxeHLT6/POTJm0ICJOmyBlocF62i/rkoVEQ==",
"dev": true,
"requires": {
"@types/css-tree": "^2.3.11",
"@types/estree": "^1.0.6",
- "es-html-parser": "0.3.1",
- "eslint": "^9.39.1"
+ "es-html-parser": "0.3.1"
}
},
"@humanfs/core": {
@@ -31583,18 +31528,11 @@
"version": "3.5.33",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.33.tgz",
"integrity": "sha512-SeyVJXlCZpEki5F0ghuYe+L+PprQta6nRZqhONt9F13dWBtR/ftoaIbdRQ7cis7womE+X2LKhsDdDtkkDhJS6g==",
+ "dev": true,
"requires": {
"@types/sizzle": "*"
}
},
- "@types/jquery.cookie": {
- "version": "1.4.36",
- "resolved": "https://registry.npmjs.org/@types/jquery.cookie/-/jquery.cookie-1.4.36.tgz",
- "integrity": "sha512-qtTnH4jHqFWyYX4deNBklWoaK5myKm0WtKf7LbGQB7DUKt6tdAVWfYQ4Kl8Hw/7eNth864Jjts5rBsHjNveR4Q==",
- "requires": {
- "@types/jquery": "*"
- }
- },
"@types/jqueryui": {
"version": "1.12.24",
"resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.24.tgz",
@@ -31774,7 +31712,8 @@
"@types/sizzle": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
- "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
+ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
+ "dev": true
},
"@types/sockjs": {
"version": "0.3.36",
@@ -36029,9 +35968,9 @@
}
},
"hono": {
- "version": "4.12.7",
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
- "integrity": "sha512-jq9l1DM0zVIvsm3lv9Nw9nlJnMNPOcAtsbsgiUhWcFzPE99Gvo6yRTlszSLLYacMeQ6quHD6hMfId8crVHvexw=="
+ "version": "4.12.14",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.14.tgz",
+ "integrity": "sha512-am5zfg3yu6sqn5yjKBNqhnTX7Cv+m00ox+7jbaKkrLMRJ4rAdldd1xPd/JzbBWspqaQv6RSTrgFN95EsfhC+7w=="
},
"hosted-git-info": {
"version": "9.0.2",
@@ -36873,9 +36812,9 @@
}
},
"jasmine-core": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.0.1.tgz",
- "integrity": "sha512-gUtzV5ASR0MLBwDNqri4kBsgKNCcRQd9qOlNw/w/deavD0cl3JmWXXfH8JhKM4LTg6LPTt2IOQ4px3YYfgh2Xg==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-6.1.0.tgz",
+ "integrity": "sha512-p/tjBw58O6vxKIWMlrU+yys8lqR3+l3UrqwNTT7wpj+dQ7N4etQekFM8joI+cWzPDYqZf54kN+hLC1+s5TvZvg==",
"dev": true
},
"jasmine-spec-reporter": {
@@ -36930,11 +36869,6 @@
"resolved": "https://registry.npmjs.org/jquery.caret/-/jquery.caret-0.3.1.tgz",
"integrity": "sha512-nS2mjMZzP4e4tIOgeTLSs+jFhUsUVZUPgkUMpi4DlJq9SgKEg6w2jf7q8joMJp6v+voJHXrH8rzAnbyxWHwAeA=="
},
- "jquery.cookie": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jquery.cookie/-/jquery.cookie-1.4.1.tgz",
- "integrity": "sha512-c/hZOOL+8VSw/FkTVH637gS1/6YzMSCROpTZ2qBYwJ7s7sHajU7uBkSSiE5+GXWwrfCCyO+jsYjUQ7Hs2rIxAA=="
- },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -37560,9 +37494,9 @@
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="
},
"lodash-es": {
- "version": "4.17.23",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
- "integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg=="
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.18.1.tgz",
+ "integrity": "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A=="
},
"lodash.clonedeep": {
"version": "4.5.0",
@@ -37992,12 +37926,6 @@
"@types/mdast": "^4.0.0"
}
},
- "mdn-data": {
- "version": "2.23.0",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.23.0.tgz",
- "integrity": "sha512-786vq1+4079JSeu2XdcDjrhi/Ry7BWtjDl9WtGPWLiIHb2T66GvIVflZTBoSNZ5JqTtJGYEVMuFA/lbQlMOyDQ==",
- "dev": true
- },
"mdurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
@@ -39390,9 +39318,9 @@
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-to-regexp": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
- "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz",
+ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==",
"dev": true
},
"picocolors": {
@@ -40390,9 +40318,9 @@
}
},
"path-to-regexp": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
- "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA=="
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz",
+ "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg=="
}
}
},
@@ -42844,11 +42772,6 @@
"integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
"dev": true
},
- "zone.js": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz",
- "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w=="
- },
"zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 041f430a450..23d47db5df8 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,8 +14,8 @@
"@angular-eslint/template-parser": "20.7.0",
"@angular/language-service": "21.1.6",
"@eslint/js": "^9.39.2",
- "@html-eslint/eslint-plugin": "^0.57.1",
- "@html-eslint/parser": "^0.57.1",
+ "@html-eslint/eslint-plugin": "^0.58.1",
+ "@html-eslint/parser": "^0.58.1",
"@jsdevtools/coverage-istanbul-loader": "3.0.5",
"@stylistic/eslint-plugin": "^5.7.1",
"@types/codemirror": "5.60.5",
@@ -48,7 +48,7 @@
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"globals": "^17.3.0",
- "jasmine-core": "~6.0.1",
+ "jasmine-core": "~6.1.0",
"jasmine-spec-reporter": "~7.0.0",
"karma": "~6.4.4",
"karma-chrome-launcher": "~3.2.0",
@@ -122,7 +122,6 @@
"@stimulus-components/auto-submit": "^6.0.0",
"@stimulus-components/reveal": "^5.0.0",
"@tiptap/extensions": "^3.20.0",
- "@types/jquery.cookie": "^1.4.36",
"@uirouter/angular": "^17.0.0",
"@uirouter/core": "^6.1.0",
"@uirouter/rx": "^1.0.0",
@@ -148,7 +147,6 @@
"idiomorph": "^0.7.4",
"jquery": "^3.7.1",
"jquery.caret": "^0.3.1",
- "jquery.cookie": "^1.4.1",
"json5": "^2.2.2",
"lit-html": "^3.3.2",
"lodash": "^4.17.23",
@@ -181,8 +179,7 @@
"turbo_power": "^0.7.1",
"typedjson": "^1.5.1",
"urijs": "^1.19.11",
- "uuid": "^13.0.0",
- "zone.js": "~0.15.1"
+ "uuid": "^13.0.0"
},
"optionalDependencies": {
"fsevents": "*"
diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index d3edb6674eb..a002c9df85e 100644
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -39,6 +39,7 @@ import { OpSharedModule } from 'core-app/shared/shared.module';
import { OpSpotModule } from 'core-app/spot/spot.module';
import { OpDragScrollDirective } from 'core-app/shared/directives/op-drag-scroll/op-drag-scroll.directive';
import { OpenprojectWorkPackagesModule } from 'core-app/features/work-packages/openproject-work-packages.module';
+import { OpenprojectBoardsModule } from 'core-app/features/boards/openproject-boards.module';
import { OpenprojectAttachmentsModule } from 'core-app/shared/components/attachments/openproject-attachments.module';
import { OpenprojectEditorModule } from 'core-app/shared/components/editor/openproject-editor.module';
import { OpenprojectGridsModule } from 'core-app/shared/components/grids/openproject-grids.module';
@@ -135,12 +136,6 @@ import {
} from 'core-app/shared/components/autocompleter/draggable-autocomplete/draggable-autocomplete.component';
import { OpExclusionInfoComponent } from 'core-app/shared/components/fields/display/info/op-exclusion-info.component';
import { OpenProjectJobStatusModule } from 'core-app/features/job-status/openproject-job-status.module';
-import {
- NotificationsSettingsPageComponent,
-} from 'core-app/features/user-preferences/notifications-settings/page/notifications-settings-page.component';
-import {
- ReminderSettingsPageComponent,
-} from 'core-app/features/user-preferences/reminder-settings/page/reminder-settings-page.component';
import { OpenProjectMyAccountModule } from 'core-app/features/user-preferences/user-preferences.module';
import { OpAttachmentsComponent } from 'core-app/shared/components/attachments/attachments.component';
import {
@@ -149,6 +144,9 @@ import {
import {
WorkPackageSplitViewEntryComponent,
} from 'core-app/features/work-packages/routing/wp-split-view/wp-split-view-entry.component';
+import {
+ BoardEntryComponent,
+} from 'core-app/features/boards/board/board-partitioned-page/board-entry.component';
import {
StorageLoginButtonComponent,
} from 'core-app/shared/components/storages/storage-login-button/storage-login-button.component';
@@ -295,6 +293,9 @@ export function runBootstrap(appRef:ApplicationRef) {
OpenprojectWorkPackagesModule,
OpenprojectWorkPackageRoutesModule,
+ // Boards
+ OpenprojectBoardsModule,
+
// Work packages in graph representation
OpenprojectWorkPackageGraphsModule,
// Calendar module
@@ -389,11 +390,9 @@ export class OpenProjectModule implements DoBootstrap {
registerCustomElement('opce-storage-login-button', StorageLoginButtonComponent, { injector });
registerCustomElement('opce-custom-modal-overlay', OpCustomModalOverlayComponent, { injector });
- // TODO: These elements are now registered custom elements, but are actually single-use components. They should be removed when we move these pages to Rails.
- registerCustomElement('opce-notification-settings', NotificationsSettingsPageComponent, { injector });
- registerCustomElement('opce-reminder-settings', ReminderSettingsPageComponent, { injector });
registerCustomElement('opce-notification-center', InAppNotificationCenterComponent, { injector });
registerCustomElement('opce-wp-split-view', WorkPackageSplitViewEntryComponent, { injector });
+ registerCustomElement('opce-board-view', BoardEntryComponent, { injector });
registerCustomElement('opce-wp-full-view', WorkPackageFullViewEntryComponent, { injector });
registerCustomElement('opce-wp-full-create', WorkPackageFullCreateEntryComponent, { injector });
registerCustomElement('opce-wp-full-copy', WorkPackageFullCopyEntryComponent, { injector });
diff --git a/frontend/src/app/core/apiv3/api-v3.service.spec.ts b/frontend/src/app/core/apiv3/api-v3.service.spec.ts
index a2391ce6cb3..034cfada593 100644
--- a/frontend/src/app/core/apiv3/api-v3.service.spec.ts
+++ b/frontend/src/app/core/apiv3/api-v3.service.spec.ts
@@ -28,7 +28,6 @@
import {
TestBed,
- waitForAsync,
} from '@angular/core/testing';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
@@ -37,19 +36,16 @@ import { States } from 'core-app/core/states/states.service';
describe('APIv3Service', () => {
let service:ApiV3Service;
- beforeEach(waitForAsync(() => {
- void TestBed.configureTestingModule({
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
providers: [
States,
PathHelperService,
ApiV3Service,
],
- })
- .compileComponents()
- .then(() => {
- service = TestBed.inject(ApiV3Service);
- });
- }));
+ }).compileComponents();
+ service = TestBed.inject(ApiV3Service);
+ });
function encodeParams(object:any) {
return new URLSearchParams(object).toString();
diff --git a/frontend/src/app/core/config/configuration.service.ts b/frontend/src/app/core/config/configuration.service.ts
index 56cc854c60b..ee186227657 100644
--- a/frontend/src/app/core/config/configuration.service.ts
+++ b/frontend/src/app/core/config/configuration.service.ts
@@ -147,6 +147,10 @@ export class ConfigurationService {
return moment.localeData(I18n.locale).firstDayOfWeek();
}
+ public get wikisAvailable():boolean {
+ return this.systemPreference('wikisAvailable');
+ }
+
public get hostName():string {
return this.systemPreference('hostName');
}
diff --git a/frontend/src/app/core/global_search/input/global-search-input.component.ts b/frontend/src/app/core/global_search/input/global-search-input.component.ts
index 5a48ecf60b7..35158e66d93 100644
--- a/frontend/src/app/core/global_search/input/global-search-input.component.ts
+++ b/frontend/src/app/core/global_search/input/global-search-input.component.ts
@@ -7,7 +7,6 @@ import {
ElementRef,
HostListener,
Input,
- NgZone,
OnDestroy,
ViewChild,
ViewEncapsulation,
@@ -141,7 +140,6 @@ export class GlobalSearchInputComponent implements AfterViewInit, OnDestroy {
readonly deviceService:DeviceService,
readonly cdRef:ChangeDetectorRef,
readonly halNotification:HalResourceNotificationService,
- readonly ngZone:NgZone,
readonly recentItemsService:RecentItemsService,
) {
populateInputsFromDataset(this);
diff --git a/frontend/src/app/core/main-menu/submenu.service.ts b/frontend/src/app/core/main-menu/submenu.service.ts
index c0374eab1d9..dff74195f52 100644
--- a/frontend/src/app/core/main-menu/submenu.service.ts
+++ b/frontend/src/app/core/main-menu/submenu.service.ts
@@ -6,9 +6,9 @@ import { StateService } from '@uirouter/core';
export class SubmenuService {
constructor(protected $state:StateService) {}
- reloadSubmenu(selectedQueryId:string|null):void {
+ reloadSubmenu(selectedQueryId:string|null, sidemenuId?:string):void {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
- const menuIdentifier:string|undefined = this.$state.current.data.sideMenuOptions?.sidemenuId;
+ const menuIdentifier:string|undefined = sidemenuId ?? this.$state.current.data?.sideMenuOptions?.sidemenuId;
if (menuIdentifier) {
const menu = document.getElementById(menuIdentifier) as FrameElement;
@@ -18,7 +18,7 @@ export class SubmenuService {
if (currentSrc && menu) {
const frameUrl = new URL(currentSrc, window.location.origin);
- const defaultQuery = sideMenuOptions.defaultQuery;
+ const defaultQuery = sideMenuOptions?.defaultQuery;
if (selectedQueryId) {
// If there is a default query passed in the route definition, it means that id passed as argument and not as parameter,
diff --git a/frontend/src/app/core/path-helper/path-helper.service.ts b/frontend/src/app/core/path-helper/path-helper.service.ts
index 5c30f35a952..5a5f305c589 100644
--- a/frontend/src/app/core/path-helper/path-helper.service.ts
+++ b/frontend/src/app/core/path-helper/path-helper.service.ts
@@ -247,6 +247,10 @@ export class PathHelperService {
return `${this.boardsPath(projectIdentifier)}/new`;
}
+ public boardDetailsPath(projectIdentifier:string|null, boardId:string|number, workPackageId:string|number) {
+ return `${this.boardsPath(projectIdentifier)}/${boardId}/details/${workPackageId}`;
+ }
+
public projectDashboardsPath(projectIdentifier:string) {
return `${this.projectPath(projectIdentifier)}/dashboards`;
}
@@ -407,6 +411,12 @@ export class PathHelperService {
return `${this.workPackagesPath(null)}/bulk`;
}
+ public workPackagesBulkDeleteDialogPath(ids:string[], backUrl?:string) {
+ const params = ids.map((id) => `ids[]=${encodeURIComponent(id)}`).join('&');
+ const backParam = backUrl ? `&back_url=${encodeURIComponent(backUrl)}` : '';
+ return `${this.workPackagesPath(null)}/bulk/delete_dialog?${params}${backParam}`;
+ }
+
public workPackagesBulkReassignmentPath() {
return `${this.workPackagesPath(null)}/bulk/reassign`;
}
diff --git a/frontend/src/app/core/routing/base/application-base.component.ts b/frontend/src/app/core/routing/base/application-base.component.ts
index 97ae414e336..fc4d7879a0a 100644
--- a/frontend/src/app/core/routing/base/application-base.component.ts
+++ b/frontend/src/app/core/routing/base/application-base.component.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
export const appBaseSelector = 'openproject-base';
@@ -38,6 +38,10 @@ export const appBaseSelector = 'openproject-base';
`,
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class ApplicationBaseComponent {
}
diff --git a/frontend/src/app/core/routing/openproject.routes.ts b/frontend/src/app/core/routing/openproject.routes.ts
index 25ff234b031..fb01324276b 100644
--- a/frontend/src/app/core/routing/openproject.routes.ts
+++ b/frontend/src/app/core/routing/openproject.routes.ts
@@ -29,7 +29,7 @@
import { StateDeclaration, StateService, Transition, TransitionService, UIRouter } from '@uirouter/core';
import { IToast, ToastService } from 'core-app/shared/components/toaster/toast.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
-import { Injector } from '@angular/core';
+import { ApplicationRef, Injector } from '@angular/core';
import { FirstRouteService } from 'core-app/core/routing/first-route-service';
import { Ng2StateDeclaration, StatesModule } from '@uirouter/angular';
import { appBaseSelector, ApplicationBaseComponent } from 'core-app/core/routing/base/application-base.component';
@@ -68,12 +68,6 @@ export const OPENPROJECT_ROUTES:Ng2StateDeclaration[] = [
'!$default': { component: ApplicationBaseComponent },
},
},
- {
- name: 'boards.**',
- parent: 'optional_project',
- url: '/boards',
- loadChildren: () => import('../../features/boards/openproject-boards.module').then((m) => m.OpenprojectBoardsModule),
- },
{
name: 'bim.**',
parent: 'optional_project',
@@ -287,4 +281,12 @@ export function initializeUiRouterListeners(injector:Injector) {
return true;
});
+
+ // In zoneless mode, UIRouter transitions complete in microtasks but
+ // Angular's change detection doesn't run automatically afterwards.
+ // Force a CD cycle after every successful transition so that the new
+ // view is rendered and Stimulus controllers properly disconnect/connect.
+ $transitions.onSuccess({}, () => {
+ injector.get(ApplicationRef).tick();
+ });
}
diff --git a/frontend/src/app/features/bim/bcf/api/bcf-api.service.spec.ts b/frontend/src/app/features/bim/bcf/api/bcf-api.service.spec.ts
index 09f24baa979..2de91e3dff7 100644
--- a/frontend/src/app/features/bim/bcf/api/bcf-api.service.spec.ts
+++ b/frontend/src/app/features/bim/bcf/api/bcf-api.service.spec.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { TestBed, waitForAsync } from '@angular/core/testing';
+import { TestBed } from '@angular/core/testing';
import { BcfApiService } from 'core-app/features/bim/bcf/api/bcf-api.service';
import { BcfResourceCollectionPath, BcfResourcePath } from 'core-app/features/bim/bcf/api/bcf-path-resources';
import { BcfTopicPaths } from 'core-app/features/bim/bcf/api/topics/bcf-topic.paths';
@@ -34,18 +34,14 @@ import { BcfTopicPaths } from 'core-app/features/bim/bcf/api/topics/bcf-topic.pa
describe('BcfApiService', () => {
let service:BcfApiService;
- beforeEach(waitForAsync(() => {
- // noinspection JSIgnoredPromiseFromCall
- TestBed.configureTestingModule({
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
providers: [
BcfApiService,
],
- })
- .compileComponents()
- .then(() => {
- service = TestBed.inject(BcfApiService);
- });
- }));
+ }).compileComponents();
+ service = TestBed.inject(BcfApiService);
+ });
describe('building the path', () => {
it('can build projects', () => {
diff --git a/frontend/src/app/features/bim/bcf/fields/display/bcf-thumbnail-field.module.ts b/frontend/src/app/features/bim/bcf/fields/display/bcf-thumbnail-field.module.ts
index c0dcd569e31..98a531bca47 100644
--- a/frontend/src/app/features/bim/bcf/fields/display/bcf-thumbnail-field.module.ts
+++ b/frontend/src/app/features/bim/bcf/fields/display/bcf-thumbnail-field.module.ts
@@ -34,13 +34,14 @@ import { HalLink } from 'core-app/features/hal/hal-link/hal-link';
export class BcfThumbnailDisplayField extends DisplayField {
@InjectField() bcfPathHelper:BcfPathHelperService;
- public render(element:HTMLElement, displayText:string):void {
- const viewpoints = this.resource.bcfViewpoints;
+ public render(element:HTMLElement, _displayText:string):void {
+ const viewpoints = this.resource.bcfViewpoints as HalLink[];
if (viewpoints && viewpoints.length > 0) {
const viewpoint = viewpoints[0];
- element.innerHTML = `
-
- `;
+ const img = document.createElement('img');
+ img.src = this.bcfPathHelper.snapshotPath(viewpoint);
+ img.classList.add('thumbnail');
+ element.appendChild(img);
} else {
element.innerHTML = '';
}
diff --git a/frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.ts b/frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.ts
index d41eef463e6..6593200dd8f 100644
--- a/frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.ts
+++ b/frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.ts
@@ -27,7 +27,7 @@
//++
import {
- ChangeDetectionStrategy, Component, Input, NgZone, OnInit,
+ ChangeDetectionStrategy, Component, Input, OnInit,
} from '@angular/core';
import { UIRouterGlobals } from '@uirouter/core';
import { States } from 'core-app/core/states/states.service';
@@ -81,8 +81,6 @@ export class BcfListComponent extends WorkPackageListViewComponent implements Un
@InjectField() bcfApi:BcfApiService;
- @InjectField() zone:NgZone;
-
public wpTableConfiguration = {
dragAndDropEnabled: false,
};
@@ -105,9 +103,7 @@ export class BcfListComponent extends WorkPackageListViewComponent implements Un
if (!this.showViewPointInFlight) {
this.showViewPointInFlight = true;
- this.zone.runOutsideAngular(() => {
- setTimeout(() => { this.showViewPointInFlight = false; }, 500);
- });
+ setTimeout(() => { this.showViewPointInFlight = false; }, 500);
const wp = this.states.workPackages.get(workPackageId).value;
diff --git a/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component.ts b/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component.ts
index 4e33473461a..1bbb9f85189 100644
--- a/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component.ts
+++ b/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-export-button.component.ts
@@ -27,7 +27,7 @@
//++
import {
- Component, Injector, OnDestroy, OnInit,
+ ChangeDetectionStrategy, ChangeDetectorRef, Component, Injector, OnDestroy, OnInit,
} from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
@@ -53,6 +53,10 @@ import { JobStatusModalService } from 'core-app/features/job-status/job-status-m
`,
selector: 'bcf-export-button',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class BcfExportButtonComponent extends UntilDestroyedMixin implements OnInit, OnDestroy {
public text = {
@@ -73,7 +77,8 @@ export class BcfExportButtonComponent extends UntilDestroyedMixin implements OnI
readonly httpClient:HttpClient,
readonly injector:Injector,
readonly toastService:ToastService,
- readonly state:StateService) {
+ readonly state:StateService,
+ readonly cdRef:ChangeDetectorRef) {
super();
}
@@ -92,6 +97,7 @@ export class BcfExportButtonComponent extends UntilDestroyedMixin implements OnI
projectIdentifier!,
JSON.stringify(filters),
);
+ this.cdRef.markForCheck();
});
}
diff --git a/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component.ts b/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component.ts
index 9081664edeb..b320357f6ba 100644
--- a/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component.ts
+++ b/frontend/src/app/features/bim/ifc_models/toolbar/import-export-bcf/bcf-import-button.component.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component } from '@angular/core';
+import { ChangeDetectionStrategy, Component } from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
import { BcfPathHelperService } from 'core-app/features/bim/bcf/helper/bcf-path-helper.service';
@@ -42,6 +42,10 @@ import { BcfPathHelperService } from 'core-app/features/bim/bcf/helper/bcf-path-
`,
selector: 'bcf-import-button',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class BcfImportButtonComponent {
public text = {
diff --git a/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.component.ts b/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.component.ts
index 585510250fc..5c477b04f12 100644
--- a/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.component.ts
+++ b/frontend/src/app/features/boards/board/add-list-modal/add-list-modal.component.ts
@@ -27,14 +27,13 @@
//++
import {
- ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild,
+ ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnInit, ViewChild,
} from '@angular/core';
import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types';
import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { Board } from 'core-app/features/boards/board/board';
-import { StateService } from '@uirouter/core';
import { BoardService } from 'core-app/features/boards/board/board.service';
import { BoardActionsRegistryService } from 'core-app/features/boards/board/board-actions/board-actions-registry.service';
import { BoardActionService } from 'core-app/features/boards/board/board-actions/board-action.service';
@@ -42,6 +41,7 @@ import { HalResourceNotificationService } from 'core-app/features/hal/services/h
import { tap } from 'rxjs/operators';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
+import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import {
firstValueFrom,
Observable,
@@ -52,6 +52,10 @@ import { HalResource } from 'core-app/features/hal/resources/hal-resource';
@Component({
templateUrl: './add-list-modal.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class AddListModalComponent extends OpModalComponent implements OnInit {
@ViewChild(OpAutocompleterComponent, { static: true }) public ngSelectComponent:OpAutocompleterComponent;
@@ -113,11 +117,11 @@ export class AddListModalComponent extends OpModalComponent implements OnInit {
readonly cdRef:ChangeDetectorRef,
readonly boardActions:BoardActionsRegistryService,
readonly halNotification:HalResourceNotificationService,
- readonly state:StateService,
readonly boardService:BoardService,
readonly I18n:I18nService,
readonly apiV3Service:ApiV3Service,
- readonly currentProject:CurrentProjectService) {
+ readonly currentProject:CurrentProjectService,
+ readonly pathHelper:PathHelperService) {
super(locals, cdRef, elementRef);
}
@@ -141,9 +145,12 @@ export class AddListModalComponent extends OpModalComponent implements OnInit {
.then((board) => {
this.inFlight = false;
this.closeMe();
- void this.state.go('boards.partitioned.show', { board_id: board.id, isNew: true });
+ void Turbo.visit(`${this.pathHelper.boardsPath(this.currentProject.identifier)}/${board.id}`);
})
- .catch(() => (this.inFlight = false));
+ .catch(() => {
+ this.inFlight = false;
+ this.cdRef.detectChanges();
+ });
}
onNewActionCreated() {
@@ -190,6 +197,7 @@ export class AddListModalComponent extends OpModalComponent implements OnInit {
.warningTextWhenNoOptionsAvailable(hasMember)
.then((text) => {
this.warningText = text;
+ this.cdRef.detectChanges();
})
.catch(() => {});
this.showWarning = this.ngSelectComponent.ngSelectInstance.searchTerm !== undefined && (values.length === 0);
diff --git a/frontend/src/app/features/boards/board/board-actions/assignee/assignee-board-header.component.ts b/frontend/src/app/features/boards/board/board-actions/assignee/assignee-board-header.component.ts
index b68dc2f87d1..7321bcf61b4 100644
--- a/frontend/src/app/features/boards/board/board-actions/assignee/assignee-board-header.component.ts
+++ b/frontend/src/app/features/boards/board/board-actions/assignee/assignee-board-header.component.ts
@@ -25,7 +25,7 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { UserResource } from 'core-app/features/hal/resources/user-resource';
@@ -35,6 +35,10 @@ import { UserResource } from 'core-app/features/hal/resources/user-resource';
styleUrls: ['./assignee-board-header.sass'],
host: { class: 'title-container -small' },
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class AssigneeBoardHeaderComponent {
@Input('resource') public user:UserResource;
diff --git a/frontend/src/app/features/boards/board/board-actions/status/status-board-header.component.ts b/frontend/src/app/features/boards/board/board-actions/status/status-board-header.component.ts
index ae559c84d08..cfdab8c28fc 100644
--- a/frontend/src/app/features/boards/board/board-actions/status/status-board-header.component.ts
+++ b/frontend/src/app/features/boards/board/board-actions/status/status-board-header.component.ts
@@ -25,7 +25,7 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { StatusResource } from 'core-app/features/hal/resources/status-resource';
@@ -34,6 +34,10 @@ import { StatusResource } from 'core-app/features/hal/resources/status-resource'
styleUrls: ['./status-board-header.sass'],
host: { class: 'title-container -small' },
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class StatusBoardHeaderComponent {
@Input('resource') public status:StatusResource;
diff --git a/frontend/src/app/features/boards/board/board-actions/subproject/subproject-board-header.component.ts b/frontend/src/app/features/boards/board/board-actions/subproject/subproject-board-header.component.ts
index 50b87614533..27fe9a979fc 100644
--- a/frontend/src/app/features/boards/board/board-actions/subproject/subproject-board-header.component.ts
+++ b/frontend/src/app/features/boards/board/board-actions/subproject/subproject-board-header.component.ts
@@ -25,7 +25,7 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { HalResource } from 'core-app/features/hal/resources/hal-resource';
@@ -36,6 +36,10 @@ import idFromLink from 'core-app/features/hal/helpers/id-from-link';
styleUrls: ['./subproject-board-header.sass'],
host: { class: 'title-container -small' },
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class SubprojectBoardHeaderComponent {
@Input() public resource:HalResource;
diff --git a/frontend/src/app/features/boards/board/board-actions/subtasks/subtasks-board-header.component.ts b/frontend/src/app/features/boards/board/board-actions/subtasks/subtasks-board-header.component.ts
index a1b793bad2c..04040a17623 100644
--- a/frontend/src/app/features/boards/board/board-actions/subtasks/subtasks-board-header.component.ts
+++ b/frontend/src/app/features/boards/board/board-actions/subtasks/subtasks-board-header.component.ts
@@ -25,7 +25,7 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, Input, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource';
@@ -37,6 +37,10 @@ import idFromLink from 'core-app/features/hal/helpers/id-from-link';
styleUrls: ['./subtasks-board-header.sass'],
host: { class: 'title-container -small' },
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class SubtasksBoardHeaderComponent implements OnInit {
@Input() public resource:WorkPackageResource;
diff --git a/frontend/src/app/features/boards/board/board-actions/version/version-action.service.ts b/frontend/src/app/features/boards/board/board-actions/version/version-action.service.ts
index 90992070755..c090f3bb58d 100644
--- a/frontend/src/app/features/boards/board/board-actions/version/version-action.service.ts
+++ b/frontend/src/app/features/boards/board/board-actions/version/version-action.service.ts
@@ -4,7 +4,6 @@ import { QueryResource } from 'core-app/features/hal/resources/query-resource';
import { VersionResource } from 'core-app/features/hal/resources/version-resource';
import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op-context-menu.types';
import { isClickedWithModifier } from 'core-app/shared/helpers/link-handling/link-handling';
-import { StateService } from '@uirouter/core';
import { HalResourceNotificationService } from 'core-app/features/hal/services/hal-resource-notification.service';
import { VersionBoardHeaderComponent } from 'core-app/features/boards/board/board-actions/version/version-board-header.component';
import { FormResource } from 'core-app/features/hal/resources/form-resource';
@@ -22,8 +21,6 @@ import { map } from 'rxjs/operators';
@Injectable()
export class BoardVersionActionService extends CachedBoardActionService {
- @InjectField() state:StateService;
-
@InjectField() halNotification:HalResourceNotificationService;
filterName = 'version';
@@ -119,8 +116,8 @@ export class BoardVersionActionService extends CachedBoardActionService {
.id(version)
.patch({ status: newStatus })
.subscribe(
- (version) => {
- this.state.go('.', {}, { reload: true });
+ () => {
+ Turbo.visit(window.location.href, { action: 'replace' });
},
(error) => this.halNotification.handleRawError(error),
);
diff --git a/frontend/src/app/features/boards/board/board-actions/version/version-board-header.component.ts b/frontend/src/app/features/boards/board/board-actions/version/version-board-header.component.ts
index fb29c183ddf..d57d88bc732 100644
--- a/frontend/src/app/features/boards/board/board-actions/version/version-board-header.component.ts
+++ b/frontend/src/app/features/boards/board/board-actions/version/version-board-header.component.ts
@@ -25,7 +25,7 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, Input } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { VersionResource } from 'core-app/features/hal/resources/version-resource';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
@@ -35,6 +35,10 @@ import { PathHelperService } from 'core-app/core/path-helper/path-helper.service
styleUrls: ['./version-board-header.sass'],
host: { class: 'title-container -small' },
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class VersionBoardHeaderComponent {
@Input('resource') public version:VersionResource;
diff --git a/frontend/src/app/features/boards/board/board-filter/board-filter.component.ts b/frontend/src/app/features/boards/board/board-filter/board-filter.component.ts
index 6c960942039..0a3ec34be8f 100644
--- a/frontend/src/app/features/boards/board/board-filter/board-filter.component.ts
+++ b/frontend/src/app/features/boards/board/board-filter/board-filter.component.ts
@@ -1,4 +1,4 @@
-import { AfterViewInit, Component, Input } from '@angular/core';
+import { AfterViewInit, ChangeDetectionStrategy, Component, Input } from '@angular/core';
import { Board } from 'core-app/features/boards/board/board';
import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
import { WorkPackageStatesInitializationService } from 'core-app/features/work-packages/components/wp-list/wp-states-initialization.service';
@@ -7,7 +7,6 @@ import { HalResourceService } from 'core-app/features/hal/services/hal-resource.
import { WorkPackageViewFiltersService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service';
import { QueryFilterInstanceResource } from 'core-app/features/hal/resources/query-filter-instance-resource';
import { UrlParamsHelperService } from 'core-app/features/work-packages/components/wp-query/url-params-helper';
-import { StateService } from '@uirouter/core';
import { debounceTime, skip, take } from 'rxjs/operators';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
import { Observable } from 'rxjs';
@@ -18,6 +17,10 @@ import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
selector: 'board-filter',
templateUrl: './board-filter.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class BoardFilterComponent extends UntilDestroyedMixin implements AfterViewInit {
/** Current active */
@@ -32,8 +35,7 @@ export class BoardFilterComponent extends UntilDestroyedMixin implements AfterVi
private readonly wpStatesInitialization:WorkPackageStatesInitializationService,
private readonly wpTableFilters:WorkPackageViewFiltersService,
private readonly urlParamsHelper:UrlParamsHelperService,
- private readonly boardFilters:BoardFiltersService,
- private readonly $state:StateService) {
+ private readonly boardFilters:BoardFiltersService) {
super();
}
@@ -71,9 +73,15 @@ export class BoardFilterComponent extends UntilDestroyedMixin implements AfterVi
const filterHash = this.urlParamsHelper.buildV3GetFilters(filters);
const query_props = JSON.stringify(filterHash);
- this.boardFilters.filters.putValue(filterHash);
+ const url = new URL(window.location.href);
+ if (query_props) {
+ url.searchParams.set('query_props', query_props);
+ } else {
+ url.searchParams.delete('query_props');
+ }
+ window.history.pushState({}, '', url);
- this.$state.go('.', { query_props }, { custom: { notify: false } });
+ this.boardFilters.filters.putValue(filterHash);
});
}
diff --git a/frontend/src/app/features/boards/board/board-list/board-list-menu.component.ts b/frontend/src/app/features/boards/board/board-list/board-list-menu.component.ts
index b870e4edf75..6c1ee33907b 100644
--- a/frontend/src/app/features/boards/board/board-list/board-list-menu.component.ts
+++ b/frontend/src/app/features/boards/board/board-list/board-list-menu.component.ts
@@ -27,7 +27,7 @@
//++
import {
- Component, EventEmitter, Input, Output,
+ ChangeDetectionStrategy, Component, EventEmitter, Input, Output,
} from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { AuthorisationService } from 'core-app/core/model-auth/model-auth.service';
@@ -43,6 +43,10 @@ import { BoardActionService } from 'core-app/features/boards/board/board-actions
selector: 'board-list-menu',
templateUrl: './board-list-menu.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class BoardListMenuComponent {
@Input() board:Board;
diff --git a/frontend/src/app/features/boards/board/board-list/board-list.component.ts b/frontend/src/app/features/boards/board/board-list/board-list.component.ts
index 52406a60191..baa4f648b35 100644
--- a/frontend/src/app/features/boards/board/board-list/board-list.component.ts
+++ b/frontend/src/app/features/boards/board/board-list/board-list.component.ts
@@ -185,9 +185,9 @@ export class BoardListComponent extends AbstractWidgetComponent implements OnIni
this.resource.isNewWidget = false;
// Set initial selection if split view open
- if (this.state.includes(`${this.state.current.data.baseRoute}.details`)) {
- const wpId = this.state.params.workPackageId;
- this.wpViewSelectionService.initializeSelection([wpId]);
+ const detailsMatch = window.location.pathname.match(/\/details\/(\d+)/);
+ if (detailsMatch) {
+ this.wpViewSelectionService.initializeSelection([detailsMatch[1]]);
}
// If this query space changes its focused or selected
@@ -495,15 +495,20 @@ export class BoardListComponent extends AbstractWidgetComponent implements OnIni
}
openStateLink(event:{ workPackageId:string; requestedState:string }) {
- const params = { workPackageId: event.workPackageId };
-
if (event.requestedState === 'split') {
- this.keepTab.goCurrentDetailsState(params);
+ this.goToSplitView(event.workPackageId);
} else {
- this.keepTab.goCurrentShowState(params.workPackageId);
+ this.keepTab.goCurrentShowState(event.workPackageId);
}
}
+ private goToSplitView(workPackageId:string):void {
+ const base = this.pathHelper.boardDetailsPath(this.currentProject.identifier, this.board.id!, workPackageId);
+ const search = window.location.search;
+ const link = search ? `${base}${search}` : base;
+ Turbo.visit(link, { frame: 'content-bodyRight', action: 'advance' });
+ }
+
private schema(workPackage:WorkPackageResource) {
return this.schemaCache.of(workPackage);
}
diff --git a/frontend/src/app/features/boards/boards-root/boards-root.component.ts b/frontend/src/app/features/boards/board/board-partitioned-page/board-entry.component.ts
similarity index 51%
rename from frontend/src/app/features/boards/boards-root/boards-root.component.ts
rename to frontend/src/app/features/boards/board/board-partitioned-page/board-entry.component.ts
index 65eb30d4516..0503484d44b 100644
--- a/frontend/src/app/features/boards/boards-root/boards-root.component.ts
+++ b/frontend/src/app/features/boards/board/board-partitioned-page/board-entry.component.ts
@@ -1,20 +1,50 @@
-import { Component, Injector } from '@angular/core';
+//-- 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 { ChangeDetectionStrategy, Component, ElementRef, Injector, Input } from '@angular/core';
+import { populateInputsFromDataset } from 'core-app/shared/components/dataset-inputs';
+import {
+ WorkPackageIsolatedQuerySpaceDirective,
+} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
import { BoardConfigurationService } from 'core-app/features/boards/board/configuration-modal/board-configuration.service';
import { BoardActionsRegistryService } from 'core-app/features/boards/board/board-actions/board-actions-registry.service';
import { BoardStatusActionService } from 'core-app/features/boards/board/board-actions/status/status-action.service';
import { BoardVersionActionService } from 'core-app/features/boards/board/board-actions/version/version-action.service';
-import { QueryUpdatedService } from 'core-app/features/boards/board/query-updated/query-updated.service';
import { BoardAssigneeActionService } from 'core-app/features/boards/board/board-actions/assignee/assignee-action.service';
import { BoardSubprojectActionService } from 'core-app/features/boards/board/board-actions/subproject/subproject-action.service';
import { BoardSubtasksActionService } from 'core-app/features/boards/board/board-actions/subtasks/board-subtasks-action.service';
-import {
- WorkPackageIsolatedQuerySpaceDirective,
-} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
+import { QueryUpdatedService } from 'core-app/features/boards/board/query-updated/query-updated.service';
@Component({
- selector: 'boards-entry',
+ selector: 'board-entry',
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective],
- template: '',
+ template: ``,
+ changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
BoardConfigurationService,
BoardStatusActionService,
@@ -26,11 +56,18 @@ import {
],
standalone: false,
})
-export class BoardsRootComponent {
- constructor(readonly injector:Injector) {
- // Register action services
- const registry = injector.get(BoardActionsRegistryService);
+export class BoardEntryComponent {
+ @Input() boardId:string;
+ constructor(
+ readonly elementRef:ElementRef,
+ readonly injector:Injector,
+ ) {
+ populateInputsFromDataset(this);
+
+ document.body.classList.add('router--boards-full-view');
+
+ const registry = injector.get(BoardActionsRegistryService);
registry.add('status', injector.get(BoardStatusActionService));
registry.add('assignee', injector.get(BoardAssigneeActionService));
registry.add('version', injector.get(BoardVersionActionService));
diff --git a/frontend/src/app/features/boards/board/board-partitioned-page/board-list-container.component.ts b/frontend/src/app/features/boards/board/board-partitioned-page/board-list-container.component.ts
index cecc9501023..fba32f8b51d 100644
--- a/frontend/src/app/features/boards/board/board-partitioned-page/board-list-container.component.ts
+++ b/frontend/src/app/features/boards/board/board-partitioned-page/board-list-container.component.ts
@@ -2,6 +2,7 @@ import {
ChangeDetectionStrategy,
Component,
ElementRef,
+ Input,
Injector,
OnInit,
QueryList,
@@ -36,11 +37,11 @@ import {
BoardActionsRegistryService,
} from 'core-app/features/boards/board/board-actions/board-actions-registry.service';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
-import {
- WorkPackageStatesInitializationService,
-} from 'core-app/features/work-packages/components/wp-list/wp-states-initialization.service';
+import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
+import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
@Component({
+ selector: 'board-list-container',
templateUrl: './board-list-container.component.html',
styleUrls: ['./board-list-container.component.sass'],
providers: [
@@ -50,6 +51,7 @@ import {
standalone: false,
})
export class BoardListContainerComponent extends UntilDestroyedMixin implements OnInit {
+ @Input() boardId:string;
text = {
delete: this.I18n.t('js.button_delete'),
areYouSure: this.I18n.t('js.text_are_you_sure'),
@@ -90,7 +92,7 @@ export class BoardListContainerComponent extends UntilDestroyedMixin implements
private currentQueryUpdatedMonitoring:Subscription;
constructor(
-readonly I18n:I18nService,
+ readonly I18n:I18nService,
readonly state:StateService,
readonly toastService:ToastService,
readonly halNotification:HalResourceNotificationService,
@@ -102,16 +104,17 @@ readonly I18n:I18nService,
readonly apiV3Service:ApiV3Service,
readonly Boards:BoardService,
readonly boardListCrossSelectionService:BoardListCrossSelectionService,
- readonly wpStatesInitialization:WorkPackageStatesInitializationService,
readonly Drag:DragAndDropService,
readonly apiv3Service:ApiV3Service,
readonly QueryUpdated:QueryUpdatedService,
+ readonly pathHelper:PathHelperService,
+ readonly currentProject:CurrentProjectService,
) {
super();
}
ngOnInit():void {
- const id:string = this.state.params.board_id.toString();
+ const id:string = this.boardId || this.state.params.board_id?.toString();
this.board$ = this
.apiV3Service
.boards
@@ -128,10 +131,12 @@ readonly I18n:I18nService,
.pipe(
this.untilDestroyed(),
filter((state) => state.focusedWorkPackage !== null),
- filter(() => this.state.includes(`${this.state.current.data.baseRoute}.details`)),
+ filter(() => window.location.pathname.includes('/details/')),
).subscribe((selection) => {
- // Update split screen
- this.state.go(`${this.state.current.data.baseRoute}.details`, { workPackageId: selection.focusedWorkPackage });
+ // Update split screen
+ const base = this.pathHelper.boardDetailsPath(this.currentProject.identifier, id, selection.focusedWorkPackage!);
+ const search = window.location.search;
+ Turbo.visit(search ? `${base}${search}` : base, { frame: 'content-bodyRight', action: 'advance' });
});
}
diff --git a/frontend/src/app/features/boards/board/board-partitioned-page/board-partitioned-page.component.html b/frontend/src/app/features/boards/board/board-partitioned-page/board-partitioned-page.component.html
new file mode 100644
index 00000000000..a0ee9d566e0
--- /dev/null
+++ b/frontend/src/app/features/boards/board/board-partitioned-page/board-partitioned-page.component.html
@@ -0,0 +1,48 @@
+
diff --git a/frontend/src/app/shared/components/modals/wp-destroy-modal/wp-destroy.modal.ts b/frontend/src/app/shared/components/modals/wp-destroy-modal/wp-destroy.modal.ts
deleted file mode 100644
index 1b83db1e8e7..00000000000
--- a/frontend/src/app/shared/components/modals/wp-destroy-modal/wp-destroy.modal.ts
+++ /dev/null
@@ -1,183 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-import { WorkPackagesListService } from 'core-app/features/work-packages/components/wp-list/wp-list.service';
-import { States } from 'core-app/core/states/states.service';
-import {
- ChangeDetectorRef,
- Component,
- ElementRef,
- Inject,
- OnInit,
-} from '@angular/core';
-import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
-import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service';
-import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types';
-import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource';
-import { WorkPackageViewFocusService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-focus.service';
-import { StateService } from '@uirouter/core';
-import { I18nService } from 'core-app/core/i18n/i18n.service';
-import { WorkPackageNotificationService } from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
-import { WorkPackageService } from 'core-app/features/work-packages/services/work-package.service';
-import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
-import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
-import { BackRoutingService } from 'core-app/features/work-packages/components/back-routing/back-routing.service';
-
-@Component({
- templateUrl: './wp-destroy.modal.html',
- standalone: false,
-})
-export class WpDestroyModalComponent extends OpModalComponent implements OnInit {
- // When deleting multiple
- public workPackages:WorkPackageResource[];
-
- public workPackageLabel:string;
-
- // Single work package
- public singleWorkPackage:WorkPackageResource;
-
- public singleWorkPackageChildren:WorkPackageResource[];
-
- public busy = false;
-
- // Need to confirm deletion when children are involved
- public childrenDeletionConfirmed = false;
-
- public text = {
- label_visibility_settings: this.I18n.t('js.label_visibility_settings'),
- button_save: this.I18n.t('js.modals.button_save'),
- confirm: this.I18n.t('js.modals.button_delete'),
- warning: this.I18n.t('js.label_warning'),
- cancel: this.I18n.t('js.button_cancel'),
- close: this.I18n.t('js.close_popup_title'),
- label_confirm_children_deletion: this.I18n.t('js.modals.destroy_work_package.confirm_deletion_children'),
- title: '',
- bulk_text: '',
- single_text: this.I18n.t('js.modals.destroy_work_package.single_text'),
- childCount: (_wp:WorkPackageResource):string => '',
- hasChildren: (_wp:WorkPackageResource):string => '',
- deletesChildren: '',
- };
-
- constructor(
- readonly elementRef:ElementRef,
- readonly workPackageService:WorkPackageService,
- @Inject(OpModalLocalsToken) public locals:OpModalLocalsMap,
- readonly I18n:I18nService,
- readonly cdRef:ChangeDetectorRef,
- readonly $state:StateService,
- readonly states:States,
- readonly wpTableFocus:WorkPackageViewFocusService,
- readonly wpListService:WorkPackagesListService,
- readonly notificationService:WorkPackageNotificationService,
- readonly currentProject:CurrentProjectService,
- readonly pathHelper:PathHelperService,
- readonly backRoutingService:BackRoutingService,
- ) {
- super(locals, cdRef, elementRef);
- }
-
- ngOnInit():void {
- super.ngOnInit();
-
- this.workPackages = this.locals.workPackages;
- this.workPackageLabel = this.I18n.t('js.units.workPackage', { count: this.workPackages.length });
-
- // Ugly way to provide the same view bindings as the ng-init in the previous template.
- if (this.workPackages.length === 1) {
- this.singleWorkPackage = this.workPackages[0];
- this.singleWorkPackageChildren = this.singleWorkPackage.children;
- }
-
- this.text.title = this.I18n.t('js.modals.destroy_work_package.title', { label: this.workPackageLabel });
- this.text.bulk_text = this.I18n.t('js.modals.destroy_work_package.bulk_text', {
- label: this.workPackageLabel,
- count: this.workPackages.length,
- });
-
- this.text.childCount = (wp:WorkPackageResource) => {
- const count = this.children(wp).length;
- return this.I18n.t('js.units.child_work_packages', { count });
- };
-
- this.text.hasChildren = (wp:WorkPackageResource) => {
- const childUnits = this.text.childCount(wp);
- return this.I18n.t('js.modals.destroy_work_package.has_children', { childUnits });
- };
- this.text.deletesChildren = this.I18n.t('js.modals.destroy_work_package.deletes_children');
- }
-
- public get blockedDueToUnconfirmedChildren():boolean {
- return this.mustConfirmChildren && !this.childrenDeletionConfirmed;
- }
-
- public get mustConfirmChildren():boolean {
- let result = false;
-
- if (this.singleWorkPackage && this.singleWorkPackageChildren) {
- result = this.singleWorkPackageChildren.length > 0;
- }
-
- return result || !!_.find(this.workPackages, (wp) => wp.children && wp.children.length > 0);
- }
-
- public confirmDeletion($event:Event):boolean {
- if (this.busy || this.blockedDueToUnconfirmedChildren) {
- return false;
- }
-
- this.busy = true;
- const ids = this.workPackages
- .map((el) => el.id)
- .filter((id) => id !== null);
- this.workPackageService.performBulkDelete(ids, true)
- .then(() => {
- this.busy = false;
- this.closeMe($event);
- this.wpTableFocus.clear('Clearing after destroying work packages');
- if (this.$state.current.data?.baseRoute) {
- this.backRoutingService.goBack(true);
- } else {
- const projectIdentifier = this.currentProject.identifier;
- window.location.href = this.pathHelper.workPackagesPath(projectIdentifier) + window.location.search;
- }
- })
- .catch(() => {
- this.busy = false;
- });
-
- return false;
- }
-
- public children(workPackage:WorkPackageResource) {
- if (workPackage.hasOwnProperty('children')) {
- return workPackage.children;
- }
- return [];
- }
-}
diff --git a/frontend/src/app/shared/components/op-context-menu/icon-triggered-context-menu/icon-triggered-context-menu.component.ts b/frontend/src/app/shared/components/op-context-menu/icon-triggered-context-menu/icon-triggered-context-menu.component.ts
index 726d030a091..e44f1a57d63 100644
--- a/frontend/src/app/shared/components/op-context-menu/icon-triggered-context-menu/icon-triggered-context-menu.component.ts
+++ b/frontend/src/app/shared/components/op-context-menu/icon-triggered-context-menu/icon-triggered-context-menu.component.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { ChangeDetectorRef, Component, ElementRef, Injector, Input } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Injector, Input } from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import {
OpContextMenuTrigger,
@@ -40,6 +40,10 @@ import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op
templateUrl: './icon-triggered-context-menu.component.html',
styleUrls: ['./icon-triggered-context-menu.component.sass'],
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class IconTriggeredContextMenuComponent extends OpContextMenuTrigger {
override readonly placement = 'bottom-end';
@@ -58,8 +62,13 @@ export class IconTriggeredContextMenuComponent extends OpContextMenuTrigger {
@Input() menuItemsFactory:() => Promise;
@Input() customAriaLabel:string = this.I18n.t('js.label_open_menu');
- protected async open(evt:Event) {
+ protected open(evt:Event):void {
+ void this.openContextMenu(evt);
+ }
+
+ private async openContextMenu(evt:Event):Promise {
this.items = await this.buildItems();
+ this.cdRef.markForCheck();
this.opContextMenu.show(this, evt);
}
diff --git a/frontend/src/app/shared/components/op-context-menu/op-context-menu.component.ts b/frontend/src/app/shared/components/op-context-menu/op-context-menu.component.ts
index 7e0144c5054..9da13c47753 100644
--- a/frontend/src/app/shared/components/op-context-menu/op-context-menu.component.ts
+++ b/frontend/src/app/shared/components/op-context-menu/op-context-menu.component.ts
@@ -1,4 +1,4 @@
-import { Component, Inject } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Inject } from '@angular/core';
import {
OpContextMenuItem,
OpContextMenuLocalsMap,
@@ -9,6 +9,10 @@ import { OPContextMenuService } from 'core-app/shared/components/op-context-menu
@Component({
templateUrl: './op-context-menu.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class OPContextMenuComponent {
public items:OpContextMenuItem[];
diff --git a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts
index 04b2972400d..f9124b4486e 100644
--- a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts
+++ b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-single-context-menu.ts
@@ -12,18 +12,17 @@ import { OpContextMenuItem } from 'core-app/shared/components/op-context-menu/op
import {
PERMITTED_CONTEXT_MENU_ACTIONS,
} from 'core-app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions';
-import { OpModalService } from 'core-app/shared/components/modal/modal.service';
import { CopyToClipboardService } from 'core-app/shared/components/copy-to-clipboard/copy-to-clipboard.service';
import {
WorkPackageAction,
} from 'core-app/features/work-packages/components/wp-table/context-menu-helper/wp-context-menu-helper.service';
-import { WpDestroyModalComponent } from 'core-app/shared/components/modals/wp-destroy-modal/wp-destroy.modal';
import { WorkPackageAuthorization } from 'core-app/features/work-packages/services/work-package-authorization.service';
import { TurboRequestsService } from 'core-app/core/turbo/turbo-requests.service';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { TimeEntryTimerService } from 'core-app/shared/components/time_entries/services/time-entry-timer.service';
import { TimeEntryResource } from 'core-app/features/hal/resources/time-entry-resource';
import { DeviceService } from 'core-app/core/browser/device.service';
+import { CurrentProjectService } from 'core-app/core/current-project/current-project.service';
@Directive({
// eslint-disable-next-line @angular-eslint/directive-selector
@@ -41,10 +40,10 @@ export class WorkPackageSingleContextMenuDirective extends OpContextMenuTrigger
readonly injector = inject(Injector);
readonly PathHelper = inject(PathHelperService);
readonly elementRef = inject(ElementRef);
- readonly opModalService = inject(OpModalService);
readonly turboRequests = inject(TurboRequestsService);
readonly apiV3Service = inject(ApiV3Service);
readonly authorisationService = inject(AuthorisationService);
+ readonly currentProject = inject(CurrentProjectService);
readonly timeEntryService = inject(TimeEntryTimerService);
protected copyToClipboardService = inject(CopyToClipboardService);
protected deviceService = inject(DeviceService);
@@ -96,9 +95,18 @@ export class WorkPackageSingleContextMenuDirective extends OpContextMenuTrigger
window.location.href = `${this.PathHelper.workPackageCopyPath(this.workPackage.project.identifier, this.workPackage.id)}`;
}
break;
- case 'delete':
- this.opModalService.show(WpDestroyModalComponent, this.injector, { workPackages: [this.workPackage] });
+ case 'delete': {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
+ const currentBaseRoute = this.$state.current.data?.baseRoute as string | undefined;
+ const backUrl = currentBaseRoute
+ ? this.$state.href(currentBaseRoute)
+ : this.PathHelper.workPackagesPath(this.currentProject.identifier ?? null);
+ void this.turboRequests.request(
+ this.PathHelper.workPackagesBulkDeleteDialogPath([this.workPackage.id!], backUrl),
+ { method: 'GET' },
+ );
break;
+ }
case 'log_time':
void this.turboRequests.request(this.PathHelper.timeEntryWorkPackageDialog(this.workPackage.id!), { method: 'GET' });
break;
diff --git a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive.ts b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive.ts
index f4e6953a8fe..e3cf08e3a50 100644
--- a/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive.ts
+++ b/frontend/src/app/shared/components/op-context-menu/wp-context-menu/wp-view-context-menu.directive.ts
@@ -20,12 +20,10 @@ import {
import {
PERMITTED_CONTEXT_MENU_ACTIONS,
} from 'core-app/shared/components/op-context-menu/wp-context-menu/wp-static-context-menu-actions';
-import { OpModalService } from 'core-app/shared/components/modal/modal.service';
import { StateService } from '@uirouter/core';
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
import { CopyToClipboardService } from 'core-app/shared/components/copy-to-clipboard/copy-to-clipboard.service';
import { splitViewRoute } from 'core-app/features/work-packages/routing/split-view-routes.helper';
-import { WpDestroyModalComponent } from 'core-app/shared/components/modals/wp-destroy-modal/wp-destroy.modal';
import isNewResource from 'core-app/features/hal/helpers/is-new-resource';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { TurboRequestsService } from 'core-app/core/turbo/turbo-requests.service';
@@ -40,8 +38,6 @@ export class WorkPackageViewContextMenu extends OpContextMenuHandler {
@InjectField() protected wpRelationsHierarchyService:WorkPackageRelationsHierarchyService;
- @InjectField() protected opModalService:OpModalService;
-
@InjectField() protected $state!:StateService;
@InjectField() protected wpTableSelection:WorkPackageViewSelectionService;
@@ -152,7 +148,9 @@ export class WorkPackageViewContextMenu extends OpContextMenuHandler {
private deleteSelectedWorkPackages() {
const selected = this.getSelectedWorkPackages();
- this.opModalService.show(WpDestroyModalComponent, this.injector, { workPackages: selected });
+ const ids = selected.map((wp) => wp.id).filter((id) => id !== null);
+ const backUrl = this.$state.href(this.baseRoute as string) || this.pathHelper.workPackagesPath(this.currentProject.identifier ?? null);
+ void this.turboRequests.request(this.pathHelper.workPackagesBulkDeleteDialogPath(ids, backUrl), { method: 'GET' });
}
private editSelectedWorkPackages(link:any) {
diff --git a/frontend/src/app/shared/components/option-list/option-list.component.ts b/frontend/src/app/shared/components/option-list/option-list.component.ts
index a3a6a60df45..c0ec3addba0 100644
--- a/frontend/src/app/shared/components/option-list/option-list.component.ts
+++ b/frontend/src/app/shared/components/option-list/option-list.component.ts
@@ -1,4 +1,6 @@
import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
Component,
EventEmitter,
forwardRef,
@@ -27,10 +29,16 @@ export type IOpOptionListValue = T|null;
multi: true,
}],
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class OpOptionListComponent implements ControlValueAccessor {
@HostBinding('class.op-option-list') className = true;
+ constructor(private cdRef:ChangeDetectorRef) {}
+
@Input() options:IOpOptionListOption[] = [];
@Input() name = `op-option-list-${+(new Date())}`;
@@ -62,6 +70,7 @@ export class OpOptionListComponent implements ControlValueAccessor {
writeValue(value:IOpOptionListValue) {
this._selected = value;
+ this.cdRef.markForCheck();
}
registerOnChange(fn:any) {
diff --git a/frontend/src/app/shared/components/persistent-toggle/persistent-toggle.component.ts b/frontend/src/app/shared/components/persistent-toggle/persistent-toggle.component.ts
index 3ac45db3083..7b3d3497f2d 100644
--- a/frontend/src/app/shared/components/persistent-toggle/persistent-toggle.component.ts
+++ b/frontend/src/app/shared/components/persistent-toggle/persistent-toggle.component.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { Component, ElementRef, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, Component, ElementRef, OnInit } from '@angular/core';
import { slideDown, slideUp } from 'es6-slide-up-down';
@@ -34,6 +34,10 @@ import { slideDown, slideUp } from 'es6-slide-up-down';
selector: 'opce-persistent-toggle',
template: '',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class PersistentToggleComponent implements OnInit {
/** Unique identifier of the toggle */
diff --git a/frontend/src/app/shared/components/primer/icon-button.component.spec.ts b/frontend/src/app/shared/components/primer/icon-button.component.spec.ts
index 59bd378835b..105526cb09c 100644
--- a/frontend/src/app/shared/components/primer/icon-button.component.spec.ts
+++ b/frontend/src/app/shared/components/primer/icon-button.component.spec.ts
@@ -28,16 +28,16 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PrimerIconButtonComponent } from './icon-button.component';
describe('PrimerIconButtonComponent', () => {
let component:PrimerIconButtonComponent;
let fixture:ComponentFixture;
- beforeEach(waitForAsync(() => {
- TestBed.configureTestingModule({imports: [PrimerIconButtonComponent]});
- }));
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({imports: [PrimerIconButtonComponent]}).compileComponents();
+ });
beforeEach(() => {
fixture = TestBed.createComponent(PrimerIconButtonComponent);
diff --git a/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.spec.ts b/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.spec.ts
new file mode 100644
index 00000000000..a7c056ea4fd
--- /dev/null
+++ b/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.spec.ts
@@ -0,0 +1,146 @@
+//-- 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 { ChangeDetectorRef, ElementRef } from '@angular/core';
+import { Observable, config, throwError } from 'rxjs';
+import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types';
+import { SortFilesPipe } from 'core-app/shared/components/storages/pipes/sort-files.pipe';
+import { StorageFilesResourceService } from 'core-app/core/state/storage-files/storage-files.service';
+import { IStorageFile } from 'core-app/core/state/storage-files/storage-file.model';
+import {
+ FilePickerBaseModalComponent,
+} from 'core-app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component';
+import { StorageFileListItem } from 'core-app/shared/components/storages/storage-file-list-item/storage-file-list-item';
+
+class TestFilePickerBaseModalComponent extends FilePickerBaseModalComponent {
+ constructor(
+ locals:OpModalLocalsMap,
+ elementRef:ElementRef,
+ cdRef:ChangeDetectorRef,
+ sortFilesPipe:SortFilesPipe,
+ storageFilesResourceService:StorageFilesResourceService,
+ ) {
+ super(locals, elementRef, cdRef, sortFilesPipe, storageFilesResourceService);
+ }
+
+ public loadDirectory(directory:IStorageFile):void {
+ this.changeLevel(directory);
+ }
+
+ protected storageFileToListItem(_file:IStorageFile, _index:number):StorageFileListItem {
+ return {} as StorageFileListItem;
+ }
+}
+
+describe('FilePickerBaseModalComponent', () => {
+ interface Spies {
+ detectChanges:jasmine.Spy;
+ close:jasmine.Spy;
+ files:jasmine.Spy;
+ reset:jasmine.Spy;
+ }
+
+ function buildComponent(spies:Spies) {
+ const cdRef = { detectChanges: spies.detectChanges } as unknown as ChangeDetectorRef;
+ const elementRef = { nativeElement: document.createElement('div') } as ElementRef;
+ const locals = {
+ service: { close: spies.close },
+ storage: {
+ name: 'Storage',
+ _links: {
+ type: { href: 'urn:openproject:test-storage' },
+ self: { href: '/api/v3/storages/1' },
+ },
+ },
+ projectFolderMode: 'inactive',
+ } as unknown as OpModalLocalsMap;
+ const sortFilesPipe = { transform: (files:IStorageFile[]) => files } as SortFilesPipe;
+ const storageFilesResourceService = {
+ files: spies.files,
+ reset: spies.reset,
+ } as unknown as StorageFilesResourceService;
+ const component = new TestFilePickerBaseModalComponent(
+ locals,
+ elementRef,
+ cdRef,
+ sortFilesPipe,
+ storageFilesResourceService,
+ );
+
+ component.ngOnInit();
+
+ return { component, cdRef, storageFilesResourceService };
+ }
+
+ it('cancels pending directory loading on destroy', () => {
+ const teardown = jasmine.createSpy('teardown');
+ const files$ = new Observable(() => teardown);
+ const directory = { location: '/folder', mimeType: 'application/x-op-directory' } as IStorageFile;
+ const files = jasmine.createSpy('files').and.returnValue(files$);
+ const { component } = buildComponent({
+ detectChanges: jasmine.createSpy('detectChanges'),
+ close: jasmine.createSpy('close'),
+ files,
+ reset: jasmine.createSpy('reset'),
+ });
+
+ component.loadDirectory(directory);
+
+ expect(files).toHaveBeenCalledTimes(2);
+ expect(teardown).not.toHaveBeenCalled();
+
+ component.ngOnDestroy();
+
+ expect(teardown).toHaveBeenCalledTimes(1);
+ });
+
+ it('does not report directory loading errors as unhandled async exceptions', async () => {
+ const previousUnhandledError = config.onUnhandledError;
+ const onUnhandledError = jasmine.createSpy('onUnhandledError');
+ const files$ = throwError(() => new Error('boom'));
+ const detectChanges = jasmine.createSpy('detectChanges');
+ const directory = { location: '/folder', mimeType: 'application/x-op-directory' } as IStorageFile;
+ const { component } = buildComponent({
+ detectChanges,
+ close: jasmine.createSpy('close'),
+ files: jasmine.createSpy('files').and.returnValue(files$),
+ reset: jasmine.createSpy('reset'),
+ });
+
+ config.onUnhandledError = onUnhandledError;
+
+ component.loadDirectory(directory);
+ await new Promise((resolve) => window.setTimeout(resolve));
+
+ expect(component.loading$.getValue()).toBe('error');
+ expect(detectChanges).toHaveBeenCalledWith();
+ expect(onUnhandledError).not.toHaveBeenCalled();
+
+ config.onUnhandledError = previousUnhandledError;
+ });
+});
diff --git a/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.ts b/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.ts
index 6bec3bbad27..81a47109c5d 100644
--- a/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.ts
+++ b/frontend/src/app/shared/components/storages/file-picker-base-modal/file-picker-base-modal.component.ts
@@ -120,10 +120,11 @@ export abstract class FilePickerBaseModalComponent extends OpModalComponent impl
this.breadcrumbs = this.makeBreadcrumbs(storageFiles.ancestors, storageFiles.parent);
this.storageFiles$.next(storageFiles.files);
this.loading$.next('success');
+ this.cdRef.detectChanges();
},
- error: (error) => {
+ error: () => {
this.loading$.next('error');
- throw error;
+ this.cdRef.detectChanges();
},
});
}
@@ -131,6 +132,7 @@ export abstract class FilePickerBaseModalComponent extends OpModalComponent impl
ngOnDestroy():void {
super.ngOnDestroy();
+ this.cancelCurrentLoading();
this.storageFilesResourceService.reset();
}
@@ -151,6 +153,7 @@ export abstract class FilePickerBaseModalComponent extends OpModalComponent impl
protected changeLevel(ancestor:IStorageFile):void {
this.cancelCurrentLoading();
this.loading$.next('loading');
+ this.cdRef.detectChanges();
this.loadingSubscription = this.storageFilesResourceService
.files(makeFilesCollectionLink(this.storage._links.self, ancestor.location))
@@ -160,10 +163,11 @@ export abstract class FilePickerBaseModalComponent extends OpModalComponent impl
this.breadcrumbs = this.makeBreadcrumbs(storageFiles.ancestors, storageFiles.parent);
this.storageFiles$.next(storageFiles.files);
this.loading$.next('success');
+ this.cdRef.detectChanges();
},
- error: (error) => {
+ error: () => {
this.loading$.next('error');
- throw error;
+ this.cdRef.detectChanges();
},
});
}
diff --git a/frontend/src/app/shared/components/toaster/toast.service.spec.ts b/frontend/src/app/shared/components/toaster/toast.service.spec.ts
index af521143451..850555ce368 100644
--- a/frontend/src/app/shared/components/toaster/toast.service.spec.ts
+++ b/frontend/src/app/shared/components/toaster/toast.service.spec.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { TestBed, waitForAsync } from '@angular/core/testing';
+import { TestBed } from '@angular/core/testing';
import { ToastService } from 'core-app/shared/components/toaster/toast.service';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { ConfigurationService } from 'core-app/core/config/configuration.service';
@@ -38,9 +38,8 @@ import { HttpEvent, provideHttpClient, withInterceptorsFromDi } from '@angular/c
describe('ToastService', () => {
let toastService:ToastService;
- beforeEach(waitForAsync(() => {
- // noinspection JSIgnoredPromiseFromCall
- TestBed.configureTestingModule({
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
imports: [OpenprojectHalModule],
providers: [
{ provide: ConfigurationService, useValue: { autoHidePopups: () => true } },
@@ -49,12 +48,9 @@ describe('ToastService', () => {
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting(),
]
-})
- .compileComponents()
- .then(() => {
- toastService = TestBed.inject(ToastService);
- });
- }));
+}).compileComponents();
+ toastService = TestBed.inject(ToastService);
+ });
it('should be able to create warnings', () => {
const toaster = toastService.addWarning('warning!');
diff --git a/frontend/src/app/shared/components/user-link/user-link.component.spec.ts b/frontend/src/app/shared/components/user-link/user-link.component.spec.ts
index cbe77a16317..1022a7bf347 100644
--- a/frontend/src/app/shared/components/user-link/user-link.component.spec.ts
+++ b/frontend/src/app/shared/components/user-link/user-link.component.spec.ts
@@ -26,7 +26,7 @@
// See COPYRIGHT and LICENSE files for more details.
//++
-import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { UserResource } from 'core-app/features/hal/resources/user-resource';
@@ -46,9 +46,8 @@ describe('UserLinkComponent component test', () => {
let element:HTMLElement;
let user:UserResource;
- beforeEach(waitForAsync(() => {
- // noinspection JSIgnoredPromiseFromCall
- TestBed.configureTestingModule({
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
declarations: [
UserLinkComponent,
],
@@ -61,11 +60,11 @@ describe('UserLinkComponent component test', () => {
fixture = TestBed.createComponent(UserLinkComponent);
app = fixture.debugElement.componentInstance;
element = fixture.elementRef.nativeElement;
- }));
+ });
describe('inner element', () => {
- describe('with the uer having the showUserPath attribute', () => {
- beforeEach(waitForAsync(() => {
+ describe('with the user having the showUserPath attribute', () => {
+ beforeEach(() => {
user = {
name: 'First Last',
showUserPath: '/users/1',
@@ -73,7 +72,7 @@ describe('UserLinkComponent component test', () => {
fixture.componentRef.setInput('user', user);
fixture.detectChanges();
- }));
+ });
it('should render an inner link with specified classes', () => {
const link = element.querySelector('a')!;
@@ -85,7 +84,7 @@ describe('UserLinkComponent component test', () => {
});
describe('with the user not having the showUserPath attribute', () => {
- beforeEach(waitForAsync(() => {
+ beforeEach(() => {
user = {
name: 'First Last',
showUserPath: null,
@@ -93,7 +92,7 @@ describe('UserLinkComponent component test', () => {
fixture.componentRef.setInput('user', user);
fixture.detectChanges();
- }));
+ });
it('renders only the name', () => {
const link = element.querySelector('a');
diff --git a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab-inner.component.ts b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab-inner.component.ts
index 157e1cde494..14e2c569689 100644
--- a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab-inner.component.ts
+++ b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab-inner.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { TabComponent } from 'core-app/features/work-packages/components/wp-table/configuration-modal/tab-portal-outlet';
import { WorkPackageViewFiltersService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-filters.service';
@@ -12,6 +12,10 @@ import { WorkPackageFiltersService } from 'core-app/features/work-packages/compo
selector: 'op-filters-tab-inner',
templateUrl: './filters-tab-inner.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class WpGraphConfigurationFiltersTabInnerComponent extends QuerySpacedTabComponent implements TabComponent, OnInit {
public filters:QueryFilterInstanceResource[] = [];
@@ -24,17 +28,19 @@ export class WpGraphConfigurationFiltersTabInnerComponent extends QuerySpacedTab
readonly wpTableFilters:WorkPackageViewFiltersService,
readonly wpFiltersService:WorkPackageFiltersService,
readonly wpStatesInitialization:WorkPackageStatesInitializationService,
- readonly wpGraphConfiguration:WpGraphConfigurationService) {
+ readonly wpGraphConfiguration:WpGraphConfigurationService,
+ private cdRef:ChangeDetectorRef) {
super(I18n, wpStatesInitialization, wpGraphConfiguration);
}
ngOnInit() {
- this.initializeQuerySpace()
+ void this.initializeQuerySpace()
.then(() => {
- this.wpTableFilters
+ void this.wpTableFilters
.onReady()
.then(() => {
this.filters = this.wpTableFilters.current;
+ this.cdRef.markForCheck();
});
});
}
diff --git a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab.component.ts b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab.component.ts
index 7a4ac06522c..255a19d2de7 100644
--- a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab.component.ts
+++ b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/filters-tab.component.ts
@@ -1,4 +1,4 @@
-import { Component, ViewChild } from '@angular/core';
+import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
import { TabComponent } from 'core-app/features/work-packages/components/wp-table/configuration-modal/tab-portal-outlet';
import {
WorkPackageIsolatedQuerySpaceDirective,
@@ -9,6 +9,10 @@ import {
templateUrl: './filters-tab.component.html',
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective], // TODO replace
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class WpGraphConfigurationFiltersTabComponent implements TabComponent {
@ViewChild('tabInner', { static: true })
diff --git a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab-inner.component.ts b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab-inner.component.ts
index 994e786162c..baffe7b4c01 100644
--- a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab-inner.component.ts
+++ b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab-inner.component.ts
@@ -1,6 +1,6 @@
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { WorkPackageViewGroupByService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-group-by.service';
-import { Component, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { WpGraphConfigurationService } from 'core-app/shared/components/work-package-graphs/configuration/wp-graph-configuration.service';
import { WorkPackageStatesInitializationService } from 'core-app/features/work-packages/components/wp-list/wp-states-initialization.service';
import { TabComponent } from 'core-app/features/work-packages/components/wp-table/configuration-modal/tab-portal-outlet';
@@ -17,6 +17,10 @@ interface OpChartType {
selector: 'op-settings-tab-inner',
templateUrl: './settings-tab-inner.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class WpGraphConfigurationSettingsTabInnerComponent extends QuerySpacedTabComponent implements TabComponent, OnInit {
// Grouping
@@ -34,7 +38,8 @@ export class WpGraphConfigurationSettingsTabInnerComponent extends QuerySpacedTa
constructor(readonly I18n:I18nService,
readonly wpTableGroupBy:WorkPackageViewGroupByService,
readonly wpStatesInitialization:WorkPackageStatesInitializationService,
- readonly wpGraphConfiguration:WpGraphConfigurationService) {
+ readonly wpGraphConfiguration:WpGraphConfigurationService,
+ private cdRef:ChangeDetectorRef) {
super(I18n, wpStatesInitialization, wpGraphConfiguration);
}
@@ -54,14 +59,15 @@ export class WpGraphConfigurationSettingsTabInnerComponent extends QuerySpacedTa
}
ngOnInit() {
- this
+ void this
.initializeQuerySpace()
.then(() => {
- this.wpTableGroupBy
+ void this.wpTableGroupBy
.onReady()
.then(() => {
this.initializeAvailableGroups();
this.initializeAvailableChartType();
+ this.cdRef.markForCheck();
});
});
}
diff --git a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab.component.ts b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab.component.ts
index ed642e8d336..fa2ec91fc69 100644
--- a/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab.component.ts
+++ b/frontend/src/app/shared/components/work-package-graphs/configuration-modal/tabs/settings-tab.component.ts
@@ -1,5 +1,5 @@
import { TabComponent } from 'core-app/features/work-packages/components/wp-table/configuration-modal/tab-portal-outlet';
-import { Component, ViewChild } from '@angular/core';
+import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
import {
WorkPackageIsolatedQuerySpaceDirective,
} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
@@ -9,6 +9,10 @@ import {
templateUrl: './settings-tab.component.html',
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective],
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class WpGraphConfigurationSettingsTabComponent implements TabComponent {
@ViewChild('tabInner', { static: true })
diff --git a/frontend/src/app/shared/components/work-package-graphs/embedded/wp-embedded-graph.component.ts b/frontend/src/app/shared/components/work-package-graphs/embedded/wp-embedded-graph.component.ts
index 48c43a5d351..1361dd9e7fe 100644
--- a/frontend/src/app/shared/components/work-package-graphs/embedded/wp-embedded-graph.component.ts
+++ b/frontend/src/app/shared/components/work-package-graphs/embedded/wp-embedded-graph.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input, SimpleChanges, OnChanges } from '@angular/core';
+import { ChangeDetectionStrategy, Component, Input, SimpleChanges, OnChanges } from '@angular/core';
import { WorkPackageTableConfiguration } from 'core-app/features/work-packages/components/wp-table/wp-table-configuration';
import { ChartOptions } from 'chart.js';
import { I18nService } from 'core-app/core/i18n/i18n.service';
@@ -28,7 +28,11 @@ interface ChartDataSet {
],
providers: [
provideCharts(withDefaultRegisterables(ChartDataLabels, PrimerColorsPlugin)),
- ]
+ ],
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class WorkPackageEmbeddedGraphComponent implements OnChanges {
@Input() public datasets:WorkPackageEmbeddedGraphDataset[];
diff --git a/frontend/src/app/spot/components/form-field/form-field.component.ts b/frontend/src/app/spot/components/form-field/form-field.component.ts
index 2838db2180b..03bbd08d373 100644
--- a/frontend/src/app/spot/components/form-field/form-field.component.ts
+++ b/frontend/src/app/spot/components/form-field/form-field.component.ts
@@ -1,14 +1,17 @@
import {
- Component, ContentChild, HostBinding, Input, Optional,
+ ChangeDetectionStrategy, Component, ContentChild, HostBinding, Input, Optional,
} from '@angular/core';
import { AbstractControl, FormGroupDirective, NgControl } from '@angular/forms';
import { I18nService } from 'core-app/core/i18n/i18n.service';
-/* eslint-disable-next-line change-detection-strategy/on-push */
@Component({
selector: 'spot-form-field',
templateUrl: './form-field.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class SpotFormFieldComponent {
@HostBinding('class.spot-form-field') className = true;
diff --git a/frontend/src/app/spot/components/selector-field/selector-field.component.ts b/frontend/src/app/spot/components/selector-field/selector-field.component.ts
index e0ae36b12e3..4c5346ebd2b 100644
--- a/frontend/src/app/spot/components/selector-field/selector-field.component.ts
+++ b/frontend/src/app/spot/components/selector-field/selector-field.component.ts
@@ -1,4 +1,5 @@
import {
+ ChangeDetectionStrategy,
Component,
ContentChild,
HostBinding,
@@ -15,6 +16,10 @@ import {
selector: 'spot-selector-field',
templateUrl: './selector-field.component.html',
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class SpotSelectorFieldComponent {
@HostBinding('class.spot-form-field') className = true;
diff --git a/frontend/src/app/spot/components/text-field/text-field.component.ts b/frontend/src/app/spot/components/text-field/text-field.component.ts
index 42f81f70f04..1b28eb903f2 100644
--- a/frontend/src/app/spot/components/text-field/text-field.component.ts
+++ b/frontend/src/app/spot/components/text-field/text-field.component.ts
@@ -1,14 +1,15 @@
import {
+ ChangeDetectionStrategy,
+ ChangeDetectorRef,
Component,
ElementRef,
- ViewChild,
- forwardRef,
+ EventEmitter,
HostBinding,
HostListener,
Input,
Output,
- EventEmitter,
- ChangeDetectorRef,
+ ViewChild,
+ forwardRef,
} from '@angular/core';
import {
ControlValueAccessor,
@@ -24,6 +25,10 @@ import {
multi: true,
}],
standalone: false,
+ // TODO: This component has been partially migrated to be zoneless-compatible.
+ // After testing, this should be updated to ChangeDetectionStrategy.OnPush.
+ // eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection
+ changeDetection: ChangeDetectionStrategy.Default,
})
export class SpotTextFieldComponent implements ControlValueAccessor {
@HostBinding('class.spot-text-field') public className = true;
@@ -100,11 +105,13 @@ export class SpotTextFieldComponent implements ControlValueAccessor {
onInputFocus(event:FocusEvent):void {
this.focused = true;
+ this.cdRef.markForCheck();
this.inputFocus.next(event);
}
onInputBlur(event:FocusEvent):void {
this.focused = false;
+ this.cdRef.markForCheck();
this.inputBlur.next(event);
}
diff --git a/frontend/src/assets/sass/backlogs/_dialogues.sass b/frontend/src/assets/sass/backlogs/_dialogues.sass
deleted file mode 100644
index 4d05872a31c..00000000000
--- a/frontend/src/assets/sass/backlogs/_dialogues.sass
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Hide the close button since we do no longer include the necessary image for the close icon
-.controller-rb_master_backlogs,
-.controller-rb_taskboards
- .ui-dialog-titlebar-close
- display: none
-
- .ui-dialog
- background: var(--body-background)
- border: 1px solid var(--borderColor-default)
diff --git a/frontend/src/assets/sass/backlogs/_global.css b/frontend/src/assets/sass/backlogs/_global.css
deleted file mode 100644
index 5e3cc7d66ba..00000000000
--- a/frontend/src/assets/sass/backlogs/_global.css
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-- copyright
-OpenProject Backlogs Plugin
-
-Copyright (C) the OpenProject GmbH
-Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda
-Copyright (C)2010-2011 friflaj
-Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns
-Copyright (C)2009-2010 Mark Maglana
-Copyright (C)2009 Joe Heck, Nate Lowrie
-
-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 Backlogs is a derivative work based on ChiliProject Backlogs.
-The copyright follows:
-Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj
-Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany
-
-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.
-
-++*/
-
-#rb .meta {
- display:none;
-}
-#rb #helpers {
- display:none;
-}
-/*
- .editor is the classname for field editors of sprint,
- story, task, impediment. These field editors get created
- at runtime whenever any of the above models are edited.
-*/
-#rb .editors {
- display:none;
-}
-#rb .ui-dialog .editor {
- display:block;
-}
-
-/* dialog */
-.ui-dialog .ui-dialog-title { float:left; margin-right:0; }
-.ui-dialog.ui-widget-content { border:none; }
-.ui-dialog .ui-dialog-buttonpane.ui-widget-content { border:none; }
-
-.subject-input {
- width: 99%;
-}
-
-th {
- font-weight: var(--base-text-weight-bold);
-}
diff --git a/frontend/src/assets/sass/backlogs/_global_print.css b/frontend/src/assets/sass/backlogs/_global_print.css
deleted file mode 100644
index 20931d7bd72..00000000000
--- a/frontend/src/assets/sass/backlogs/_global_print.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/*-- copyright
-OpenProject Backlogs Plugin
-
-Copyright (C) the OpenProject GmbH
-Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda
-Copyright (C)2010-2011 friflaj
-Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns
-Copyright (C)2009-2010 Mark Maglana
-Copyright (C)2009 Joe Heck, Nate Lowrie
-
-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 Backlogs is a derivative work based on ChiliProject Backlogs.
-The copyright follows:
-Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj
-Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany
-
-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.
-
-++*/
-
-#toolbar .links{
- display:none !important;
-}
diff --git a/frontend/src/assets/sass/backlogs/_index.sass b/frontend/src/assets/sass/backlogs/_index.sass
index af0bd069623..bfd07ffb393 100644
--- a/frontend/src/assets/sass/backlogs/_index.sass
+++ b/frontend/src/assets/sass/backlogs/_index.sass
@@ -39,10 +39,4 @@
@import "../../../global_styles/openproject/_variables.sass"
@import "../../../global_styles/openproject/_mixins.sass"
-@import global
-@import global_print
-@import jqplot
-@import statistics
@import master_backlog
-@import taskboard
-@import dialogues
diff --git a/frontend/src/assets/sass/backlogs/_jqplot.css b/frontend/src/assets/sass/backlogs/_jqplot.css
deleted file mode 100644
index d9467564c3a..00000000000
--- a/frontend/src/assets/sass/backlogs/_jqplot.css
+++ /dev/null
@@ -1,185 +0,0 @@
-/*-- copyright
-OpenProject Backlogs Plugin
-
-Copyright (C) the OpenProject GmbH
-Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda
-Copyright (C)2010-2011 friflaj
-Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns
-Copyright (C)2009-2010 Mark Maglana
-Copyright (C)2009 Joe Heck, Nate Lowrie
-
-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 Backlogs is a derivative work based on ChiliProject Backlogs.
-The copyright follows:
-Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj
-Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany
-
-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.
-
-++*/
-
-.jqplot-target {
- position: relative;
- color: #666;
- font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
- font-size: 1em;
-}
-
-.jqplot-axis {
- font-size: .75em;
-}
-
-.jqplot-xaxis {
- margin-top: 10px;
-}
-
-.jqplot-x2axis {
- margin-bottom: 10px;
-}
-
-.jqplot-yaxis {
- margin-right: 10px;
-}
-
-.jqplot-y2axis, .jqplot-y3axis, .jqplot-y4axis, .jqplot-y5axis, .jqplot-y6axis, .jqplot-y7axis, .jqplot-y8axis, .jqplot-y9axis {
- margin-left: 10px;
- margin-right: 10px;
-}
-
-.jqplot-axis-tick, .jqplot-xaxis-tick, .jqplot-yaxis-tick, .jqplot-x2axis-tick, .jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
- position: absolute;
-}
-
-.jqplot-xaxis-tick {
- top: 0;
- left: 15px;
- vertical-align: top;
-}
-
-.jqplot-x2axis-tick {
- bottom: 0;
- left: 15px;
- vertical-align: bottom;
-}
-
-.jqplot-yaxis-tick {
- right: 0;
- top: 15px;
- text-align: right;
-}
-
-.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
- left: 0;
- top: 15px;
- text-align: left;
-}
-
-.jqplot-xaxis-label {
- margin-top: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-x2axis-label {
- margin-bottom: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-yaxis-label {
- margin-right: 10px;
- font-size: 11pt;
- position: absolute;
-}
-
-.jqplot-y2axis-label, .jqplot-y3axis-label, .jqplot-y4axis-label, .jqplot-y5axis-label, .jqplot-y6axis-label, .jqplot-y7axis-label, .jqplot-y8axis-label, .jqplot-y9axis-label {
- font-size: 11pt;
- position: absolute;
-}
-
-table.jqplot-table-legend, table.jqplot-cursor-legend {
- background-color: rgba(255, 255, 255, 0.6);
- border: 1px solid #ccc;
- position: absolute;
- font-size: .75em;
-}
-
-td.jqplot-table-legend {
- vertical-align: middle;
-}
-
-td.jqplot-table-legend > div {
- border: 1px solid #ccc;
- padding: .2em;
-}
-
-div.jqplot-table-legend-swatch {
- width: 0;
- height: 0;
- border-top-width: .35em;
- border-bottom-width: .35em;
- border-left-width: .6em;
- border-right-width: .6em;
- border-top-style: solid;
- border-bottom-style: solid;
- border-left-style: solid;
- border-right-style: solid;
-}
-
-.jqplot-title {
- top: 0;
- left: 0;
- padding-bottom: .5em;
- font-size: 1.2em;
-}
-
-table.jqplot-cursor-tooltip {
- border: 1px solid #ccc;
- font-size: .75em;
-}
-
-.jqplot-cursor-tooltip {
- border: 1px solid #ccc;
- font-size: .75em;
- white-space: nowrap;
- background: rgba(208, 208, 208, 0.5);
- padding: 1px;
-}
-
-.jqplot-highlighter-tooltip {
- border: 1px solid #ccc;
- font-size: .75em;
- white-space: nowrap;
- background: rgba(208, 208, 208, 0.5);
- padding: 1px;
-}
-
-.jqplot-point-label {
- font-size: .75em;
-}
-
-td.jqplot-cursor-legend-swatch {
- vertical-align: middle;
- text-align: center;
-}
-
-div.jqplot-cursor-legend-swatch {
- width: 1.2em;
- height: .7em;
-}
diff --git a/frontend/src/assets/sass/backlogs/_master_backlog.sass b/frontend/src/assets/sass/backlogs/_master_backlog.sass
index 62b6a0a15b3..6df37ec24e3 100644
--- a/frontend/src/assets/sass/backlogs/_master_backlog.sass
+++ b/frontend/src/assets/sass/backlogs/_master_backlog.sass
@@ -32,21 +32,38 @@ $op-backlogs-header--points-min-width-narrow: 2rem
.action-sprint_planning
@include extended-content--bottom
-.op-backlogs-header
+.op-backlogs-header,
+.op-sprint-header
display: grid
grid-template-columns: 1fr minmax($op-backlogs-header--points-min-width, max-content) auto
- grid-template-areas: "collapsible points menu"
align-items: center
-.op-backlogs-header--collapsible
- margin-left: calc(var(--stack-padding-normal) / 2)
+ &--collapsible
+ margin-left: calc(var(--stack-padding-normal) / 2)
-.op-backlogs-header--points
- margin-left: var(--stack-gap-normal)
- font-variant-numeric: tabular-nums
+ &--actions
+ margin-left: var(--stack-gap-normal)
+
+ &--menu
+ margin-left: var(--stack-gap-normal)
+
+.op-backlogs-header
+ grid-template-areas: "collapsible points menu"
+
+ &--points
+ margin-left: var(--stack-gap-normal)
+ font-variant-numeric: tabular-nums
+
+.op-sprint-header
+ grid-template-areas: "collapsible actions menu"
+
+ &--actions,
+ &--menu
+ margin-left: var(--stack-gap-normal)
+ align-self: flex-start
+ // Unfortunately, the invisible button style bites us here again.
+ margin-top: -6px
-.op-backlogs-header--menu
- margin-left: var(--stack-gap-normal)
.op-backlogs-story
display: grid
diff --git a/frontend/src/assets/sass/backlogs/_statistics.css b/frontend/src/assets/sass/backlogs/_statistics.css
deleted file mode 100644
index de64988edaf..00000000000
--- a/frontend/src/assets/sass/backlogs/_statistics.css
+++ /dev/null
@@ -1,48 +0,0 @@
-/*-- copyright
-OpenProject Backlogs Plugin
-
-Copyright (C) the OpenProject GmbH
-Copyright (C)2011 Stephan Eckardt, Tim Felgentreff, Marnen Laibow-Koser, Sandro Munda
-Copyright (C)2010-2011 friflaj
-Copyright (C)2010 Maxime Guilbot, Andrew Vit, Joakim Kolsjö, ibussieres, Daniel Passos, Jason Vasquez, jpic, Emiliano Heyns
-Copyright (C)2009-2010 Mark Maglana
-Copyright (C)2009 Joe Heck, Nate Lowrie
-
-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 Backlogs is a derivative work based on ChiliProject Backlogs.
-The copyright follows:
-Copyright (C) 2010-2011 - Emiliano Heyns, Mark Maglana, friflaj
-Copyright (C) 2011 - Jens Ulferts, Gregor Schmidt - Finn GmbH - Berlin, Germany
-
-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.
-
-++*/
-
-.score { text-align: center; width: 1.5em; font-size: large; display: inline-block; }
-.score_0 { background-color: #FF0000; }
-.score_1 { background-color: #FF5300; }
-.score_2 { background-color: #FF8100; }
-.score_3 { background-color: #FFA100; }
-.score_4 { background-color: #FFBB00; }
-.score_5 { background-color: #FFD300; }
-.score_6 { background-color: #FFEC00; }
-.score_7 { background-color: #E9FB00; }
-.score_8 { background-color: #B1F100; }
-.score_9 { background-color: #74E600; }
-.score_10 { background-color: #00CC00; }
diff --git a/frontend/src/assets/sass/backlogs/_taskboard.sass b/frontend/src/assets/sass/backlogs/_taskboard.sass
deleted file mode 100644
index 733973ed520..00000000000
--- a/frontend/src/assets/sass/backlogs/_taskboard.sass
+++ /dev/null
@@ -1,329 +0,0 @@
-/*-- copyright
- * OpenProject is an open source project management software.
- * Copyright (C) the OpenProject GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 3.
- *
- * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
- * Copyright (C) 2006-2013 Jean-Philippe Lang
- * Copyright (C) 2010-2013 the ChiliProject Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * See COPYRIGHT and LICENSE files for more details. ++
- */
-
-@mixin story-header
- background-color: #FFFFFF
- font-size: 1rem - rem-calc(5px)
- opacity: 0.8
- filter: alpha(opacity = 80)
- overflow: hidden
- padding-bottom: 1px
- padding-right: 3px
-
-@mixin story-footer
- float: left
- font-size: 1rem - rem-calc(5px)
- width: 85%
- margin-top: 4px
- padding: 2px
- padding-top: 0
-
-@mixin ellipsis
- overflow: hidden
- white-space: nowrap
- text-overflow: ellipsis
-
-#rb .task
- color: #484848
- line-height: inherit
- white-space: inherit
-
-#rb #taskboard
- overflow-x: auto
- #assigned_to_id_options
- display: none
- .swimlane
- min-width: 107px
- /* width + (2*margin) + (2*padding) of .work_package + (2*border) of cell */
- padding: 5px
- width: 107px
- /* Must be the same as min-width */
- #board_header
- background-color: var(--body-background)
- color: var(--body-font-color)
- border: 1px solid var(--borderColor-default)
- margin-bottom: 0
- margin-right: 10px
- td
- border-right: 1px dotted var(--borderColor-default)
- font-weight: var(--base-text-weight-bold)
- text-align: center
- vertical-align: middle
- padding-top: 0
- padding-bottom: 0
- line-height: 30px
- &:first-child
- min-width: 241px
- width: 241px
-
- .board
- background-color: var(--overlay-bgColor)
- border: 1px solid var(--borderColor-default)
- border-top: none
- margin-right: 10px
- /* IE7 table fix */
- table-layout: fixed
- border-collapse: collapse
- empty-cells: show
- tr:hover
- background-color: var(--control-transparent-bgColor-hover)
- td
- border-right: 1px dotted #CFCFCF
- border-bottom: 1px dotted #CFCFCF
- vertical-align: top
- &:first-child
- min-width: 210px
- padding: 5px
- width: 210px
- tr:last-child td
- border-bottom: none
- .add_new
- margin: 0
- min-width: 30px
- padding: 0
- text-align: center
- vertical-align: middle
- width: 30px
- &.clickable:hover
- cursor: pointer
- background-color: var(--highlight-neutral-bgColor)
- .story, .label_sprint_impediments
- background-color: var(--display-lemon-bgColor-muted)
- color: var(--fgColor-muted)
- border: none
- display: block
- min-height: 100px
- margin: 5px
- padding: 5px
- position: relative
- width: 190px
- .story
- .subject
- height: 42px
- line-height: 13px
- margin-top: 0
- overflow: hidden
- padding: 2px
- width: 180px
- &.closed .subject
- text-decoration: line-through
- .work_package, .placeholder
- background-color: #AFAFAF
- color: var(--color-ansi-black)
- border: none
- cursor: move
- display: block
- font-size: 10px
- height: 85px
- padding: 5px
- margin: 5px 0px
- position: relative
- width: 85px
- .work_package.prevent_edit
- cursor: default
- .placeholder
- background-color: #FFFF00
- border: 1px dashed #333300
- height: 78px
- width: 83px
- .work_package
- &.closed .subject.editable
- text-decoration: line-through
- .v
- display: none
- .remaining_hours.editable
- border: 2px solid #FFFFFF
- background-color: #EE0000
- bottom: -5px
- color: #FFFFFF
- font-size: 9px
- height: 18px
- padding-left: 5px
- padding-right: 5px
- position: absolute
- right: -5px
- .blocks, .remaining_hours.editable.empty
- display: none
- .indicator
- display: none
-
- &.error .indicator
- background: none
- border: none
-
- &.error.icon-bug:before
- position: absolute
- top: 30px
- left: 28px
- color: red
-
-
- .editors
- display: none
-
-/*
- * swimlane class is used by:
- * - #board_header
- * - .board
- *
- * Also use by the Column Width preference to determine the unit width of the
- * swimlanes. See RB.Taskboard.initialize()
-
-/* status labels */
-
-/* shared #impediments and #tasks */
-
-/* item styles used by .task and .impediment */
-
-/* dialog */
-
-.task_editor_dialog.ui-dialog
- .ui-widget-header
- background-color: var(--bgColor-muted)
- filter: alpha(opacity = 50)
- .ui-dialog-title
- float: right
- margin-right: 0
- color: var(--body-font-color)
- &.ui-widget-content
- background: none
- border: none
- .ui-dialog-buttonpane.ui-widget-content
- background: none
- background-color: none
- border: none
-
-.dark
- #task_editor label, .subject, .assigned_to_id, div
- color: #FFFFFF
- option
- color: var(--body-font-color)
-
-.light
- #task_editor label, .subject, .assigned_to_id, div
- color: var(--body-font-color)
-
-/* item editor */
-
-#task_editor
- label:first-letter
- text-transform: capitalize
- label
- display: block
- font-size: 11px
- width: 100%
- .editor
- font-size: 11px
- margin-bottom: 10px
- width: 100%
- .subject
- height: 65px
- width: 272px
- .remaining_hours, .blocks
- width: 268px
-
-/* compact view */
-
-#rb
- .compact
- .story, .label_sprint_impediments
- height: 15px
- .story .subject
- display: none
- .work_package
- height: 21px
- padding: 0
- width: 21px
- *
- display: none
- .placeholder
- background-color: #FFFF00
- border: 1px dashed #333300
- height: 19px
- width: 19px
- #impediment_template, #task_template
- display: none
-
-/* others */
-
-.story
- .story-bar
- @include story-header
- text-align: right
- width: 180px
- clear: both
- .id
- float: right
- .status
- float: left
-
-.story,
-.label_sprint_impediments
- font-size: 1rem - rem-calc(3px)
-
-.work_package
- .id
- @include story-header
- text-align: right
- width: 75px
- a
- opacity: 1.0
- filter: alpha(opacity = 100)
- .editable:hover
- background-color: transparent
- .subject.editable
- font-size: 1rem - rem-calc(3px)
- height: 42px
- line-height: 13px
- margin-top: 0
- overflow: hidden
- padding: 2px
- width: 81px
-
-.story
- .story-footer
- .assigned_to_id
- @include story-footer
- @include ellipsis
- .story-points
- margin-top: 2px
- float: right
-.work_package
- .assigned_to_id.editable
- @include story-footer
- .t
- @include ellipsis
-
-/* Toolbar modifications (no support for labels form the component) */
-
-#toolbar
- label[for=col_width_input]
- padding-top: rem-calc(20px)
-
- #col_width_input
- max-width: 60px
diff --git a/frontend/src/elements/block-note-element.ts b/frontend/src/elements/block-note-element.ts
index 8ee18f9937a..e9ceb8c65b9 100644
--- a/frontend/src/elements/block-note-element.ts
+++ b/frontend/src/elements/block-note-element.ts
@@ -30,8 +30,6 @@
import { User } from '@blocknote/core/comments';
import { HocuspocusProvider } from '@hocuspocus/provider';
-import { Application } from '@hotwired/stimulus';
-import FlashController from 'core-stimulus/controllers/flash.controller';
import { LiveCollaborationManager } from 'core-stimulus/helpers/live-collaboration-helpers';
import { ShadowDomWrapper } from 'op-blocknote-extensions';
import React from 'react';
@@ -40,42 +38,32 @@ import { createRoot } from 'react-dom/client';
import OpBlockNoteContainer from '../react/OpBlockNoteContainer';
class BlockNoteElement extends HTMLElement {
- private stimulusRoot:HTMLDivElement;
+ private editorRoot:HTMLDivElement;
private editorMount:HTMLDivElement;
- private errorContainer:HTMLDivElement;
private reactRoot:Root|null = null;
- private stimulusApp:Application|null = null;
- private renderCallback:((provider?:HocuspocusProvider) => void) | null = null;
+ private renderCallback:((provider:HocuspocusProvider) => void) | null = null;
constructor() {
super();
const shadowRoot = this.attachShadow({ mode: 'open' });
- // Wrapper div as Stimulus root so both errorContainer and editorMount are in scope
- this.stimulusRoot = document.createElement('div');
+ this.editorRoot = document.createElement('div');
const browserSpecificClasses = this.getAttribute('browser-specific-classes')?.split(' ') ?? [];
if (browserSpecificClasses.length > 0) {
- this.stimulusRoot.classList.add(...browserSpecificClasses);
+ this.editorRoot.classList.add(...browserSpecificClasses);
}
// Clone the blank-target link description into the shadow DOM
// so aria-describedby references resolve for links inside the editor
const blankLinkDesc = document.getElementById('open-blank-target-link-description');
if (blankLinkDesc) {
- this.stimulusRoot.appendChild(blankLinkDesc.cloneNode(true));
+ this.editorRoot.appendChild(blankLinkDesc.cloneNode(true));
}
- // Container for connection error/recovery messages (rendered by React via fetchConnectionTemplate)
- this.errorContainer = document.createElement('div');
- this.errorContainer.id = 'documents-show-edit-view-connection-error-notice-component';
- this.errorContainer.dataset.controller = 'flash';
- this.errorContainer.dataset.flashAutohideValue = 'true';
-
this.editorMount = document.createElement('div');
- this.stimulusRoot.appendChild(this.errorContainer);
- this.stimulusRoot.appendChild(this.editorMount);
- shadowRoot.appendChild(this.stimulusRoot);
+ this.editorRoot.appendChild(this.editorMount);
+ shadowRoot.appendChild(this.editorRoot);
const blockNoteStylesheetUrl = this.getAttribute('blocknote-stylesheet-url');
if (blockNoteStylesheetUrl) {
@@ -95,26 +83,18 @@ class BlockNoteElement extends HTMLElement {
}
connectedCallback() {
- // Initialize Stimulus application within shadow DOM
- this.stimulusApp = Application.start(this.stimulusRoot);
- this.stimulusApp.register('flash', FlashController);
+ const collaborationEnabled = this.getAttribute('collaboration-enabled') === 'true';
+ if (!collaborationEnabled) return;
- // Initialize React application within shadow DOM
this.reactRoot = createRoot(this.editorMount);
- const collaborationEnabled = this.getAttribute('collaboration-enabled') === 'true';
-
- this.renderCallback = (provider?:HocuspocusProvider) => {
+ this.renderCallback = (provider:HocuspocusProvider) => {
this.reactRoot?.render(
React.createElement(React.StrictMode, null, this.BlockNoteReactContainer(provider))
);
};
- if (collaborationEnabled) {
- LiveCollaborationManager.onReady(this.renderCallback);
- } else {
- this.renderCallback();
- }
+ LiveCollaborationManager.onReady(this.renderCallback);
}
disconnectedCallback() {
@@ -128,28 +108,21 @@ class BlockNoteElement extends HTMLElement {
this.reactRoot.unmount();
this.reactRoot = null;
}
-
- if (this.stimulusApp) {
- this.stimulusApp.stop();
- this.stimulusApp = null;
- }
}
- private BlockNoteReactContainer = (hocuspocusProvider?:HocuspocusProvider) => {
+ private BlockNoteReactContainer = (hocuspocusProvider:HocuspocusProvider) => {
return React.createElement(
ShadowDomWrapper,
{ target: this.editorMount },
React.createElement(
OpBlockNoteContainer,
{
- inputField: document.createElement('input'),
activeUser: this.parseActiveUser()!,
readOnly: this.getAttribute('read-only') === 'true',
openProjectUrl: this.getAttribute('open-project-url') ?? '',
attachmentsUploadUrl: this.getAttribute('attachments-upload-url') ?? '',
attachmentsCollectionKey: this.getAttribute('attachments-collection-key') ?? '',
- hocuspocusProvider: hocuspocusProvider,
- errorContainer: this.errorContainer,
+ hocuspocusProvider,
}
)
);
@@ -167,7 +140,6 @@ class BlockNoteElement extends HTMLElement {
}
return null;
}
-
}
if (!customElements.get('op-block-note')) {
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/work_package.ts b/frontend/src/global_styles/content/_admin_groups_tree_layout.sass
similarity index 66%
rename from frontend/src/stimulus/controllers/dynamic/backlogs/work_package.ts
rename to frontend/src/global_styles/content/_admin_groups_tree_layout.sass
index f10d3b67a65..4cdd17399ac 100644
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/work_package.ts
+++ b/frontend/src/global_styles/content/_admin_groups_tree_layout.sass
@@ -25,33 +25,19 @@
//
// See COPYRIGHT and LICENSE files for more details.
//++
+@import ../openproject/mixins
-/**************************************
- WORK PACKAGE
-***************************************/
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.WorkPackage = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.Model, {
+body:has(.admin-groups-tree-page)
+ @include extended-content--bottom
+ #content-body
+ display: flex
+ flex-direction: column
- initialize(el:any) {
- this.$ = $(el);
- this.el = el;
- },
+.admin-groups-tree-page
+ &--sidebar
+ border-top-left-radius: var(--borderRadius-medium)
+ border-top-right-radius: var(--borderRadius-medium)
- beforeSaveDragResult() {
- // Do nothing
- },
-
- getType() {
- return 'WorkPackage';
- },
-
- saveDragResult() {
- this.beforeSaveDragResult();
- if (!this.$.hasClass('editing')) {
- this.saveEdits();
- }
- },
- });
-}(jQuery));
+ &--wrapper
+ height: 100%
+ overflow: hidden
diff --git a/frontend/src/global_styles/content/_hover_cards.sass b/frontend/src/global_styles/content/_hover_cards.sass
index f381e94fd02..6487295d793 100644
--- a/frontend/src/global_styles/content/_hover_cards.sass
+++ b/frontend/src/global_styles/content/_hover_cards.sass
@@ -52,6 +52,3 @@
&:popover-open
opacity: 1
-
- &--hidden-container
- display: none
diff --git a/frontend/src/global_styles/content/_index.sass b/frontend/src/global_styles/content/_index.sass
index 92e77dd3b79..5d7931874d8 100644
--- a/frontend/src/global_styles/content/_index.sass
+++ b/frontend/src/global_styles/content/_index.sass
@@ -76,6 +76,7 @@
@import activity_list
@import activity_days
@import hierachy_custom_field_layout
+@import admin_groups_tree_layout
@import text_utils
@import menus/menu_blocks
diff --git a/frontend/src/global_styles/openproject.sass b/frontend/src/global_styles/openproject.sass
index 826e78810c4..2e2eeea80ab 100644
--- a/frontend/src/global_styles/openproject.sass
+++ b/frontend/src/global_styles/openproject.sass
@@ -28,6 +28,7 @@
@import "../../../modules/meeting/app/components/_index.sass"
@import "../../../modules/overviews/app/components/_index.sass"
@import "../../../modules/storages/app/components/_index.sass"
+@import "../../../modules/wikis/app/components/_index.sass"
// Component specific Styles
@import "../../../app/components/_index.sass"
diff --git a/frontend/src/global_styles/openproject/_mixins.sass b/frontend/src/global_styles/openproject/_mixins.sass
index 35c929d6139..8d088d8e981 100644
--- a/frontend/src/global_styles/openproject/_mixins.sass
+++ b/frontend/src/global_styles/openproject/_mixins.sass
@@ -275,18 +275,14 @@ $scrollbar-size: 10px
@mixin macro--text-style
@media screen
display: inline
- background: rgba(218,223,225,0.19)
+ background: var(--bgColor-muted)
border: 1px solid transparent
+ border-radius: var(--borderRadius-medium)
padding: 2px
&:has(.-multiline)
display: inline-flex
- &:hover
- cursor: default
- border-color: var(--fgColor-muted)
- background: rgba(218,223,225,0.75)
-
@mixin unset-button-styles
padding: 0
margin: 0
diff --git a/frontend/src/global_styles/primer/_overrides.sass b/frontend/src/global_styles/primer/_overrides.sass
index 0446465a5cd..b7d2c98e92d 100644
--- a/frontend/src/global_styles/primer/_overrides.sass
+++ b/frontend/src/global_styles/primer/_overrides.sass
@@ -75,6 +75,9 @@ ul.SegmentedControl,
&-body_autocomplete_height
min-height: 320px
+ &-body_autocomplete_height--lg
+ min-height: 480px
+
&--size-xlarge-maximized-empty-footer
min-height: 534px
diff --git a/frontend/src/main.ts b/frontend/src/main.ts
index d15f24fb937..30459af0604 100644
--- a/frontend/src/main.ts
+++ b/frontend/src/main.ts
@@ -1,5 +1,5 @@
import { OpenProjectModule } from 'core-app/app.module';
-import { enableProdMode, provideZoneChangeDetection } from '@angular/core';
+import { enableProdMode, provideZonelessChangeDetection } from '@angular/core';
import 'core-app/core/setup/init-jquery';
import 'core-app/core/setup/init-js-patches';
@@ -46,5 +46,5 @@ void initializeLocale()
initializeGlobalListeners();
// Due to the behaviour of the Edge browser we need to wait for 'DOM ready'
- void platformBrowser().bootstrapModule(OpenProjectModule, { applicationProviders: [provideZoneChangeDetection()], });
+ void platformBrowser().bootstrapModule(OpenProjectModule, { applicationProviders: [provideZonelessChangeDetection()], });
});
diff --git a/frontend/src/polyfills.ts b/frontend/src/polyfills.ts
index 71c224c339b..8bfe64db969 100644
--- a/frontend/src/polyfills.ts
+++ b/frontend/src/polyfills.ts
@@ -1,54 +1,3 @@
-/**
- * This file includes polyfills needed by Angular and is loaded before the app.
- * You can add your own extra polyfills to this file.
- *
- * This file is divided into 2 sections:
- * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
- * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
- * file.
- *
- * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
- * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
- * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
- *
- * Learn more in https://angular.io/guide/browser-support
- */
-
-/** *************************************************************************************************
-* BROWSER POLYFILLS
-*/
-
// Ensure global is set for ng2-dragula and others
-// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access no-explicit-any
+// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
(window as any).global = window;
-
-/*
- * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
- * with the following flag, it will bypass `zone.js` patch for IE/Edge
- */
-// (window as any).__Zone_enable_cross_context_check = true;
-
-/** *************************************************************************************************
- * Zone JS is required by default for Angular itself.
- */
-import 'zone.js';
-
-/** IE10 and IE11 requires the following for the Reflect API. */
-// import 'core-js/es6/reflect';
-
-/** Evergreen browsers require these. * */
-// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
-// import 'core-js/es7/reflect';
-
-/**
- * By default, zone.js will patch all possible macroTask and DomEvents
- * user can disable parts of macroTask/DomEvents patch by setting following flags
- */
-
-// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
-// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
-(window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove', 'mouseover', 'mouseout', 'mousewheel']; // Included with Angular CLI.
-
-/** *************************************************************************************************
- * APPLICATION IMPORTS
- */
diff --git a/frontend/src/react/OpBlockNoteContainer.tsx b/frontend/src/react/OpBlockNoteContainer.tsx
index 3da7c64d167..c4b42cf5931 100644
--- a/frontend/src/react/OpBlockNoteContainer.tsx
+++ b/frontend/src/react/OpBlockNoteContainer.tsx
@@ -34,69 +34,46 @@ import { useEffect, useRef } from 'react';
import * as Y from 'yjs';
import { DocumentLoadingSkeleton } from './components/DocumentLoadingSkeleton';
import { OpBlockNoteEditor } from './components/OpBlockNoteEditor';
-import { fetchConnectionTemplate } from './helpers/connection-template-fetcher';
import { useCollaboration } from './hooks/useCollaboration';
export interface OpBlockNoteContainerProps {
- inputField:HTMLInputElement;
- inputText?:string;
activeUser:User;
readOnly:boolean;
openProjectUrl:string;
attachmentsUploadUrl:string;
attachmentsCollectionKey:string;
- hocuspocusProvider?:HocuspocusProvider;
- errorContainer?:HTMLElement;
+ hocuspocusProvider:HocuspocusProvider;
}
-export default function OpBlockNoteContainer({ inputField,
- inputText,
- activeUser,
- readOnly,
- openProjectUrl,
- attachmentsUploadUrl,
- attachmentsCollectionKey,
- hocuspocusProvider,
- errorContainer }:OpBlockNoteContainerProps) {
- const doc:Y.Doc = hocuspocusProvider
- ? hocuspocusProvider.document
- : (() => {
- // NOTE: This should only be used in TEST environments where there is no provider.
- const newDoc = new Y.Doc();
- if (inputText) {
- try {
- const update = Uint8Array.from(atob(inputText), c => c.charCodeAt(0));
- Y.applyUpdate(newDoc, update);
- } catch (e) {
- console.error('Failed to load document binary', e);
- return new Y.Doc();
- }
- }
- return newDoc;
- })();
-
- const { isLoading, connectionError } = useCollaboration(hocuspocusProvider, doc, inputField);
+export default function OpBlockNoteContainer({
+ activeUser,
+ readOnly,
+ openProjectUrl,
+ attachmentsUploadUrl,
+ attachmentsCollectionKey,
+ hocuspocusProvider,
+}:OpBlockNoteContainerProps) {
+ const doc:Y.Doc = hocuspocusProvider.document;
+ const { isLoading, offlineMode } = useCollaboration(hocuspocusProvider);
const hadErrorRef = useRef(false);
- // Fetch error/recovery template based on connection state
useEffect(() => {
- if (!errorContainer) return;
-
- if (connectionError) {
+ if (offlineMode) {
hadErrorRef.current = true;
- void fetchConnectionTemplate('error', errorContainer);
+ window.dispatchEvent(new CustomEvent('documents:connection-error'));
} else if (hadErrorRef.current) {
- // Only fetch recovery if we previously had an error (avoid fetching on initial render)
- void fetchConnectionTemplate('recovery', errorContainer);
+ window.dispatchEvent(new CustomEvent('documents:connection-recovery'));
}
- }, [connectionError, errorContainer]);
+ }, [offlineMode]);
if (isLoading) {
return ;
}
- if (connectionError) {
- // Error UI is rendered in errorContainer via fetchConnectionTemplate (outside React tree)
+ // Without IndexedDB offline persistence, all offline is blocking — hide the
+ // editor entirely to prevent a fresh empty Y.Doc from being synced as
+ // authoritative server state on reconnect.
+ if (offlineMode) {
return null;
}
@@ -112,4 +89,3 @@ export default function OpBlockNoteContainer({ inputField,
/>
);
}
-
diff --git a/frontend/src/react/helpers/connection-template-fetcher.ts b/frontend/src/react/helpers/connection-template-fetcher.ts
deleted file mode 100644
index 090bc6df265..00000000000
--- a/frontend/src/react/helpers/connection-template-fetcher.ts
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * -- copyright
- * OpenProject is an open source project management software.
- * Copyright (C) the OpenProject GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 3.
- *
- * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
- * Copyright (C) 2006-2013 Jean-Philippe Lang
- * Copyright (C) 2010-2013 the ChiliProject Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * See COPYRIGHT and LICENSE files for more details.
- * ++
- */
-
-/**
- * Fetches connection error/recovery templates from the server.
- * Used by the BlockNote editor to display server-rendered error messages
- * when the collaboration connection fails.
- */
-
-function getDocumentIdFromUrl():string|null {
- const match = /\/documents\/(\d+)/.exec(window.location.pathname);
- return match ? match[1] : null;
-}
-
-/**
- * Parses Turbo Stream response and extracts the template content.
- * Standard Turbo.renderStreamMessage() uses document.getElementById()
- * which can't find Shadow DOM elements, so we parse manually.
- */
-function parseTurboStreamContent(html:string):string|null {
- const parser = new DOMParser();
- const doc = parser.parseFromString(html, 'text/html');
- const turboStream = doc.querySelector('turbo-stream');
-
- if (!turboStream) {
- console.error('No turbo-stream element found in response');
- return null;
- }
-
- const template = turboStream.querySelector('template');
- if (!template) {
- console.error('No template element found in turbo-stream');
- return null;
- }
-
- return template.innerHTML;
-}
-
-export async function fetchConnectionTemplate(
- type:'error'|'recovery',
- targetElement:HTMLElement,
-):Promise {
- const documentId = getDocumentIdFromUrl();
- if (!documentId) {
- console.error('Could not extract document ID from URL');
- return;
- }
-
- const url = `/documents/${documentId}/render_connection_${type}`;
-
- try {
- const response = await fetch(url, {
- method: 'GET',
- headers: {
- Accept: 'text/vnd.turbo-stream.html',
- },
- });
-
- if (!response.ok) {
- throw new Error(`Failed to fetch ${url}: ${response.status}`);
- }
-
- const html = await response.text();
- const content = parseTurboStreamContent(html);
-
- if (content !== null) {
- targetElement.innerHTML = content;
-
- // Attach reload handler to the error button (Stimulus not available in Shadow DOM)
- const reloadButton = targetElement.querySelector('#connection-error-reload-button');
- if (reloadButton) {
- reloadButton.addEventListener('click', () => window.location.reload());
- }
- }
- } catch (error) {
- console.error('Error fetching connection template:', error);
- }
-}
diff --git a/frontend/src/react/hooks/useCollaboration.ts b/frontend/src/react/hooks/useCollaboration.ts
index fd7639621e4..a4c16a29eaa 100644
--- a/frontend/src/react/hooks/useCollaboration.ts
+++ b/frontend/src/react/hooks/useCollaboration.ts
@@ -30,55 +30,70 @@
import { HocuspocusProvider } from '@hocuspocus/provider';
import { debugLog } from 'core-app/shared/helpers/debug_output';
-import { PROVIDER_AUTH_ERROR_EVENT, ProviderAuthErrorKind } from 'core-stimulus/services/documents/token-refresh.service';
+import {
+ PROVIDER_AUTH_ERROR_EVENT,
+ ProviderAuthErrorKind,
+} from 'core-stimulus/services/documents/token-refresh.service';
import { useCallback, useEffect, useRef, useState } from 'react';
-import * as Y from 'yjs';
-function useConnectionTimeout(provider:HocuspocusProvider | undefined, timeoutMs = 5000) {
- const [hasTimedOut, setHasTimedOut] = useState(false);
- const timeoutRef = useRef | null>(null);
+/**
+ * Calls `onTimeout` if the provider has not synced within `timeoutMs`.
+ * The timer is cancelled proactively when the provider emits 'synced',
+ * so it never fires after a successful connection.
+ */
+function useConnectionTimeout(provider:HocuspocusProvider, onTimeout:() => void, timeoutMs = 5000) {
+ const timeoutRef = useRef|null>(null);
useEffect(() => {
- setHasTimedOut(false);
- if (!provider) return;
-
if (provider.synced) {
- setHasTimedOut(false);
return;
}
- timeoutRef.current = setTimeout(() => {
- if (!provider.synced) {
- setHasTimedOut(true);
- }
- }, timeoutMs);
-
- return () => {
- if (timeoutRef.current) {
+ const cancel = () => {
+ if (timeoutRef.current !== null) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
- }, [provider, timeoutMs]);
- return hasTimedOut;
+ timeoutRef.current = setTimeout(() => {
+ timeoutRef.current = null;
+ onTimeout();
+ }, timeoutMs);
+
+ // Cancel the timer as soon as the provider syncs rather than waiting
+ // for the full timeout to elapse.
+ provider.on('synced', cancel);
+
+ return () => {
+ provider.off('synced', cancel);
+ cancel();
+ };
+ }, [provider, onTimeout, timeoutMs]);
}
+/**
+ * Subscribes to the provider's 'synced' and 'disconnect' events and
+ * forwards them to the supplied callbacks.
+ *
+ * Listeners are registered before the initial synced check so that a
+ * sync event emitted between registration and the check is never lost.
+ * If the provider is already synced on mount, `onSynced` is called
+ * immediately.
+ */
function useCollaborationProvider(
- provider:HocuspocusProvider | undefined,
+ provider:HocuspocusProvider,
onSynced:() => void,
onDisconnect:() => void,
) {
useEffect(() => {
- if (!provider) return;
+ provider.on('synced', onSynced);
+ provider.on('disconnect', onDisconnect);
if (provider.synced) {
onSynced();
}
- provider.on('synced', onSynced);
- provider.on('disconnect', onDisconnect);
-
return () => {
provider.off('synced', onSynced);
provider.off('disconnect', onDisconnect);
@@ -86,32 +101,43 @@ function useCollaborationProvider(
}, [provider, onSynced, onDisconnect]);
}
-function useLocalDocumentSync(doc:Y.Doc, inputField:HTMLInputElement, enabled:boolean) {
+/**
+ * Listens for PROVIDER_AUTH_ERROR_EVENT on the document and calls `onAuthError` when it fires.
+ * The event is dispatched when authentication fails on the Hocuspocus WebSocket connection.
+ */
+function useProviderAuthError(onAuthError:() => void) {
useEffect(() => {
- if (!enabled) return;
-
- const updateInput = () => {
- const update = Y.encodeStateAsUpdate(doc);
- const b64 = btoa(String.fromCharCode(...update));
- inputField.value = b64;
+ const handler = (event:Event) => {
+ const { kind, message } = (event as CustomEvent<{ kind:ProviderAuthErrorKind; message:string }>).detail;
+ debugLog(`(BlockNote Editor) Provider auth error: ${kind} - ${message}`);
+ onAuthError();
};
- doc.on('update', updateInput);
-
- return () => {
- doc.off('update', updateInput);
- doc.destroy();
- };
- }, [doc, inputField, enabled]);
+ document.addEventListener(PROVIDER_AUTH_ERROR_EVENT, handler);
+ return () => document.removeEventListener(PROVIDER_AUTH_ERROR_EVENT, handler);
+ }, [onAuthError]);
}
-export function useCollaboration(
- provider:HocuspocusProvider | undefined,
- doc:Y.Doc,
- inputField:HTMLInputElement,
-) {
+/**
+ * Tracks the real-time connection state of a HocuspocusProvider and
+ * exposes it as React state for the BlockNote editor.
+ *
+ * Returns:
+ * - `isLoading` — true while waiting for the first sync after mount.
+ * - `offlineMode` — true when the connection is lost or timed out; the editor
+ * is hidden entirely (blocking) because there is no local
+ * cache to edit from.
+ *
+ * Transitions:
+ * mount → synced : isLoading false, offlineMode false
+ * mount → timeout (5s) : isLoading false, offlineMode true
+ * connected → disconnect : offlineMode true (after 5s grace period)
+ * offline → re-synced : offlineMode false
+ * any → auth error : isLoading false, offlineMode true
+ */
+function useCollaboration(provider:HocuspocusProvider) {
const [isLoading, setIsLoading] = useState(true);
- const [connectionError, setConnectionError] = useState(false);
+ const [offlineMode, setOfflineMode] = useState(false);
const disconnectTimerRef = useRef | null>(null);
const clearDisconnectTimer = useCallback(() => {
@@ -125,57 +151,43 @@ export function useCollaboration(
debugLog('(BlockNote Editor) synced with collaboration server');
clearDisconnectTimer();
setIsLoading(false);
- setConnectionError(false);
+ setOfflineMode(false);
}, [clearDisconnectTimer]);
const handleDisconnect = useCallback(() => {
debugLog('(BlockNote Editor) Disconnected — starting grace period');
- // Don't flag a connection error immediately. Start a grace timer so that
- // transient reconnections (idle heartbeat, token-expiry reconnect) never
- // surface to the user. If synced fires within the window the timer is
- // cancelled.
+ setIsLoading(false);
+ // Don't go offline immediately. Start a grace timer so that transient
+ // reconnections (idle heartbeat, token-expiry reconnect) never surface
+ // to the user. If synced fires within the window the timer is cancelled.
disconnectTimerRef.current ??= setTimeout(() => {
disconnectTimerRef.current = null;
- debugLog('(BlockNote Editor) Grace period expired — connection error');
- setConnectionError(true);
+ debugLog('(BlockNote Editor) Grace period expired — offline mode');
+ setOfflineMode(true);
}, 5_000);
}, []);
- const hasTimedOut = useConnectionTimeout(provider);
- useCollaborationProvider(provider, handleSynced, handleDisconnect);
- useLocalDocumentSync(doc, inputField, !provider);
+ const handleTimeout = useCallback(() => {
+ debugLog('(BlockNote Editor) Connection to collaboration server timed out - now in offline mode');
+ setIsLoading(false);
+ setOfflineMode(true);
+ }, []);
+
+ const handleAuthError = useCallback(() => {
+ // Auth errors are permanent — bypass the grace period.
+ clearDisconnectTimer();
+ setOfflineMode(true);
+ setIsLoading(false);
+ }, [clearDisconnectTimer]);
// Clean up the grace timer on unmount and when the provider changes.
useEffect(() => clearDisconnectTimer, [provider, clearDisconnectTimer]);
- useEffect(() => {
- if (!provider) {
- setIsLoading(false);
- }
- }, [provider]);
+ useConnectionTimeout(provider, handleTimeout);
+ useCollaborationProvider(provider, handleSynced, handleDisconnect);
+ useProviderAuthError(handleAuthError);
- useEffect(() => {
- if (hasTimedOut) {
- debugLog('(BlockNote Editor) Connection to collaboration server timed out');
- setConnectionError(true);
- setIsLoading(false);
- }
- }, [hasTimedOut]);
-
- useEffect(() => {
- const handleProviderAuthError = (event:Event) => {
- const customEvent = event as CustomEvent<{ kind:ProviderAuthErrorKind; message:string }>;
- debugLog(`(BlockNote Editor) Provider auth error: ${customEvent.detail.kind} - ${customEvent.detail.message}`);
- // Auth errors are permanent — bypass the grace period.
- clearDisconnectTimer();
- setConnectionError(true);
- };
-
- document.addEventListener(PROVIDER_AUTH_ERROR_EVENT, handleProviderAuthError);
- return () => document.removeEventListener(PROVIDER_AUTH_ERROR_EVENT, handleProviderAuthError);
- }, [clearDisconnectTimer]);
-
- return { isLoading, connectionError } as const;
+ return { isLoading, offlineMode } as const;
}
-export { useCollaborationProvider };
+export { useCollaboration };
diff --git a/frontend/src/stimulus/controllers/dynamic/admin/backlogs-settings.controller.ts b/frontend/src/stimulus/controllers/dynamic/admin/backlogs-settings.controller.ts
deleted file mode 100644
index 8482d0d0c32..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/admin/backlogs-settings.controller.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * -- copyright
- * OpenProject is an open source project management software.
- * Copyright (C) the OpenProject GmbH
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version 3.
- *
- * OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
- * Copyright (C) 2006-2013 Jean-Philippe Lang
- * Copyright (C) 2010-2013 the ChiliProject Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * See COPYRIGHT and LICENSE files for more details.
- * ++
- */
-
-import { Controller } from '@hotwired/stimulus';
-import {
- NgOption,
- NgSelectComponent,
-} from '@ng-select/ng-select';
-
-/**
- * Stimulus Controller adding behavior to Admin > Backlogs page.
- * Ensures that story types and task types are mutually exclusive.
- */
-export default class BacklogsSettings extends Controller {
- static targets = ['storyTypes', 'taskType'];
-
- declare readonly storyTypesTarget:HTMLElement;
- declare readonly taskTypeTarget:HTMLElement;
- declare readonly hasStoryTypesTarget:boolean;
- declare readonly hasTaskTypeTarget:boolean;
-
- private isUpdating = false;
-
- storyTypesTargetConnected(target:HTMLElement) {
- target.addEventListener('change', this.onStoryTypesChanged);
- }
-
- storyTypesTargetDisconnected(target:HTMLElement) {
- target.removeEventListener('change', this.onStoryTypesChanged);
- }
-
- taskTypeTargetConnected(target:HTMLElement) {
- target.addEventListener('change', this.onTaskTypeChanged);
- }
-
- taskTypeTargetDisconnected(target:HTMLElement) {
- target.removeEventListener('change', this.onTaskTypeChanged);
- }
-
- private onStoryTypesChanged = () => {
- if (this.isUpdating || !this.hasTaskTypeTarget) return;
-
- this.syncDisabledOptions(this.storyTypesTarget, this.taskTypeTarget);
- };
-
- private onTaskTypeChanged = () => {
- if (this.isUpdating || !this.hasStoryTypesTarget) return;
-
- this.syncDisabledOptions(this.taskTypeTarget, this.storyTypesTarget);
- };
-
- /**
- * Syncs disabled options between two autocompleters.
- * Selected values in the source autocompleter will be disabled in the target.
- *
- * @param sourceTarget The autocompleter whose selections should disable options in the target
- * @param targetTarget The autocompleter whose options should be disabled
- */
- private syncDisabledOptions(sourceTarget:HTMLElement, targetTarget:HTMLElement) {
- this.isUpdating = true;
- try {
- const sourceNgSelect = this.getNgSelectComponent(sourceTarget);
- const targetNgSelect = this.getNgSelectComponent(targetTarget);
-
- if (!sourceNgSelect || !targetNgSelect) {
- return;
- }
-
- this.syncAutocompleters(sourceNgSelect, targetNgSelect);
- } finally {
- this.isUpdating = false;
- }
- }
-
- /**
- * Gets the NgSelectComponent instance from an op-autocompleter element.
- */
- private getNgSelectComponent(target:HTMLElement):NgSelectComponent|null {
- // Access the ng-select instance stored by op-autocompleter component
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-member-access
- return (target as any).ngSelectComponentInstance ?? null;
- }
-
- /**
- * Syncs two ng-select autocompleters - ensuring selections are mutually exclusive.
- *
- * @param source source autocompleter
- * @param target target autocompleter
- */
- private syncAutocompleters(source:NgSelectComponent, target:NgSelectComponent) {
- const sourceSelectedIds = new Set(
- source.selectedItems
- .map((item) => item.value.id)
- .filter((id) => id != null)
- );
-
- // Directly mutate the items array to ensure ng-select updates properly
- let hasChanges = false;
- target.itemsList.items.forEach((targetItem:NgOption) => {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const itemId = targetItem.value?.id;
-
- if (!itemId) return;
-
- const shouldBeDisabled = sourceSelectedIds.has(itemId);
- if (targetItem.disabled !== shouldBeDisabled) {
- targetItem.disabled = shouldBeDisabled;
- hasChanges = true;
- }
- });
-
- // Force ng-select to re-render if we made changes
- if (hasChanges) {
- target.detectChanges();
- }
- }
-}
diff --git a/frontend/src/stimulus/controllers/dynamic/admin/work-packages-identifier.controller.ts b/frontend/src/stimulus/controllers/dynamic/admin/work-packages-identifier.controller.ts
index e40bff2a598..2543efe5e87 100644
--- a/frontend/src/stimulus/controllers/dynamic/admin/work-packages-identifier.controller.ts
+++ b/frontend/src/stimulus/controllers/dynamic/admin/work-packages-identifier.controller.ts
@@ -52,17 +52,17 @@ export default class WorkPackagesIdentifierController extends Controller {
}
private updateVisibility() {
- const showAutofix = this.isAlphanumericSelected() && this.hasProblematicProjectsValue;
+ const showAutofix = this.isSemanticSelected() && this.hasProblematicProjectsValue;
this.autofixSectionTarget.hidden = !showAutofix;
this.saveButtonTarget.hidden = showAutofix;
this.autofixButtonTarget.hidden = !showAutofix;
}
- private isAlphanumericSelected():boolean {
+ private isSemanticSelected():boolean {
const checked = this.element.querySelector(
'input[name="settings[work_packages_identifier]"]:checked',
);
- return checked?.value === 'alphanumeric';
+ return checked?.value === 'semantic';
}
}
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/common.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/common.ts
deleted file mode 100644
index 12937fef187..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/common.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-import 'jquery.cookie';
-
-// @ts-expect-error TS(2339): Property 'RB' does not exist on type 'Window & typ... Remove this comment to see the full error message
-if (window.RB === null || window.RB === undefined) {
- // @ts-expect-error TS(2339): Property 'RB' does not exist on type 'Window & typ... Remove this comment to see the full error message
- window.RB = {};
-}
-
-(function ($) {
- let object:any;
- let Factory;
- let Dialog;
- let UserPreferences;
-
- object = {
- // Douglas Crockford's technique for object extension
- // http://javascript.crockford.com/prototypal.html
- create() {
- let obj;
- let i;
- let methods;
- let methodName;
-
- function F() {
- }
-
- F.prototype = arguments[0];
- // @ts-expect-error TS(7009): 'new' expression, whose target lacks a construct s... Remove this comment to see the full error message
- obj = new F();
-
- // Add all the other arguments as mixins that
- // 'write over' any existing methods
- for (i = 1; i < arguments.length; i += 1) {
- methods = arguments[i];
- if (typeof methods === 'object') {
- for (methodName in methods) {
- if (methods.hasOwnProperty(methodName)) {
- obj[methodName] = methods[methodName];
- }
- }
- }
- }
- return obj;
- },
- };
-
- // Object factory for chiliproject_backlogs
- Factory = object.create({
-
- initialize(objType:any, el:any) {
- let obj;
-
- obj = object.create(objType);
- obj.initialize(el);
- return obj;
- },
-
- });
-
- // Utilities
- Dialog = object.create({
- msg(msg:any) {
- let dialog;
- let baseClasses;
-
- baseClasses = 'ui-button ui-widget ui-state-default ui-corner-all';
-
- if ($('#msgBox').length === 0) {
- dialog = $('').appendTo('body');
- } else {
- dialog = $('#msgBox');
- }
-
- dialog.html(msg);
- dialog.dialog({
- title: 'Backlogs Plugin',
- buttons: [
- {
- text: 'OK',
- class: 'button -primary',
- click() {
- $(this).dialog('close');
- },
- }],
- modal: true,
- });
- $('.button').removeClass(baseClasses);
- $('.ui-icon-closethick').prop('title', 'close');
- },
- });
-
- // Abstract the user preference from the rest of the RB objects
- // so that we can change the underlying implementation as needed
- UserPreferences = object.create({
- get(key:any) {
- return $.cookie(key);
- },
-
- set(key:any, value:any) {
- $.cookie(key, value, { expires: 365 * 10 });
- },
- });
-
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Object = object;
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Factory = Factory;
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Dialog = Dialog;
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.UserPreferences = UserPreferences;
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/editable_inplace.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/editable_inplace.ts
deleted file mode 100644
index 22c947f995b..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/editable_inplace.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.EditableInplace = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.Model, {
-
- displayEditor(editor:any) {
- this.$.addClass('editing');
- editor.find('.editor').bind('keydown', this.handleKeydown);
- },
-
- getEditor() {
- // Create the model editor container if it does not yet exist
- let editor = this.$.children('.editors');
-
- if (editor.length === 0) {
- editor = $("").appendTo(this.$);
- } else if (!editor.hasClass('permanent')) {
- editor.first().html('');
- }
- return editor;
- },
-
- // For detecting Enter and ESC
- handleKeydown(e:any) {
- let j;
- let that;
-
- j = $(this).parents('.model').first();
- that = j.data('this');
-
- if (e.key === 'Enter') {
- that.saveEdits();
- } else if (e.key === 'Escape') {
- that.cancelEdit();
- }
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/impediment.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/impediment.ts
deleted file mode 100644
index 9393425dafb..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/impediment.ts
+++ /dev/null
@@ -1,91 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-/**************************************
- IMPEDIMENT
-***************************************/
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.Impediment = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.Task, {
-
- initialize(el:any) {
- let j; // This ensures that we use a local 'j' variable, not a global one.
-
- this.$ = j = $(el);
- this.el = el;
-
- j.addClass('impediment'); // If node is based on #task_template, it doesn't have the impediment class yet
-
- // Associate this object with the element for later retrieval
- j.data('this', this);
-
- j.on('mouseup', '.editable', this.handleClick);
- },
-
- // Override saveDirectives of RB.Task
- saveDirectives() {
- let j;
- let prev;
- let statusID;
-
- let method;
- let url;
- let data;
-
- j = this.$;
- prev = this.$.prev();
- statusID = j.parent('td').first().attr('id').split('_')[1];
-
- data = `${j.find('.editor').serialize()
- }&is_impediment=true`
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- + `&version_id=${RB.constants.sprint_id
- }&status_id=${statusID
- }&prev=${prev.length === 1 ? prev.data('this').getID() : ''
- }${this.isNew() ? '' : `&id=${j.children('.id').text()}`}`;
-
- if (this.isNew()) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- url = RB.urlFor('create_impediment', { sprint_id: RB.constants.sprint_id });
- method = 'post';
- } else {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- url = RB.urlFor('update_impediment', { id: this.getID(), sprint_id: RB.constants.sprint_id });
- method = 'put';
- }
-
- return {
- url,
- method,
- data,
- };
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/model.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/model.ts
deleted file mode 100644
index b77e59ad580..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/model.ts
+++ /dev/null
@@ -1,486 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-import { FetchRequest, FetchResponse } from '@rails/request.js';
-
-/***************************************
- MODEL
- Common methods for sprint, work_package,
- story, task, and impediment
-***************************************/
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.Model = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create({
-
- initialize(el:any) {
- this.$ = $(el);
- this.el = el;
- },
-
- afterCreate(data:string, response:FetchResponse) {
- // Do nothing. Child objects may optionally override this
- },
-
- afterSave(data:string, response:FetchResponse) {
- let isNew;
- let result;
-
- isNew = this.isNew();
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- result = RB.Factory.initialize(RB.Model, data);
-
- this.unmarkSaving();
- this.refresh(result);
-
- if (isNew) {
- const id = result.$.filter('.model').attr('id');
- this.$.attr('id', id);
-
- this.afterCreate(data, response);
- } else {
- this.afterUpdate(data, response);
- }
- },
-
- afterUpdate(data:string, response:FetchResponse) {
- // Do nothing. Child objects may optionally override this
- },
-
- beforeSave() {
- // Do nothing. Child objects may or may not override this method
- },
-
- cancelEdit() {
- this.endEdit();
- if (this.isNew()) {
- this.$.hide('blind');
- }
- },
-
- close() {
- this.$.addClass('closed');
- },
-
- copyFromDialog() {
- let editors;
-
- if (this.$.find('.editors').length === 0) {
- editors = $("").appendTo(this.$);
- } else {
- editors = this.$.find('.editors').first();
- }
- editors.html('');
- editors.append($(`#${this.getType().toLowerCase()}_editor`).children('.editor'));
- this.saveEdits();
- },
-
- displayEditor(editor:any) {
- const self = this;
- let baseClasses;
-
- baseClasses = 'ui-button ui-widget ui-state-default ui-corner-all';
-
- editor.dialog({
- buttons: [
- {
- text: 'OK',
- class: 'button -primary',
- click() {
- self.copyFromDialog();
- $(this).dialog('close');
- },
- },
- {
- text: 'Cancel',
- class: 'button',
- click() {
- self.cancelEdit();
- $(this).dialog('close');
- },
- },
- ],
- close(e:any, ui:any) {
- if (e.type === 'click' || (e.type === 'keydown' && e.key === 'Escape')) {
- self.cancelEdit();
- }
- },
- dialogClass: `${this.getType().toLowerCase()}_editor_dialog`,
- modal: true,
- position: { my: 'center', at: 'center', of: window },
- resizable: false,
- title: (this.isNew() ? this.newDialogTitle() : this.editDialogTitle()),
- });
- editor.find('.editor').first().focus();
- $('.button').removeClass(baseClasses);
- $('.ui-icon-closethick').prop('title', 'close');
- },
-
- edit() {
- const editor = this.getEditor();
- const self = this;
- let maxTabIndex = 0;
-
- $('.stories .editors .editor').each(function (index) {
- let value;
-
- // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message
- value = parseInt($(this).attr('tabindex'), 10);
-
- if (maxTabIndex < value) {
- maxTabIndex = value;
- }
- });
-
- if (!editor.hasClass('permanent')) {
- this.$.find('.editable').each(function (this:any, index:any) {
- const field = $(this);
- const fieldId = field.attr('field_id');
- const fieldName = field.attr('fieldname');
- const fieldLabel = field.attr('fieldlabel');
- // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message
- const fieldOrder = parseInt(field.attr('fieldorder'), 10);
- const fieldEditable = field.attr('fieldeditable') || 'true';
- const fieldType = field.attr('fieldtype') || 'input';
- let typeId;
- let statusId;
- let input:any;
-
- if (fieldType === 'select') {
- // Special handling for status_id => they are dependent of type_id
- if (fieldName === 'status_id') {
- typeId = $.trim(self.$.find('.type_id .v').html());
- // when creating stories we need to query the select directly
- if (typeId === '') {
- typeId = $('#type_id_options').val();
- }
- statusId = $.trim(self.$.find('.status_id .v').html());
- input = self.findFactory(typeId, statusId, fieldName);
- } else if (fieldName === 'type_id') {
- input = $(`#${fieldName}_options`).clone(true);
- // if the type changes the status dropdown has to be modified
- input.change(function () {
- // @ts-expect-error TS(2683): 'this' implicitly has type 'any' because it does n... Remove this comment to see the full error message
- typeId = $(this).val();
- statusId = $.trim(self.$.find('.status_id .v').html());
- let newInput = self.findFactory(typeId, statusId, 'status_id');
- newInput = self.prepareInputFromFactory(newInput, fieldId, 'status_id', fieldOrder, maxTabIndex);
- // @ts-expect-error TS(2683): 'this' implicitly has type 'any' because it does n... Remove this comment to see the full error message
- newInput = self.replaceStatusForNewType(input, newInput, $(this).parent().find('.status_id').val(), editor);
- });
- } else {
- input = $(`#${fieldName}_options`).clone(true);
- }
- } else {
- input = $(document.createElement(fieldType));
- }
-
- input = self.prepareInputFromFactory(input, fieldId, fieldName, fieldOrder, maxTabIndex, fieldEditable);
-
- // Copy the value in the field to the input element
- input.val(fieldType === 'select' ? field.children('.v').first().text() : field.text());
-
- // Record in the model's root element which input field had the last focus. We will
- // use this information inside RB.Model.refresh() to determine where to return the
- // focus after the element has been refreshed with info from the server.
- input.focus(function (this:any) {
- self.$.data('focus', $(this).attr('name'));
- });
-
- input.blur(() => {
- self.$.data('focus', '');
- });
-
- $('').attr({
- for: input.attr('id'),
- // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message
- }).text(fieldLabel).appendTo(editor);
- input.appendTo(editor);
- });
- }
-
- this.displayEditor(editor);
- this.editorDisplayed(editor);
- return editor;
- },
-
- findFactory(typeId:any, statusId:any, fieldName:any) {
- // Find a factory
- let newInput = $(`#${fieldName}_options_${typeId}_${statusId}`);
- if (newInput.length === 0) {
- // when no list found, only offer the default status
- // no list = combination is not valid / user has no rights -> workflow
- newInput = $(`#status_id_options_default_${statusId}`);
- }
- newInput = newInput.clone(true);
- return newInput;
- },
-
- prepareInputFromFactory(input:any, fieldId:any, fieldName:any, fieldOrder:any, maxTabIndex:any, fieldEditable:any) {
- input.attr('id', `${fieldName}_${fieldId}`);
- input.attr('name', fieldName);
- input.attr('tabindex', fieldOrder + maxTabIndex);
- if (fieldEditable !== 'true') {
- input.attr('disabled', true);
- }
- input.addClass(fieldName);
- input.addClass('editor');
- input.removeClass('template');
- input.removeClass('helper');
- return input;
- },
-
- replaceStatusForNewType(input:any, newInput:any, statusId:any, editor:any) {
- // Append an empty field and select it in case the old status is not available
- newInput.val(statusId); // try to set the status
- if (newInput.val() !== statusId) {
- newInput.append(new Option('', ''));
- newInput.val('');
- }
- newInput.focus(function (this:any) {
- // @ts-expect-error TS(2339): Property '$' does not exist on type 'Window & type... Remove this comment to see the full error message
- self.$.data('focus', $(this).attr('name'));
- });
-
- newInput.blur(() => {
- // @ts-expect-error TS(2339): Property '$' does not exist on type 'Window & type... Remove this comment to see the full error message
- self.$.data('focus', '');
- });
- // Find the old status dropdown and replace it with the new one
- input.parent().find('.status_id').replaceWith(newInput);
- },
-
- // Override this method to change the dialog title
- editDialogTitle() {
- return `Edit ${this.getType()}`;
- },
-
- editorDisplayed(editor:any) {
- // Do nothing. Child objects may override this.
- },
-
- endEdit() {
- this.$.removeClass('editing');
- },
-
- error(responseHtml:string, error:unknown) {
- this.markError();
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Dialog.msg($(responseHtml).find('.errors').html());
- this.processError(responseHtml, error);
- },
-
- getEditor() {
- let editorId;
- let editor;
-
- // Create the model editor if it does not yet exist
- editorId = `${this.getType().toLowerCase()}_editor`;
-
- editor = $(`#${editorId}`).html('');
-
- if (editor.length === 0) {
- editor = $(``).appendTo('body');
- }
- return editor;
- },
-
- getID() {
- return this.$.children('.id').children('.v').text();
- },
-
- getType() {
- throw new Error('Child objects must override getType()');
- },
-
- handleClick(e:any) {
- const field = $(this);
- const model = field.parents('.model').first().data('this');
- const j = model.$;
-
- if (!j.hasClass('editing')
- && !j.hasClass('dragging')
- && !j.hasClass('prevent_edit')
- && !$(e.target).hasClass('prevent_edit')
- && e.target.closest('.editable').getAttribute('fieldeditable') !== 'false') {
- const editor = model.edit();
- const input = editor.find(`.${$(e.currentTarget).attr('fieldname')}.editor`);
-
- input.focus();
- input.click();
- }
- },
-
- handleSelect(e:any) {
- const j = $(this);
- const self = j.data('this');
-
- if (!$(e.target).hasClass('editable')
- && !$(e.target).hasClass('checkbox')
- && !j.hasClass('editing')
- && e.target.tagName !== 'A'
- && !j.hasClass('dragging')) {
- self.setSelection(!self.isSelected());
- }
- },
-
- isClosed() {
- return this.$.hasClass('closed');
- },
-
- isNew() {
- return this.getID() === '';
- },
-
- markError() {
- this.$.addClass('error icon icon-bug');
- },
-
- markIfClosed() {
- throw new Error('Child objects must override markIfClosed()');
- },
-
- markSaving() {
- this.$.addClass('ajax-indicator');
- },
-
- // Override this method to change the dialog title
- newDialogTitle() {
- return `New ${this.getType()}`;
- },
-
- open() {
- this.$.removeClass('closed');
- },
-
- processError(responseHtml:string, error:unknown) {
- // Override as needed
- },
-
- refresh(obj:any) {
- this.$.html($(obj.el).filter('.model').html());
-
- if (obj.$.length > 1) {
- // execute script tags, that were attached to the sources
- obj.$.filter('script').each(function (this:any) {
- try {
- $.globalEval($(this).html());
- } catch (e) {
- }
- });
- }
-
- if (obj.isClosed()) {
- this.close();
- } else {
- this.open();
- }
-
- this.refreshed();
- },
-
- refreshed() {
- // Override as needed
- },
-
- saveDirectives() {
- throw new Error('Child object must implement saveDirectives()');
- },
-
- saveEdits() {
- const j = this.$;
- const self = this;
- const editors = j.find('.editor');
-
- // Copy the values from the fields to the proper html elements
- editors.each(function (this:any, index:any) {
- const editor = $(this).find('input,select,textarea').addBack('input,select,textarea');
- const fieldName = editor.attr('name');
- const tagName = editor.prop('tagName');
- if (tagName === 'SELECT') {
- // if the user changes the type and that type does not offer the status
- // of the current story, the status field is set to blank
- // if the user saves this edit we will receive a validation error
- // the following 3 lines will prevent the override of the status id
- // otherwise we would loose the status id of the current ticket
- if (!(fieldName === 'status_id' && editor.val() === '')) {
- j.children(`div.${fieldName}`).children('.v').text(editor.val());
- }
- let text = editor.children(':selected').text().trim();
- if (fieldName === 'type_id') {
- text += ':';
- }
-
- j.children(`div.${fieldName}`).children('.t').text(text);
- } else {
- j.children(`div.${fieldName}`).text(editor.val());
- }
- });
-
- // Mark the work_package as closed if so
- self.markIfClosed();
-
- // Get the save directives.
- const { method, url, data } = self.saveDirectives();
-
- self.beforeSave();
- self.unmarkError();
- self.markSaving();
-
- (async () => {
- try {
- const request = new FetchRequest(method, url, {
- body: data,
- contentType: 'multipart/form-data',
- responseKind: 'html',
- });
- const response = await request.perform();
- const html = await response.html;
- if (!response.ok) {
- self.error(html, null);
- } else {
- self.afterSave(html, response);
- }
- } catch (error) {
- self.error('Network error', error);
- } finally {
- self.endEdit();
- }
- })();
- },
-
- unmarkError() {
- this.$.removeClass('error icon icon-bug');
- },
-
- unmarkSaving() {
- this.$.removeClass('ajax-indicator');
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/show_main.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/show_main.ts
deleted file mode 100644
index f56db5e6edf..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/show_main.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-// Initialize everything after DOM is loaded
-jQuery(($) => {
- let defaultDialogColor:any; // this var is used as cache for some computation in
- // the inner function. -> Do not move to where it
- // actually belongs!
-
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Factory.initialize(RB.Taskboard, $('#taskboard'));
-
- $('#assigned_to_id_options').change(function () {
- const selected = $(this).children(':selected');
- if (!defaultDialogColor) {
- // fetch the color from the task rendered as a prototype/template for new tasks
- defaultDialogColor = $('#work_package_').css('background-color');
- }
- $(this).parents('.ui-dialog').css('background-color', selected.attr('color') || defaultDialogColor);
- // @ts-expect-error TS(2339): Property 'colorcontrast' does not exist on type 'J... Remove this comment to see the full error message
- $(this).parents('.ui-dialog').colorcontrast();
- });
-});
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/sprint.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/sprint.ts
deleted file mode 100644
index f77f08fdb90..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/sprint.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-/***************************************
- SPRINT
-***************************************/
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.Sprint = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.Model, RB.EditableInplace, {
-
- initialize(el:any) {
- this.$ = $(el);
- this.el = el;
-
- // Associate this object with the element for later retrieval
- this.$.data('this', this);
- this.$.on('mouseup', '.editable', this.handleClick);
- },
-
- beforeSave() {
- // Do nothing
- },
-
- getType() {
- return 'Sprint';
- },
-
- markIfClosed() {
- // Do nothing
- },
-
- refreshed() {
- // Do nothing
- },
-
- saveDirectives() {
- const wrapper = this.$;
- const editor = wrapper.find('.editor');
- const data = editor.serialize();
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- const url = RB.urlFor('update_sprint', { id: this.getID() });
-
- return {
- url,
- method: 'put',
- data,
- };
- },
-
- beforeSaveDragResult() {
- // Do nothing
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/task.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/task.ts
deleted file mode 100644
index 970e4006dc7..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/task.ts
+++ /dev/null
@@ -1,127 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-/**************************************
- TASK
-***************************************/
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.Task = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.WorkPackage, {
-
- initialize(el:any) {
- this.$ = $(el);
- this.el = el;
-
- // If node is based on #task_template, it doesn't have the story class yet
- this.$.addClass('task');
-
- // Associate this object with the element for later retrieval
- this.$.data('this', this);
- this.$.on('mouseup', '.editable', this.handleClick);
- this.defaultColor = $('#rb .task').css('background-color');
- },
-
- beforeSave: function name() {
- if (this.el && $(this.el).hasClass('dragging')) {
- return;
- }
- const c = this.$.find('select.assigned_to_id').children(':selected').attr('color') || this.defaultColor;
- this.$.css('background-color', c);
- this.$.colorcontrast();
- },
-
- editorDisplayed(dialog:any) {
- dialog.parents('.ui-dialog').css('background-color', this.$.css('background-color'));
- dialog.parents('.ui-dialog').colorcontrast();
- },
-
- getType() {
- return 'Task';
- },
-
- markIfClosed() {
- if (this.$.parent('td').first().hasClass('closed')) {
- this.$.addClass('closed');
- } else {
- this.$.removeClass('closed');
- }
- },
-
- saveDirectives() {
- let prev;
- let cellId;
-
- let url;
- let method;
- let data;
-
- prev = this.$.prev();
- cellId = this.$.parent('td').first().attr('id').split('_');
-
- data = `${this.$.find('.editor').serialize()
- }&parent_id=${cellId[0]
- }&status_id=${cellId[1]
- }&prev=${prev.length === 1 ? prev.data('this').getID() : ''
- }${this.isNew() ? '' : `&id=${this.$.children('.id').text()}`}`;
-
- if (this.isNew()) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- url = RB.urlFor('create_task', { sprint_id: RB.constants.sprint_id });
- method = 'post';
- } else {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- url = RB.urlFor('update_task', { id: this.getID(), sprint_id: RB.constants.sprint_id });
- method = 'put';
- }
-
- return {
- url,
- method,
- data,
- };
- },
-
- beforeSaveDragResult() {
- if (this.$.parent('td').first().hasClass('closed')) {
- // This is only for the purpose of making the Remaining Hours reset
- // instantaneously after dragging to a closed status. The server should
- // still make sure to reset the value.
- this.$.children('.remaining_hours.editor').val('');
- this.$.children('.remaining_hours.editable').text('');
- }
- },
-
- refreshed() {
- const remainingHours = this.$.children('.remaining_hours.editable');
-
- remainingHours.toggleClass('empty', remainingHours.is(':empty'));
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard-legacy.controller.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard-legacy.controller.ts
deleted file mode 100644
index 3e3beebea8e..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard-legacy.controller.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Controller } from '@hotwired/stimulus';
-
-import 'core-vendor/jquery.jeditable.mini';
-import 'core-vendor/jquery.colorcontrast';
-
-import './common';
-import './model';
-import './editable_inplace';
-import './sprint';
-import './work_package';
-import './task';
-import './impediment';
-import './taskboard';
-import './show_main';
-
-export default class TaskboardLegacyController extends Controller {
-}
diff --git a/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard.ts b/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard.ts
deleted file mode 100644
index 49d5bb61397..00000000000
--- a/frontend/src/stimulus/controllers/dynamic/backlogs/taskboard.ts
+++ /dev/null
@@ -1,209 +0,0 @@
-//-- copyright
-// OpenProject is an open source project management software.
-// Copyright (C) the OpenProject GmbH
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License version 3.
-//
-// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
-// Copyright (C) 2006-2013 Jean-Philippe Lang
-// Copyright (C) 2010-2013 the ChiliProject Team
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//
-// See COPYRIGHT and LICENSE files for more details.
-//++
-
-/***************************************
- TASKBOARD
-***************************************/
-
-// @ts-expect-error TS(2304): Cannot find name 'RB'.
-RB.Taskboard = (function ($) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- return RB.Object.create(RB.Model, {
-
- initialize(el:any) {
- const self = this; // So we can bind the event handlers to this object
-
- this.$ = $(el);
- this.el = el;
-
- // Associate this object with the element for later retrieval
- this.$.data('this', this);
-
- // Initialize column widths
- this.colWidthUnit = 107;
- this.defaultColWidth = 1;
- this.loadColWidthPreference();
- this.updateColWidths();
-
- $('#col_width_input')
- .on('keyup', (evt) => {
- if (evt.which === 13) {
- self.updateColWidths();
- }
- });
-
- this.initializeTasks();
- this.initializeImpediments();
-
- this.initializeNewButtons();
- this.initializeSortables();
-
- this.initializeTaskboardMenus();
- },
-
- initializeNewButtons() {
- this.$.find('#tasks .add_new.clickable').click(this.handleAddNewTaskClick);
- this.$.find('#impediments .add_new.clickable').click(this.handleAddNewImpedimentClick);
- },
-
- initializeSortables() {
- this.$.find('#impediments .list').sortable({
- placeholder: 'placeholder',
- start: this.dragStart,
- stop: this.dragStop,
- update: this.dragComplete,
- cancel: '.prevent_edit',
- }).sortable('option', 'connectWith', '#impediments .list');
- $('#impediments .list').disableSelection();
-
- let list:any;
- let augmentList:any;
- const self = this;
-
- list = this.$.find('#tasks .list');
-
- augmentList = function () {
- $(list.splice(0, 50)).sortable({
- placeholder: 'placeholder',
- start: self.dragStart,
- stop: self.dragStop,
- update: self.dragComplete,
- cancel: '.prevent_edit',
- }).sortable('option', 'connectWith', '#tasks .list');
- $('#tasks .list').disableSelection();
-
- if (list.length > 0) {
- /*globals setTimeout*/
- setTimeout(augmentList, 10);
- }
- };
- augmentList();
- },
-
- initializeTasks() {
- this.$.find('.task').each(function (this:any, index:any) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Factory.initialize(RB.Task, this);
- });
- },
-
- initializeImpediments() {
- this.$.find('.impediment').each(function (this:any, index:any) {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.Factory.initialize(RB.Impediment, this);
- });
- },
-
- initializeTaskboardMenus() {
- const toggleOpen = 'open icon-pulldown-up icon-pulldown';
-
- $('.backlog .backlog-menu > div.menu-trigger').on('click', function () {
- $(this).toggleClass(toggleOpen);
- });
-
- $('.backlog .backlog-menu > ul.items li.item').on('click', function () {
- $(this).closest('.backlog-menu').find('div.menu-trigger').toggleClass(toggleOpen);
- });
- },
-
- dragComplete(e:any, ui:any) {
- // Handler is triggered for source and target. Thus the need to check.
- const isDropTarget = (ui.sender === null);
-
- if (isDropTarget) {
- ui.item.data('this').saveDragResult();
- }
- },
-
- dragStart(e:any, ui:any) {
- ui.item.addClass('dragging');
- },
-
- dragStop(e:any, ui:any) {
- ui.item.removeClass('dragging');
- },
-
- handleAddNewImpedimentClick(e:any) {
- const row = $(this).parents('tr').first();
- $('#taskboard').data('this').newImpediment(row);
- },
-
- handleAddNewTaskClick(e:any) {
- const row = $(this).parents('tr').first();
- $('#taskboard').data('this').newTask(row);
- },
-
- loadColWidthPreference() {
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- let w = RB.UserPreferences.get('taskboardColWidth');
- if (w === null || w === undefined) {
- w = this.defaultColWidth;
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.UserPreferences.set('taskboardColWidth', w);
- }
- $('#col_width input').val(w);
- },
-
- newImpediment(row:any) {
- let impediment;
- let o;
-
- impediment = $('#impediment_template').children().first().clone();
- row.find('.list').first().prepend(impediment);
-
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- o = RB.Factory.initialize(RB.Impediment, impediment);
- o.edit();
- },
-
- newTask(row:any) {
- let task;
- let o;
-
- task = $('#task_template').children().first().clone();
- row.find('.list').first().prepend(task);
-
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- o = RB.Factory.initialize(RB.Task, task);
- o.edit();
- },
-
- updateColWidths() {
- // @ts-expect-error TS(2345): Argument of type 'string | number | string[] | und... Remove this comment to see the full error message
- let w = parseInt($('#col_width_input').val(), 10);
-
- if (isNaN(w) || w <= 0) {
- w = this.defaultColWidth;
- }
- $('#col_width_input').val(w);
- // @ts-expect-error TS(2304): Cannot find name 'RB'.
- RB.UserPreferences.set('taskboardColWidth', w);
- $('.swimlane').width(this.colWidthUnit * w).css('min-width', this.colWidthUnit * w);
- },
- });
-}(jQuery));
diff --git a/frontend/src/stimulus/controllers/dynamic/documents/connection-status.controller.ts b/frontend/src/stimulus/controllers/dynamic/documents/connection-status.controller.ts
new file mode 100644
index 00000000000..5d61e075afd
--- /dev/null
+++ b/frontend/src/stimulus/controllers/dynamic/documents/connection-status.controller.ts
@@ -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.
+ * ++
+ */
+
+import { Controller } from '@hotwired/stimulus';
+
+type ConnectionState = 'live' | 'offline' | 'recovered';
+
+export default class ConnectionStatusController extends Controller {
+ static targets = ['live', 'offline', 'recovered'];
+
+ declare readonly offlineTarget:HTMLElement;
+ declare readonly recoveredTarget:HTMLElement;
+ declare readonly liveTargets:HTMLElement[];
+
+ private recoveryTimeout:ReturnType|null = null;
+
+ showOffline():void {
+ this.clearRecoveryTimeout();
+ this.activateState('offline');
+ }
+
+ showRecovered():void {
+ this.clearRecoveryTimeout();
+ this.activateState('recovered');
+
+ this.recoveryTimeout = setTimeout(() => this.activateState('live'), 5000);
+ }
+
+ disconnect():void {
+ this.clearRecoveryTimeout();
+ }
+
+ private activateState(state:ConnectionState):void {
+ this.offlineTarget.hidden = state !== 'offline';
+ this.recoveredTarget.hidden = state !== 'recovered';
+ this.liveTargets.forEach((el) => { el.hidden = state !== 'live'; });
+ }
+
+ private clearRecoveryTimeout():void {
+ if (this.recoveryTimeout !== null) {
+ clearTimeout(this.recoveryTimeout);
+ this.recoveryTimeout = null;
+ }
+ }
+}
diff --git a/frontend/src/stimulus/controllers/dynamic/documents/editor-connection.controller.ts b/frontend/src/stimulus/controllers/dynamic/documents/editor-connection.controller.ts
new file mode 100644
index 00000000000..5caba4647f0
--- /dev/null
+++ b/frontend/src/stimulus/controllers/dynamic/documents/editor-connection.controller.ts
@@ -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.
+ * ++
+ */
+
+import { Controller } from '@hotwired/stimulus';
+
+export default class EditorConnectionController extends Controller {
+ static targets = ['error', 'editor'];
+
+ declare readonly errorTarget:HTMLElement;
+ declare readonly editorTarget:HTMLElement;
+
+ showError():void {
+ this.errorTarget.hidden = false;
+ this.editorTarget.hidden = true;
+ }
+
+ showEditor():void {
+ this.errorTarget.hidden = true;
+ this.editorTarget.hidden = false;
+ }
+}
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 ab450c4342a..e935131f9f8 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
@@ -1,37 +1,41 @@
/*
* -- copyright
- * openproject is an open source project management software.
- * copyright (c) the openproject gmbh
+ * 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.
+ * 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
+ * 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 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.
+ * 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.
+ * 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.
+ * See COPYRIGHT and LICENSE files for more details.
* ++
*/
import { HocuspocusProvider } from '@hocuspocus/provider';
import { Controller } from '@hotwired/stimulus';
import { LiveCollaborationManager } from 'core-stimulus/helpers/live-collaboration-helpers';
-import { PROVIDER_AUTH_ERROR_EVENT, ProviderAuthErrorKind, TokenRefreshService } from 'core-stimulus/services/documents/token-refresh.service';
+import {
+ PROVIDER_AUTH_ERROR_EVENT,
+ ProviderAuthErrorKind,
+ TokenRefreshService,
+} from 'core-stimulus/services/documents/token-refresh.service';
import type { Doc } from 'yjs';
import * as Y from 'yjs';
diff --git a/frontend/src/stimulus/controllers/dynamic/my/daily-reminders.controller.ts b/frontend/src/stimulus/controllers/dynamic/my/daily-reminders.controller.ts
new file mode 100644
index 00000000000..b63ce5f1cab
--- /dev/null
+++ b/frontend/src/stimulus/controllers/dynamic/my/daily-reminders.controller.ts
@@ -0,0 +1,88 @@
+/*
+ * -- 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';
+
+export default class DailyRemindersController extends Controller {
+ static targets = ['list', 'row', 'rowTemplate'];
+
+ declare readonly listTarget:HTMLElement;
+ declare readonly rowTargets:HTMLElement[];
+ declare readonly rowTemplateTarget:HTMLTemplateElement;
+ declare readonly hasRowTemplateTarget:boolean;
+
+ private readonly handleChange = ():void => { this.syncDisabledOptions(); };
+
+ connect():void {
+ this.listTarget.addEventListener('change', this.handleChange);
+ this.syncDisabledOptions();
+ this.updateRemoveButtons();
+ }
+
+ disconnect():void {
+ this.listTarget.removeEventListener('change', this.handleChange);
+ }
+
+ addTime():void {
+ if (!this.hasRowTemplateTarget) return;
+
+ const clone = this.rowTemplateTarget.content.cloneNode(true) as DocumentFragment;
+ this.listTarget.appendChild(clone);
+ this.syncDisabledOptions();
+ this.updateRemoveButtons();
+ }
+
+ removeTime(event:Event):void {
+ const button = event.currentTarget as HTMLElement;
+ button.closest('[data-my--daily-reminders-target="row"]')?.remove();
+ this.syncDisabledOptions();
+ this.updateRemoveButtons();
+ }
+
+ private updateRemoveButtons():void {
+ const rows = this.rowTargets;
+ const showRemove = rows.length > 1;
+ rows.forEach((row) => {
+ const btn = row.querySelector('[data-action="my--daily-reminders#removeTime"]');
+ if (btn) btn.hidden = !showRemove;
+ });
+ }
+
+ private syncDisabledOptions():void {
+ const selects = Array.from(this.listTarget.querySelectorAll('select'));
+ const selectedValues = new Set(selects.map((s) => s.value));
+
+ selects.forEach((select) => {
+ Array.from(select.options).forEach((option) => {
+ option.disabled = selectedValues.has(option.value) && option.value !== select.value;
+ });
+ });
+ }
+}
diff --git a/frontend/src/stimulus/controllers/dynamic/my/look-and-feel.controller.ts b/frontend/src/stimulus/controllers/dynamic/my/look-and-feel.controller.ts
index 2ac5a1a9e79..aea43c361f8 100644
--- a/frontend/src/stimulus/controllers/dynamic/my/look-and-feel.controller.ts
+++ b/frontend/src/stimulus/controllers/dynamic/my/look-and-feel.controller.ts
@@ -38,7 +38,6 @@ export default class LookAndFeelController extends Controller {
declare singleThemeContrastTarget:HTMLElement;
private syncWithOsValue = 'sync_with_os';
- private viewComponentSelector = '[data-view-component="true"]';
connect() {
this.toggleOptionGroups();
@@ -56,9 +55,10 @@ export default class LookAndFeelController extends Controller {
}
private toggleElementVisibility(targetElement:HTMLElement, shouldShow:boolean) {
- const viewComponentContainer = targetElement.closest(this.viewComponentSelector);
- if (viewComponentContainer) {
- (viewComponentContainer as HTMLElement).hidden = !shouldShow;
+ const container = targetElement.closest('.FormControl-check-group-wrap')
+ ?? targetElement.closest('[data-view-component="true"]');
+ if (container) {
+ container.hidden = !shouldShow;
}
}
}
diff --git a/frontend/src/stimulus/controllers/dynamic/projects/identifier-suggestion.controller.ts b/frontend/src/stimulus/controllers/dynamic/projects/identifier-suggestion.controller.ts
index 8c3ea979c1e..0310832ca7d 100644
--- a/frontend/src/stimulus/controllers/dynamic/projects/identifier-suggestion.controller.ts
+++ b/frontend/src/stimulus/controllers/dynamic/projects/identifier-suggestion.controller.ts
@@ -32,7 +32,7 @@ import {ApplicationController, useDebounce} from 'stimulus-use';
const ALLOWED_CHARS:Record = {
semantic: /[^A-Z0-9_]/g,
- legacy: /[^a-z0-9\-_]/g,
+ classic: /[^a-z0-9\-_]/g,
};
export default class extends ApplicationController {
@@ -42,7 +42,7 @@ export default class extends ApplicationController {
static values = {
url: String,
debounce: {type: Number, default: 300},
- mode: {type: String, default: 'legacy'},
+ mode: {type: String, default: 'classic'},
setNameFirst: {type: String, default: ''},
};
@@ -88,7 +88,7 @@ export default class extends ApplicationController {
private filterInput():void {
if (!this.hasIdentifierTarget) return;
- const pattern = ALLOWED_CHARS[this.modeValue] ?? ALLOWED_CHARS.legacy;
+ const pattern = ALLOWED_CHARS[this.modeValue] ?? ALLOWED_CHARS.classic;
const current = this.identifierTarget.value;
const filtered = current.replace(pattern, '');
diff --git a/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/editor.controller.ts b/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/editor.controller.ts
index 77194f0d7c6..2436608f2ef 100644
--- a/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/editor.controller.ts
+++ b/frontend/src/stimulus/controllers/dynamic/work-packages/activities-tab/editor.controller.ts
@@ -65,6 +65,8 @@ export default class EditorController extends BaseController {
private rescuedEditorDataKey:string;
private abortController = new AbortController();
private ckEditorAbortController = new AbortController();
+ private editorDataObserver?:MutationObserver;
+ private editorDataTimer?:number;
connect() {
super.connect();
@@ -75,6 +77,7 @@ export default class EditorController extends BaseController {
}
disconnect() {
+ this.clearPendingEditorDataSetup();
this.rescueEditorContent();
this.removeCkEditorEventListeners();
this.removeEventListeners();
@@ -109,9 +112,7 @@ export default class EditorController extends BaseController {
openEditorWithInitialData(quotedText:string) {
this.showForm();
- if (this.isEditorEmpty()) {
- this.ckEditorInstance!.setData(quotedText);
- }
+ this.setEditorDataWhenReady(quotedText);
}
clearEditor() {
@@ -210,6 +211,59 @@ export default class EditorController extends BaseController {
this.ckEditorAbortController = new AbortController();
}
+ /**
+ * Sets the editor data once CKEditor is initialized. If CKEditor is already
+ * available and empty, sets the data immediately. Otherwise, watches for CKEditor
+ * readiness via MutationObserver. This handles the case where the Stimulus
+ * controller connects before CKEditor has finished its async initialization
+ * (e.g., after a Turbo navigation).
+ *
+ * A setTimeout deferral is used to ensure Angular's CKEditor initialization
+ * Promise chain has fully completed before we interact with the editor.
+ */
+ private setEditorDataWhenReady(data:string) {
+ this.clearPendingEditorDataSetup();
+
+ if (this.ckEditorInstance) {
+ if (this.isEditorEmpty()) {
+ this.ckEditorInstance.setData(data);
+ }
+ return;
+ }
+
+ const observer = new MutationObserver(() => {
+ if (this.ckEditorInstance) {
+ observer.disconnect();
+ if (this.editorDataObserver === observer) {
+ this.editorDataObserver = undefined;
+ }
+ // Defer to the next macrotask so that Angular's CKEditor initialization
+ // Promise chain completes and the component's `initialized` flag is set.
+ // This prevents "Tried to access CKEditor instance before initialization"
+ // errors when the form is subsequently submitted.
+ this.editorDataTimer = window.setTimeout(() => {
+ this.editorDataTimer = undefined;
+ if (this.isEditorEmpty()) {
+ this.ckEditorInstance?.setData(data);
+ }
+ });
+ }
+ });
+
+ this.editorDataObserver = observer;
+ observer.observe(this.element, { childList: true, subtree: true });
+ }
+
+ private clearPendingEditorDataSetup() {
+ this.editorDataObserver?.disconnect();
+ this.editorDataObserver = undefined;
+
+ if (this.editorDataTimer !== undefined) {
+ window.clearTimeout(this.editorDataTimer);
+ this.editorDataTimer = undefined;
+ }
+ }
+
private rescueEditorContent() {
const data = this.ckEditorInstance?.getData({ trim: false });
if (data) {
diff --git a/frontend/src/stimulus/controllers/hover-card-trigger.controller.ts b/frontend/src/stimulus/controllers/hover-card-trigger.controller.ts
index 249bf9a8b21..ad718686a14 100644
--- a/frontend/src/stimulus/controllers/hover-card-trigger.controller.ts
+++ b/frontend/src/stimulus/controllers/hover-card-trigger.controller.ts
@@ -146,8 +146,8 @@ export default class HoverCardTriggerController extends ApplicationController {
this.close(true);
const turboFrameUrl = this.parseHoverCardUrl(el);
- const popoverEl = this.getPopoverFromId(el);
- if (!turboFrameUrl && !popoverEl) { return; }
+ const popoverTemplate = this.getPopoverTemplateFromId(el);
+ if (!turboFrameUrl && !popoverTemplate) { return; }
// Reset close timer for when hovering over multiple triggers in quick succession.
// A timer from a previous hover card might still be running. We do not want it to
@@ -156,11 +156,11 @@ export default class HoverCardTriggerController extends ApplicationController {
// Set a delay before showing the hover card
this.hoverTimeout = window.setTimeout(() => {
- this.showHoverCard(el, turboFrameUrl, popoverEl);
+ this.showHoverCard(el, turboFrameUrl, popoverTemplate);
}, this.OPEN_DELAY_IN_MS);
}
- private showHoverCard(el:HTMLElement, turboFrameUrl:string, popoverElement:HTMLElement|null) {
+ private showHoverCard(el:HTMLElement, turboFrameUrl:string, popoverTemplate:HTMLTemplateElement|null) {
// Abort if the trigger element is no longer present in the DOM. This can happen when this method is called after a delay.
if (!this.element.contains(el)) { return; }
// Do not try to show two hover cards at the same time.
@@ -168,8 +168,8 @@ export default class HoverCardTriggerController extends ApplicationController {
// The mouse might have left the trigger while we were waiting for the hover delay.
if (!this.mouseIsHoveringOverTrigger) { return; }
- if (popoverElement) {
- this.showHoverCardViaExistingElement(el, popoverElement);
+ if (popoverTemplate) {
+ this.showHoverCardViaExistingElement(el, popoverTemplate);
} else {
this.loadAndShowHoverCardViaTurboFrame(el, turboFrameUrl);
}
@@ -194,13 +194,13 @@ export default class HoverCardTriggerController extends ApplicationController {
});
}
- private showHoverCardViaExistingElement(targetEl:HTMLElement, protoPopover:HTMLElement) {
+ private showHoverCardViaExistingElement(targetEl:HTMLElement, popoverTemplate:HTMLTemplateElement) {
const overlay = this.getAndResetOverlay();
if (!overlay) { return; }
this.moveOverlayToAppropriateParent(overlay, targetEl);
- const popover = this.cloneStaticPopover(overlay, protoPopover);
+ const popover = this.popoverFromTemplate(overlay, popoverTemplate);
this.isShowingHoverCard = true;
this.previousTarget = targetEl;
@@ -262,7 +262,7 @@ export default class HoverCardTriggerController extends ApplicationController {
* When there is no URL or if the URL is invalid, will return an empty string.
*/
private parseHoverCardUrl(el:HTMLElement) {
- let url = el.getAttribute('data-hover-card-url');
+ let url = el.dataset.hoverCardUrl;
if (!url) { return ''; }
url = sanitizeUrl(url);
@@ -272,11 +272,14 @@ export default class HoverCardTriggerController extends ApplicationController {
return url === 'about:blank' ? '' : url;
}
- private getPopoverFromId(el:HTMLElement):HTMLElement|null {
- const id = el.getAttribute('data-hover-card-popover-id');
+ private getPopoverTemplateFromId(el:HTMLElement):HTMLTemplateElement|null {
+ const id = el.dataset.hoverCardPopoverTemplateId;
if (!id) { return null; }
- return document.getElementById(id);
+ const element = document.getElementById(id);
+ if (!(element instanceof HTMLTemplateElement)) { return null; }
+
+ return element;
}
private async reposition(element:HTMLElement, target:HTMLElement) {
@@ -317,12 +320,13 @@ export default class HoverCardTriggerController extends ApplicationController {
return { turboFrame, popover };
}
- private cloneStaticPopover(overlay:HTMLElement, staticPopover:HTMLElement):HTMLElement {
- const popover = staticPopover.cloneNode(true) as HTMLElement;
-
- popover.removeAttribute('id');
+ private popoverFromTemplate(overlay:HTMLElement, template:HTMLTemplateElement):HTMLElement {
+ const popover = document.createElement('div');
this.setPopoverAttributes(popover);
+ const popoverFragment = document.importNode(template.content, true);
+ popover.appendChild(popoverFragment);
+
overlay.appendChild(popover);
return popover;
@@ -331,7 +335,7 @@ export default class HoverCardTriggerController extends ApplicationController {
private setPopoverAttributes(popover:HTMLElement) {
popover.classList.add('op-hover-card');
popover.setAttribute('popover', 'auto');
- popover.setAttribute('data-hover-card-trigger-target', 'card');
+ popover.dataset.hoverCardTriggerTarget = 'card';
}
/*
diff --git a/frontend/src/stimulus/setup.ts b/frontend/src/stimulus/setup.ts
index be2be48ec2d..a373d2d9b48 100644
--- a/frontend/src/stimulus/setup.ts
+++ b/frontend/src/stimulus/setup.ts
@@ -26,6 +26,7 @@ import EditorController from './controllers/dynamic/work-packages/activities-tab
import LazyPageController from './controllers/dynamic/work-packages/activities-tab/lazy-page.controller';
import EditablePageHeaderTitleController from './controllers/dynamic/editable-page-header-title.controller';
import WorkingHoursFormController from './controllers/dynamic/users/working-hours-form.controller';
+import DailyRemindersController from './controllers/dynamic/my/daily-reminders.controller';
import NonWorkingTimesController from './controllers/dynamic/users/non-working-times.controller';
import NonWorkingTimesFormController from './controllers/dynamic/users/non-working-times-form.controller';
@@ -86,6 +87,7 @@ OpenProjectStimulusApplication.preregister('highlight-target-element', Highlight
OpenProjectStimulusApplication.preregister('select-autosize', SelectAutosizeController);
OpenProjectStimulusApplication.preregister('editable-page-header-title', EditablePageHeaderTitleController);
OpenProjectStimulusApplication.preregister('users--working-hours-form', WorkingHoursFormController);
+OpenProjectStimulusApplication.preregister('my--daily-reminders', DailyRemindersController);
OpenProjectStimulusApplication.preregister('users--non-working-times', NonWorkingTimesController);
OpenProjectStimulusApplication.preregister('users--non-working-times-form', NonWorkingTimesFormController);
OpenProjectStimulusApplication.preregister('check-all', CheckAllController);
diff --git a/frontend/src/test.ts b/frontend/src/test.ts
index 4519f147ad5..c1296c28a42 100644
--- a/frontend/src/test.ts
+++ b/frontend/src/test.ts
@@ -1,11 +1,7 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
-// Require the reflect ES7 polyfill for JIT
-import 'zone.js'; // Included with Angular CLI.
-import 'core-js/es/reflect';
-
-import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
+import { NgModule, provideZonelessChangeDetection } from '@angular/core';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
@@ -15,15 +11,22 @@ import { registerDialogStreamAction } from 'core-turbo/dialog-stream-action';
registerDialogStreamAction();
-// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access no-explicit-any
+// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
(window as any).global = window;
// Declare global I18n shim
window.I18n = new I18n();
+@NgModule({
+ imports: [BrowserDynamicTestingModule],
+ exports: [BrowserDynamicTestingModule],
+ providers: [provideZonelessChangeDetection()],
+})
+class ZonelessBrowserDynamicTestingModule {}
+
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
- BrowserDynamicTestingModule,
+ ZonelessBrowserDynamicTestingModule,
platformBrowserDynamicTesting(),
{
teardown: { destroyAfterEach: false },
diff --git a/frontend/src/vendor/jquery.colorcontrast.js b/frontend/src/vendor/jquery.colorcontrast.js
deleted file mode 100644
index d5764452f6f..00000000000
--- a/frontend/src/vendor/jquery.colorcontrast.js
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * jQuery color contrast
- * @Author: Jochen Vandendriessche
- * @Author URI: http://builtbyrobot.com
- **/
-
-function debug(o){
- var _r = '';
- for (var k in o){
- _r += 'o[' + k + '] => ' + o[k] + '\n';
- }
- window.alert(_r);
-}
-
-(function($){
-
- var methods = {
- /*
- Function: init
-
- Initialises the color contrast
-
- Parameters:
- jQuery object - {object}
-
- Example
- > // initialise new color contrast calculator
- > $('body').colorcontrast();
-
- */
- init : function() {
- // check if we have a background image, if not, use the backgroundcolor
- if ($(this).css('background-image') == 'none') {
- $(this).colorcontrast('bgColor');
- }else{
- $(this).colorcontrast('bgImage');
- }
- return this;
- },
- bgColor : function() {
- var t = $(this);
- t.removeClass('dark light');
- t.addClass($(this).colorcontrast('calculateYIQ', t.css('background-color')));
- },
- bgImage : function() {
- var t = $(this);
- t.removeClass('dark light');
- t.addClass($(this).colorcontrast('calculateYIQ', t.colorcontrast('fetchImageColor')));
- },
- fetchImageColor : function(){
- var img = new Image();
- var src = $(this).css('background-image').replace('url(', '').replace(/'/, '').replace(')', '');
- img.src = src;
- var can = document.createElement('canvas');
- var context = can.getContext('2d');
- context.drawImage(img, 0, 0);
- data = context.getImageData(0, 0, 1, 1).data;
- return 'rgb(' + data[0] + ',' + data[1] + ',' + data[2] + ')';
- },
- calculateYIQ : function(color){
- var r = 0, g = 0, b = 0, a = 1, yiq = 0;
- if (/rgba/.test(color)){
- color = color.replace('rgba(', '').replace(')', '').split(/,/);
- r = color[0];
- g = color[1];
- b = color[2];
- a = color[3];
- }else if (/rgb/.test(color)){
- color = color.replace('rgb(', '').replace(')', '').split(/,/);
- r = color[0];
- g = color[1];
- b = color[2];
- }else if(/#/.test(color)){
- color = color.replace('#', '');
- if (color.length == 3){
- var _t = '';
- _t += color[0] + color[0];
- _t += color[1] + color[1];
- _t += color[2] + color[2];
- color = _t;
- }
- r = parseInt(color.substr(0,2),16);
- g = parseInt(color.substr(2,2),16);
- b = parseInt(color.substr(4,2),16);
- }
- yiq = ((r*299)+(g*587)+(b*114))/1000;
- return (yiq >= 128) ? 'light' : 'dark';
- }
- };
- $.fn.colorcontrast = function(method){
-
- if ( methods[method] ) {
- return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
- } else if ( typeof method === 'object' || ! method ) {
- return methods.init.apply( this, arguments );
- } else {
- $.error( 'Method ' + method + ' does not exist on jQuery color contrast' );
- }
-
- }
-
-})(jQuery);
diff --git a/frontend/src/vendor/jquery.jeditable.mini.js b/frontend/src/vendor/jquery.jeditable.mini.js
deleted file mode 100644
index ef885f06023..00000000000
--- a/frontend/src/vendor/jquery.jeditable.mini.js
+++ /dev/null
@@ -1,38 +0,0 @@
-
-(function($){$.fn.editable=function(target,options){if('disable'==target){$(this).data('disabled.editable',true);return;}
-if('enable'==target){$(this).data('disabled.editable',false);return;}
-if('destroy'==target){$(this).unbind($(this).data('event.editable')).removeData('disabled.editable').removeData('event.editable');return;}
-var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr('title',settings.tooltip);}
-settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data('event.editable',settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder);}
-$(this).bind(settings.event,function(e){if(true===$(this).data('disabled.editable')){return;}
-if(self.editing){return;}
-if(false===onedit.apply(this,[settings,self])){return;}
-e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr('title');}
-if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;}
-if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}}
-if($(this).html().toLowerCase().replace(/(;|")/g,'')==settings.placeholder.toLowerCase().replace(/(;|")/g,'')){$(this).html('');}
-self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}}
-if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}}
-var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);}
-$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;}
-content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();}
-input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit();},200);});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});}
-form.submit(function(e){if(t){clearTimeout(t);}
-e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);}
-if('PUT'==settings.method){submitdata['_method']='put';}
-$(self).html(settings.indicator);var ajaxoptions={type:'POST',data:submitdata,dataType:'html',url:settings.target,success:function(result,status){if(ajaxoptions.dataType=='html'){$(self).html(result);}
-self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr]);}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions);}}}
-$(self).attr('title',settings.tooltip);return false;});});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);}
-if(settings.tooltip){$(self).attr('title',settings.tooltip);}}}};});};$.editable={types:{defaults:{element:function(settings,original){var input=$('');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset(this);},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('');submit.html(settings.submit);}
-$(this).append(submit);}
-if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('');cancel.html(settings.cancel);}
-$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;}
-reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('');if(settings.width!='none'){input.width(settings.width);}
-if(settings.height!='none'){input.height(settings.height);}
-input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('');if(settings.rows){textarea.attr('rows',settings.rows);}else if(settings.height!="none"){textarea.height(settings.height);}
-if(settings.cols){textarea.attr('cols',settings.cols);}else if(settings.width!="none"){textarea.width(settings.width);}
-$(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('');$(this).append(select);return(select);},content:function(data,settings,original){if(String==data.constructor){eval('var json = '+data);}else{var json=data;}
-for(var key in json){if(!json.hasOwnProperty(key)){continue;}
-if('selected'==key){continue;}
-var option=$('').val(key).append(json[key]);$('select',this).append(option);}
-$('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==$.trim(original.revert)){$(this).attr('selected','selected');}});}}},addInputType:function(name,input){$.editable.types[name]=input;}};$.fn.editable.defaults={name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click.editable',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{},ajaxoptions:{}};})(jQuery);
\ No newline at end of file
diff --git a/lefthook.yml b/lefthook.yml
index ce1717e53b6..04448887bb0 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -1,8 +1,14 @@
# Lefthook configuration
#
-# Add commit hooks with `bundle exec lefthook install`
+# Install lefthook with any preferred method (see https://github.com/evilmartians/lefthook?tab=readme-ov-file#install).
+# example: `gem install lefthook`
#
-# Refer for explanation to following link:
+# Add commit hooks with `lefthook install`.
+#
+# To override any config, create a `lefthook-local.yml` file - e.g., for changing the run command
+# to be executed in a docker container context.
+#
+# Refer for explanation to the following link:
# https://github.com/evilmartians/lefthook/blob/master/docs/usage.md
pre-commit:
diff --git a/lib/api/decorators/simple_form.rb b/lib/api/decorators/simple_form.rb
index f25826d1d7a..11854028596 100644
--- a/lib/api/decorators/simple_form.rb
+++ b/lib/api/decorators/simple_form.rb
@@ -53,15 +53,15 @@ module API
end
def commit_method
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def form_url
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def resource_url
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def payload_representer
@@ -79,11 +79,11 @@ module API
end
def contract_class
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def model
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
private
diff --git a/lib/api/root_api.rb b/lib/api/root_api.rb
index abf986df567..ea028b4a116 100644
--- a/lib/api/root_api.rb
+++ b/lib/api/root_api.rb
@@ -303,6 +303,8 @@ module API
error_response ActiveRecord::RecordNotFound, ::API::Errors::NotFound, log: false
error_response ActiveRecord::StaleObjectError, ::API::Errors::Conflict, log: false
+
+ # TODO: Where do we expect this to be raised and **not** be a programming error?
error_response NotImplementedError, ::API::Errors::NotImplemented, log: false
error_response MultiJson::ParseError, ::API::Errors::ParseError
diff --git a/lib/api/utilities/endpoints/bodied.rb b/lib/api/utilities/endpoints/bodied.rb
index 185ab430e2d..dc9d29911ff 100644
--- a/lib/api/utilities/endpoints/bodied.rb
+++ b/lib/api/utilities/endpoints/bodied.rb
@@ -33,7 +33,7 @@ module API
include NamespacedLookup
def default_instance_generator(_model)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def default_params_modifier
@@ -146,11 +146,11 @@ module API
private
def present_success(_request, _call)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def present_error(_call)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def success?(call)
@@ -166,15 +166,15 @@ module API
end
def deduce_parse_representer
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def deduce_parse_service
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def deduce_render_representer
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def deduce_api_namespace
@@ -182,7 +182,7 @@ module API
end
def update_or_create
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/lib/api/utilities/endpoints/index.rb b/lib/api/utilities/endpoints/index.rb
index 80b58e1d556..780a765b241 100644
--- a/lib/api/utilities/endpoints/index.rb
+++ b/lib/api/utilities/endpoints/index.rb
@@ -44,7 +44,7 @@ module API
end
def mount
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
attr_accessor :model,
@@ -55,7 +55,7 @@ module API
private
def deduce_render_representer
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def deduce_api_namespace
diff --git a/lib/api/utilities/endpoints/modify.rb b/lib/api/utilities/endpoints/modify.rb
index d3d721a9b44..774399b320d 100644
--- a/lib/api/utilities/endpoints/modify.rb
+++ b/lib/api/utilities/endpoints/modify.rb
@@ -39,7 +39,7 @@ module API
private
def present_success(_request, _call)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def present_error(call)
diff --git a/lib/api/utilities/endpoints/show.rb b/lib/api/utilities/endpoints/show.rb
index 174c61c2fcd..65528e93f1a 100644
--- a/lib/api/utilities/endpoints/show.rb
+++ b/lib/api/utilities/endpoints/show.rb
@@ -74,7 +74,7 @@ module API
private
def deduce_render_representer
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def deduce_api_namespace
diff --git a/lib/api/utilities/meta_property.rb b/lib/api/utilities/meta_property.rb
index 07b6d4068ef..f3ecb50594a 100644
--- a/lib/api/utilities/meta_property.rb
+++ b/lib/api/utilities/meta_property.rb
@@ -60,7 +60,7 @@ module API
end
def meta_representer_class
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/lib/api/utilities/representer_to_json_cache.rb b/lib/api/utilities/representer_to_json_cache.rb
index 12a058b19da..09002ea4d0f 100644
--- a/lib/api/utilities/representer_to_json_cache.rb
+++ b/lib/api/utilities/representer_to_json_cache.rb
@@ -44,7 +44,7 @@ module API
end
def json_cache_key
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
private
diff --git a/lib/api/v3/groups/group_representer.rb b/lib/api/v3/groups/group_representer.rb
index dc2fd37c708..a7f561c9760 100644
--- a/lib/api/v3/groups/group_representer.rb
+++ b/lib/api/v3/groups/group_representer.rb
@@ -39,6 +39,14 @@ module API
"Group"
end
+ property :organizational_unit,
+ render_nil: true
+
+ associated_resource :parent,
+ v3_path: :group,
+ representer: GroupRepresenter,
+ skip_render: ->(*) { represented.parent_id.nil? }
+
link :delete,
cache_if: -> { current_user.admin? } do
{
diff --git a/lib/api/v3/groups/groups_api.rb b/lib/api/v3/groups/groups_api.rb
index 6b43b830faf..ee46a425a13 100644
--- a/lib/api/v3/groups/groups_api.rb
+++ b/lib/api/v3/groups/groups_api.rb
@@ -46,7 +46,7 @@ module API
route_param :id, type: Integer, desc: "Group ID" do
after_validation do
- @group = Group.visible(current_user).find(params[:id])
+ @group = Group.visible(current_user).includes(:group_detail).find(params[:id])
end
get &::API::V3::Utilities::Endpoints::Show
diff --git a/lib/api/v3/queries/form_representer.rb b/lib/api/v3/queries/form_representer.rb
index 011b67746d6..0c5dec11c6d 100644
--- a/lib/api/v3/queries/form_representer.rb
+++ b/lib/api/v3/queries/form_representer.rb
@@ -63,19 +63,19 @@ module API
end
def commit_action
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def commit_method
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def form_url
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def resource_url
- raise NotImplementedError, "subclass responsibility"
+ raise SubclassResponsibilityError
end
def payload_representer
diff --git a/lib/api/v3/queries/schemas/filter_dependency_representer.rb b/lib/api/v3/queries/schemas/filter_dependency_representer.rb
index eb8be59f7d8..794c08e6cc9 100644
--- a/lib/api/v3/queries/schemas/filter_dependency_representer.rb
+++ b/lib/api/v3/queries/schemas/filter_dependency_representer.rb
@@ -82,11 +82,11 @@ module API
end
def type
- raise NotImplementedError, "Subclass has to implement #type"
+ raise SubclassResponsibilityError, "Subclass has to implement #type"
end
def href_callback
- raise NotImplementedError, "Subclass has to implement #href_callback"
+ raise SubclassResponsibilityError, "Subclass has to implement #href_callback"
end
attr_accessor :operator
diff --git a/lib/api/v3/queries/schemas/principal_filter_dependency_representer.rb b/lib/api/v3/queries/schemas/principal_filter_dependency_representer.rb
index 95b3f301109..ff4f572f099 100644
--- a/lib/api/v3/queries/schemas/principal_filter_dependency_representer.rb
+++ b/lib/api/v3/queries/schemas/principal_filter_dependency_representer.rb
@@ -47,7 +47,7 @@ module API
private
def filter_query
- raise NotImplementedError, "Subclasses need to implement #filter_query"
+ raise SubclassResponsibilityError, "Subclasses need to implement #filter_query"
end
end
end
diff --git a/lib/api/v3/schemas/schema_collection_representer.rb b/lib/api/v3/schemas/schema_collection_representer.rb
index cc1cd6cdf54..221c9219a94 100644
--- a/lib/api/v3/schemas/schema_collection_representer.rb
+++ b/lib/api/v3/schemas/schema_collection_representer.rb
@@ -56,7 +56,7 @@ module API
attr_accessor :form_embedded
def model_self_link(_model)
- raise NotImplementedError, "Subclass has to implement this"
+ raise SubclassResponsibilityError
end
end
end
diff --git a/lib/api/v3/work_packages/eager_loading/base.rb b/lib/api/v3/work_packages/eager_loading/base.rb
index 874f7dcc80c..f7aaddd4e58 100644
--- a/lib/api/v3/work_packages/eager_loading/base.rb
+++ b/lib/api/v3/work_packages/eager_loading/base.rb
@@ -39,7 +39,7 @@ module API
end
def apply(_work_package)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def self.module
diff --git a/lib/api/v3/work_packages/schema/base_work_package_schema.rb b/lib/api/v3/work_packages/schema/base_work_package_schema.rb
index a0308918e3b..b9425124322 100644
--- a/lib/api/v3/work_packages/schema/base_work_package_schema.rb
+++ b/lib/api/v3/work_packages/schema/base_work_package_schema.rb
@@ -80,7 +80,7 @@ module API
private
def contract
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/lib/api/v3/work_packages/schema/work_package_schema_representer.rb b/lib/api/v3/work_packages/schema/work_package_schema_representer.rb
index bef356e401c..153fd8e6305 100644
--- a/lib/api/v3/work_packages/schema/work_package_schema_representer.rb
+++ b/lib/api/v3/work_packages/schema/work_package_schema_representer.rb
@@ -37,8 +37,7 @@ module API
cached_representer key_parts: %i[project type],
dependencies: -> {
- all_permissions_granted_to_user_under_project + [Setting.work_package_done_ratio,
- Setting.plugin_openproject_backlogs]
+ all_permissions_granted_to_user_under_project + [Setting.work_package_done_ratio]
}
custom_field_injector type: :schema_representer
@@ -385,7 +384,7 @@ module API
end
def form_config_attribute_representation(group)
- OpenProject::Cache.fetch(*form_config_attribute_cache_key(group)) do
+ OpenProject::Cache.fetch_request_cached(*form_config_attribute_cache_key(group)) do
::JSON::parse(::API::V3::WorkPackages::Schema::FormConfigurations::AttributeRepresenter
.new(group, current_user:, project: represented.project, embed_links: true)
.to_json)
diff --git a/lib/api/v3/work_packages/work_package_representer.rb b/lib/api/v3/work_packages/work_package_representer.rb
index bd2088b8712..907ef4769c3 100644
--- a/lib/api/v3/work_packages/work_package_representer.rb
+++ b/lib/api/v3/work_packages/work_package_representer.rb
@@ -345,6 +345,11 @@ module API
property :id,
render_nil: true
+ property :display_id,
+ as: :displayId,
+ render_nil: true,
+ getter: ->(*) { display_id&.to_s }
+
property :lock_version,
render_nil: true,
getter: ->(*) {
diff --git a/lib/api/v3/work_packages/work_package_sql_representer.rb b/lib/api/v3/work_packages/work_package_sql_representer.rb
index 41ec6851f16..84a7b89ec9a 100644
--- a/lib/api/v3/work_packages/work_package_sql_representer.rb
+++ b/lib/api/v3/work_packages/work_package_sql_representer.rb
@@ -76,6 +76,11 @@ module API
property :id
+ property :displayId,
+ representation: ->(*) {
+ Setting::WorkPackageIdentifier.semantic_mode_active? ? "identifier" : "id::text"
+ }
+
property :subject
property :startDate, column: :start_date,
diff --git a/lib/open_project/cache.rb b/lib/open_project/cache.rb
index edb508408b9..50ddfcdf738 100644
--- a/lib/open_project/cache.rb
+++ b/lib/open_project/cache.rb
@@ -34,6 +34,18 @@ module OpenProject
Rails.cache.fetch(CacheKey.key(*), **, &)
end
+ # Like .fetch, but caches the result in RequestStore for the
+ # lifetime of the current request.
+ # Useful when accessing many times during a request to avoid
+ # multiple cache round-trips.
+ def self.fetch_request_cached(*, **, &)
+ key = CacheKey.key(*)
+
+ RequestStore.fetch(key) do
+ Rails.cache.fetch(key, **, &)
+ end
+ end
+
def self.read(name, **, &)
Rails.cache.read(CacheKey.key(name), **, &)
end
diff --git a/lib/open_project/patches/grape_dsl_routing.rb b/lib/open_project/patches/grape_dsl_routing.rb
index 8aaf0402a7f..099a7ee4c6d 100644
--- a/lib/open_project/patches/grape_dsl_routing.rb
+++ b/lib/open_project/patches/grape_dsl_routing.rb
@@ -56,6 +56,6 @@ module OpenProject::Patches::GrapeDslRouting
end
end
-OpenProject::Patches.patch_gem_version "grape", "3.1.1" do
+OpenProject::Patches.patch_gem_version "grape", "3.2.0" do
Grape::DSL::Routing.include OpenProject::Patches::GrapeDslRouting
end
diff --git a/lib/open_project/rate_limiting/base.rb b/lib/open_project/rate_limiting/base.rb
index 2d97759e14a..fc0b784244e 100644
--- a/lib/open_project/rate_limiting/base.rb
+++ b/lib/open_project/rate_limiting/base.rb
@@ -92,15 +92,15 @@ module OpenProject
end
def discriminator(request)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def default_limit
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def default_period
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
end
end
diff --git a/lib/open_project/scm/adapters/checkout_instructions.rb b/lib/open_project/scm/adapters/checkout_instructions.rb
index e8f6f282ea7..3bbbafa2b18 100644
--- a/lib/open_project/scm/adapters/checkout_instructions.rb
+++ b/lib/open_project/scm/adapters/checkout_instructions.rb
@@ -59,7 +59,7 @@ module OpenProject
##
# Returns the checkout command for this vendor
def checkout_command
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
private
diff --git a/lib/open_project/text_formatting/filters/pattern_matcher_filter.rb b/lib/open_project/text_formatting/filters/pattern_matcher_filter.rb
index ab411734562..98096983d48 100644
--- a/lib/open_project/text_formatting/filters/pattern_matcher_filter.rb
+++ b/lib/open_project/text_formatting/filters/pattern_matcher_filter.rb
@@ -34,12 +34,14 @@ module OpenProject::TextFormatting
# Skip text nodes that are within preformatted blocks
PREFORMATTED_BLOCKS = %w(pre code).to_set
- def self.matchers
- [
- OpenProject::TextFormatting::Matchers::ResourceLinksMatcher,
- OpenProject::TextFormatting::Matchers::WikiLinksMatcher,
- OpenProject::TextFormatting::Matchers::AttributeMacros
- ]
+ class << self
+ def append_matcher(matcher)
+ matchers << matcher
+ end
+
+ def matchers
+ @matchers ||= []
+ end
end
def call
diff --git a/lib/open_project/text_formatting/formats/base_format.rb b/lib/open_project/text_formatting/formats/base_format.rb
index bfb082e301f..737858c8fce 100644
--- a/lib/open_project/text_formatting/formats/base_format.rb
+++ b/lib/open_project/text_formatting/formats/base_format.rb
@@ -32,11 +32,11 @@ module OpenProject::TextFormatting::Formats
class BaseFormat
class << self
def format
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def priority
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def helper
diff --git a/lib/open_project/text_formatting/formats/base_formatter.rb b/lib/open_project/text_formatting/formats/base_formatter.rb
index 55fe0093f1f..b9308ed8db4 100644
--- a/lib/open_project/text_formatting/formats/base_formatter.rb
+++ b/lib/open_project/text_formatting/formats/base_formatter.rb
@@ -39,7 +39,7 @@ module OpenProject::TextFormatting::Formats
end
def to_html(text)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
protected
diff --git a/lib/open_project/text_formatting/matchers/link_handlers/base.rb b/lib/open_project/text_formatting/matchers/link_handlers/base.rb
index 40178cbd16b..6dc2d2484e5 100644
--- a/lib/open_project/text_formatting/matchers/link_handlers/base.rb
+++ b/lib/open_project/text_formatting/matchers/link_handlers/base.rb
@@ -62,7 +62,7 @@ module OpenProject::TextFormatting::Matchers
##
# Test whether we should try to resolve the given link
def applicable?
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
##
@@ -70,7 +70,7 @@ module OpenProject::TextFormatting::Matchers
# and matchers.
# If nil is returned, the link remains as-is.
def call
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
def oid
diff --git a/lib/open_project/text_formatting/matchers/regex_matcher.rb b/lib/open_project/text_formatting/matchers/regex_matcher.rb
index a2cc6dea7ef..d23fd3b2caf 100644
--- a/lib/open_project/text_formatting/matchers/regex_matcher.rb
+++ b/lib/open_project/text_formatting/matchers/regex_matcher.rb
@@ -63,13 +63,13 @@ module OpenProject::TextFormatting
##
# Get the regexp that matches the content
def self.regexp
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
##
# Called with a match from the regexp on the node's content
def self.process_match(matchdata, matched_string, context)
- raise NotImplementedError
+ raise SubclassResponsibilityError
end
##
diff --git a/lib/open_project/ui/extensible_tabs.rb b/lib/open_project/ui/extensible_tabs.rb
index 7363a462453..b8c17de2d0f 100644
--- a/lib/open_project/ui/extensible_tabs.rb
+++ b/lib/open_project/ui/extensible_tabs.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
@@ -105,13 +107,13 @@ module OpenProject
name: "notifications",
partial: "users/notifications",
path: ->(params) { edit_user_path(params[:user], tab: :notifications) },
- label: :"js.notifications.settings.title"
+ label: :"my_account.notifications_and_email.tabs.notifications"
},
{
name: "reminders",
partial: "users/reminders",
path: ->(params) { edit_user_path(params[:user], tab: :reminders) },
- label: :"js.reminders.settings.title"
+ label: :"my_account.notifications_and_email.tabs.email_reminders"
}
]
end
diff --git a/lib/open_project/version.rb b/lib/open_project/version.rb
index 72977a83cb6..00cc8051491 100644
--- a/lib/open_project/version.rb
+++ b/lib/open_project/version.rb
@@ -32,8 +32,8 @@ require "open3"
module OpenProject
module VERSION # :nodoc:
MAJOR = 17
- MINOR = 3
- PATCH = 2
+ MINOR = 4
+ PATCH = 0
class << self
def revision
diff --git a/lib/primer/open_project/forms/block_note_editor.rb b/lib/primer/open_project/forms/block_note_editor.rb
index 226d9cb5d90..c89a7127ef0 100644
--- a/lib/primer/open_project/forms/block_note_editor.rb
+++ b/lib/primer/open_project/forms/block_note_editor.rb
@@ -63,7 +63,7 @@ module Primer
@blocknote_stylesheet_url = variable_asset_path("blocknote.css")
@shadow_dom_stylesheet_url = variable_asset_path("styles.css")
- @collaboration_enabled = true
+ @collaboration_enabled = Setting.real_time_text_collaboration_enabled?
end
end
end
diff --git a/lib/primer/open_project/forms/dsl/input_methods.rb b/lib/primer/open_project/forms/dsl/input_methods.rb
index 23526dc2c1e..1ed63ce8168 100644
--- a/lib/primer/open_project/forms/dsl/input_methods.rb
+++ b/lib/primer/open_project/forms/dsl/input_methods.rb
@@ -98,7 +98,8 @@ module Primer
def supports_help_texts?(model)
return @supports_help_texts if defined?(@supports_help_texts)
- @supports_help_texts = model && ::AttributeHelpText.available_types.include?(model.model_name)
+ @supports_help_texts = model.respond_to?(:model_name) &&
+ ::AttributeHelpText.available_types.include?(model.model_name)
end
end
end
diff --git a/lib/redmine/menu_manager/menu_item.rb b/lib/redmine/menu_manager/menu_item.rb
index cd508a1356f..1fb511f446a 100644
--- a/lib/redmine/menu_manager/menu_item.rb
+++ b/lib/redmine/menu_manager/menu_item.rb
@@ -39,7 +39,8 @@ class Redmine::MenuManager::MenuItem < Redmine::MenuManager::TreeNode
:partial,
:scheme,
:engine,
- :enterprise_feature
+ :enterprise_feature,
+ :show_divider_before
# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/PerceivedComplexity
@@ -60,6 +61,7 @@ class Redmine::MenuManager::MenuItem < Redmine::MenuManager::TreeNode
@icon = options[:icon]
@icon_after = options[:icon_after]
@enterprise_feature = options[:enterprise_feature]
+ @show_divider_before = options[:show_divider_before]
@caption = options[:caption]
@context = options[:context]
@html_options = options[:html].nil? ? {} : options[:html].dup
@@ -178,4 +180,8 @@ class Redmine::MenuManager::MenuItem < Redmine::MenuManager::TreeNode
def enterprise_feature_missing?
@enterprise_feature.present? && !EnterpriseToken.allows_to?(@enterprise_feature)
end
+
+ def show_divider_before?
+ @show_divider_before || false
+ end
end
diff --git a/lib/redmine/menu_manager/top_menu/user_menu.rb b/lib/redmine/menu_manager/top_menu/user_menu.rb
index ca0370ffb58..0806991d25f 100644
--- a/lib/redmine/menu_manager/top_menu/user_menu.rb
+++ b/lib/redmine/menu_manager/top_menu/user_menu.rb
@@ -141,6 +141,8 @@ module Redmine::MenuManager::TopMenu::UserMenu
def add_lateral_user_menu_items(list, link_items)
link_items.each do |item|
+ list.with_divider if item.show_divider_before?
+
list.with_item(
href: allowed_node_url(item, nil),
label: item.caption,
diff --git a/lib/subclass_responsibility_error.rb b/lib/subclass_responsibility_error.rb
new file mode 100644
index 00000000000..6175114ac26
--- /dev/null
+++ b/lib/subclass_responsibility_error.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+#-- copyright
+# OpenProject is an open source project management software.
+# Copyright (C) the OpenProject GmbH
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License version 3.
+#
+# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+# Copyright (C) 2010-2013 the ChiliProject Team
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# See COPYRIGHT and LICENSE files for more details.
+#++
+class SubclassResponsibilityError < StandardError
+ def initialize(message = nil)
+ message ||= "The subclass needs to implement this method."
+
+ super
+ end
+end
diff --git a/lib_static/redmine/i18n.rb b/lib_static/redmine/i18n.rb
index c844ec1cc6b..159bc80175d 100644
--- a/lib_static/redmine/i18n.rb
+++ b/lib_static/redmine/i18n.rb
@@ -94,6 +94,22 @@ module Redmine
format.present? ? ::I18n.l(local, format:) : ::I18n.l(local)
end
+ # Formats the given date pair as an HTML date range with each date
+ # wrapped in a