Merge branch 'dev' into user-working-times

This commit is contained in:
Klaus Zanders
2026-03-18 11:16:01 +01:00
committed by GitHub
686 changed files with 13658 additions and 2684 deletions
+2
View File
@@ -40,6 +40,8 @@ updates:
update-types: ["version-update:semver-major"]
- dependency-name: "@openproject/octicons"
- dependency-name: "@openproject/primer-view-components"
- dependency-name: "@primer/primitives"
- dependency-name: "@primer/css"
- package-ecosystem: "bundler"
directory: "/"
schedule:
+7 -14
View File
@@ -137,30 +137,25 @@ jobs:
- platform: linux/amd64
digest: amd64-slim
bim_support: false
debian_base: trixie
target: slim
runner: runner=4cpu-linux-x64
- platform: linux/amd64
digest: amd64-bim
bim_support: true
debian_base: bookworm
target: slim-bim
runner: runner=4cpu-linux-x64
- platform: linux/arm64/v8
digest: arm64-slim
debian_base: trixie
bim_support: false
target: slim
runner: runner=4cpu-linux-arm64
- platform: linux/amd64
digest: amd64-aio
debian_base: bookworm
bim_support: true
target: all-in-one
runner: runner=4cpu-linux-x64
- platform: linux/arm64/v8
digest: arm64-aio
debian_base: trixie
bim_support: false
target: all-in-one
runner: runner=4cpu-linux-arm64
@@ -197,7 +192,7 @@ jobs:
id: buildx
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
@@ -222,7 +217,7 @@ jobs:
with:
path: |
vendor/bundle
key: ${{ matrix.platform }}-${{ matrix.debian_base }}-vendor-bundle-${{ github.ref }}
key: ${{ matrix.platform }}-trixie-vendor-bundle-${{ github.ref }}
- name: Include vendor/bundle in this build (so we can use it from the cache above)
run: |
sed -i 's/vendor\/bundle//g' .dockerignore
@@ -234,15 +229,14 @@ jobs:
platforms: ${{ matrix.platform }}
target: ${{ matrix.target }}
build-args: |
DEBIAN_BASE=${{ matrix.debian_base }}
BIM_SUPPORT=${{ matrix.bim_support }}
BUILDKIT_PROGRESS=plain
pull: true
load: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},manifests_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},manifests_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/trixie,manifests_prefix=cache/${{ github.repository }}/trixie,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/trixie,manifests_prefix=cache/${{ github.repository }}/trixie,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
- name: Extract vendor/bundle from container
run: |
docker create --name bundle ${{ steps.build.outputs.imageid }}
@@ -279,12 +273,11 @@ jobs:
platforms: ${{ matrix.platform }}
target: ${{ matrix.target }}
build-args: |
DEBIAN_BASE=${{ matrix.debian_base }}
BIM_SUPPORT=${{ matrix.bim_support }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=${{ needs.setup.outputs.registry_image }},push-by-digest=true,name-canonical=true,push=true
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},manifests_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},manifests_prefix=cache/${{ github.repository }}/${{ matrix.debian_base }},region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
cache-from: type=s3,blobs_prefix=cache/${{ github.repository }}/trixie,manifests_prefix=cache/${{ github.repository }}/trixie,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }}
cache-to: type=s3,blobs_prefix=cache/${{ github.repository }}/trixie,manifests_prefix=cache/${{ github.repository }}/trixie,region=${{ env.RUNS_ON_AWS_REGION }},bucket=${{ env.RUNS_ON_S3_BUCKET_CACHE }},mode=max
- name: Export digest
run: |
mkdir -p /tmp/digests
@@ -342,7 +335,7 @@ jobs:
tags: |
${{ needs.setup.outputs.docker_tags }}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Send mail
uses: dawidd6/action-send-mail@v11
uses: dawidd6/action-send-mail@v15
with:
subject: ${{ inputs.subject }}
body: ${{ inputs.body }}
+2 -2
View File
@@ -83,7 +83,7 @@ jobs:
echo $REGISTRY:$LATEST_TAG >> $GITHUB_OUTPUT
echo 'EOF' >> $GITHUB_OUTPUT
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
@@ -112,7 +112,7 @@ jobs:
- name: Generate GHA token
id: generate-gha-token
uses: actions/create-github-app-token@v2
uses: actions/create-github-app-token@v3
with:
app-id: ${{ vars.DEPLOY_APP_ID }}
private-key: ${{ secrets.DEPLOY_APP_PRIVATE_KEY }}
+9 -2
View File
@@ -1,10 +1,11 @@
name: Package
on:
push:
tags:
- v*
branches:
- packaging/*
- release/*
- stable/*
workflow_dispatch:
schedule:
- cron: '0 3 * * *' # Daily at 03:00
@@ -42,6 +43,12 @@ jobs:
run: |
VERSION=$(ruby -r ./lib/open_project/version.rb -e "puts OpenProject::VERSION")
echo "version=$VERSION" >> $GITHUB_OUTPUT
if [[ "${{ github.ref_type }}" == "tag" ]]; then
MAJOR=$(ruby -r ./lib/open_project/version.rb -e "puts OpenProject::VERSION::MAJOR")
echo "channel=stable/${MAJOR}" >> $GITHUB_OUTPUT
else
echo "channel=${{ github.ref_name }}" >> $GITHUB_OUTPUT
fi
- name: Package
uses: pkgr/action/package@main
id: package
@@ -58,5 +65,5 @@ jobs:
target: ${{ matrix.target }}
token: ${{ secrets.PACKAGER_PUBLISH_TOKEN }}
repository: opf/openproject
channel: ${{ github.ref_name }}
channel: ${{ steps.setup.outputs.channel }}
file: ${{ steps.package.outputs.package_path }}
+18 -166
View File
@@ -20,8 +20,6 @@
- Node: `^22.21.0` (see `package.json` engines)
- Bundler: Latest 2.x
OpenProject supports two development setups: **Local** and **Docker**. Choose one based on your preference.
### Local Development Setup
```bash
@@ -34,59 +32,24 @@ bin/dev # Start all services (Rails, frontend, Good Job
### Docker Development Setup
The Docker development environment uses configurations in `docker/dev/` and the `bin/compose` wrapper script.
```bash
# Initial setup (first time only)
bin/compose setup # Installs backend and frontend dependencies
# Starting services
bin/compose start # Start backend and frontend in background
bin/compose run # Start frontend in background, backend in foreground (for debugging with pry)
# Running tests
bin/compose rspec spec/models/user_spec.rb # Run specific tests in backend-test container
# Other operations
bin/compose reset # Remove all containers and volumes (requires setup again)
bin/compose <command> # Pass any docker-compose command directly
```
**Important Docker Notes:**
- **CRITICAL**: `config/database.yml` must NOT exist when using Docker (rename or delete it)
- Most developers use a local `docker-compose.override.yml` for custom port mappings and configurations
- Copy `docker-compose.override.example.yml` to `docker-compose.override.yml` and customize as needed
- Default ports: Backend at http://localhost:3000 (or 4200 for frontend dev server)
- Services: `backend`, `frontend`, `worker`, `db`, `db-test`, `backend-test`, `cache`
- Persisted volumes: `pgdata`, `bundle`, `npm`, `tmp`, `opdata` (data survives container restarts)
- Docker build context: Uses Dockerfiles in `docker/dev/backend/` and `docker/dev/frontend/`
See [`docker/dev/AGENTS.md`](docker/dev/AGENTS.md) for full Docker setup and commands.
## Project Structure
### Key Directories
- `app/` - Rails application code
- `app/components/` - ViewComponent-based UI components (Ruby + ERB)
- `app/contracts/` - Validation and authorization contracts
- `app/controllers/` - Rails controllers
- `app/models/` - ActiveRecord models
- `app/services/` - Service objects (business logic)
- `app/workers/` - Background job workers
- `config/` - Rails configuration, routes, locales
- `db/` - Database migrations and seeds
- `frontend/src/` - Frontend code
- `frontend/src/app/` - Legacy Angular modules/components
- `frontend/src/stimulus/` - Stimulus controllers
- `frontend/src/turbo/` - Turbo integration
- `lib/` - Ruby libraries and extensions
- `lookbook/` - ViewComponent previews (https://qa.openproject-edge.com/lookbook/)
- `modules/` - OpenProject plugin modules
- `spec/` - RSpec test suite
- `spec/features/` - System/feature tests (Capybara)
- `spec/models/` - Model unit tests
- `spec/requests/` - API/integration tests
- `spec/services/` - Service tests
- `app/` — Rails application code
- `config/` — Rails configuration, routes, locales
- `db/` — Database migrations and seeds
- `docker/dev/` — Docker development environment
- `frontend/` — TypeScript/Angular/Stimulus frontend
- `lib/` — Ruby libraries and extensions
- `lookbook/` — ViewComponent previews (<https://qa.openproject-edge.com/lookbook/>)
- `modules/` — OpenProject plugin modules
- `spec/` — RSpec test suite
### Configuration Files
- `.ruby-version` - Ruby version
- `.rubocop.yml` - Ruby linting rules
- `.erb_lint.yml` - ERB template linting
@@ -95,8 +58,6 @@ bin/compose <command> # Pass any docker-compose command dire
- `package.json` / `frontend/package.json` - Node.js dependencies
- `lefthook.yml` - Git hooks configuration
## Building and Testing
### Linting (Run Before Committing)
```bash
@@ -114,125 +75,16 @@ erb_lint {files}
bundle exec lefthook install
```
### Running Tests
## Commit Messages
```bash
# Backend (RSpec) - prefer specific tests over running all
bundle exec rspec spec/models/user_spec.rb # Single file
bundle exec rspec spec/models/user_spec.rb:42 # Single line
bundle exec rspec spec/features # Directory
bundle exec rake parallel:spec # Parallel execution
# Frontend (Jasmine/Karma)
cd frontend && npm test && cd ..
```
### Debugging CI Failures
```bash
./script/github_pr_errors | xargs bundle exec rspec # Run failed tests from CI
./script/bulk_run_rspec spec/path/to/flaky_spec.rb # Run tests multiple times
```
## Code Style Guidelines
### Ruby
- Follow [Ruby community style guide](https://github.com/bbatsov/ruby-style-guide)
- Use service objects for complex business logic (return `ServiceResult`)
- Use contracts for validation and authorization
- Keep controllers thin, models focused
- Document with [YARD](https://yardoc.org/)
- Write RSpec tests for all new features
### JavaScript/TypeScript
- **New development**: Use Hotwire (Turbo + Stimulus) with server-rendered HTML
- **Legacy code**: Follow ESLint rules
- Prefer TypeScript over JavaScript
- Use [Primer Design System](https://primer.style/product/) via ViewComponent
### Templates
- Use ERB for server-rendered views
- Use ViewComponents for reusable UI (with Lookbook previews)
- Lint with erb_lint before committing
### Database Migrations
- Follow Rails migration conventions
- Migrations are "squashed" between major releases (see `docs/development/migrations/`)
### Translations
- UI strings must use translation keys (never hard-coded)
- Source translations in `**/config/locales/en.yml` can be modified directly
- Other translations managed via Crowdin
### Commit Messages
- First line: < 72 characters, then blank line, then detailed description
- Reference work packages when applicable
- Merge strategy: "Merge pull request" (not squash), except single-commit PRs can use "Rebase and merge"
## Important Commands Reference
### Local Development Commands
```bash
# Setup
bin/setup # Initial Rails setup
bin/setup_dev # Full dev environment setup
# Database
bundle exec rails g migration MigrationName # Generate a migration
bundle exec rails db:migrate # Run migrations
bundle exec rails db:rollback # Rollback last migration
bundle exec rails db:seed # Seed sample data
# Development
bin/dev # Start all services
bundle exec rails console # Rails console
bundle exec rails routes # List routes
# Testing
bundle exec rspec # Run RSpec tests
bundle exec rails parallel:spec # Parallel tests
cd frontend && npm test # Frontend tests
# Linting
bundle exec rubocop # Ruby linting
cd frontend && npx eslint src/ # JS/TS linting
erb_lint {files} # ERB linting
```
### Docker Development Commands
```bash
# Setup and lifecycle
bin/compose setup # Setup Docker environment (first time)
bin/compose start # Start all services in background
bin/compose run # Start frontend in background, backend in foreground
bin/compose reset # Remove all containers and volumes
bin/compose stop # Stop all services
bin/compose down # Stop and remove containers
# Testing
bin/compose rspec spec/models/user_spec.rb # Run specific tests
bin/compose exec backend bundle exec rspec # Run tests directly in backend container
# Development
bin/compose exec backend bundle exec rails console # Rails console
bin/compose logs backend # View backend logs
bin/compose logs -f backend # Follow backend logs
bin/compose ps # List running containers
# Database
bin/compose exec backend bundle exec rails db:migrate # Run migrations
bin/compose exec backend bundle exec rails db:seed # Seed data
# Direct docker-compose commands
bin/compose up -d # Start services
bin/compose restart backend # Restart backend service
```
## Additional Documentation
- `docs/development/` - Development documentation
- `docs/development/running-tests/` - Testing guide
- `docs/development/code-review-guidelines/` - Code review standards
- `CONTRIBUTING.md` - Contribution workflow
- `.github/copilot-instructions.md` - Extended agent instructions with troubleshooting
- `docs/development/` Development documentation
- `docs/development/running-tests/` Testing guide
- `docs/development/code-review-guidelines/` Code review standards
- `CONTRIBUTING.md` Contribution workflow
- `.github/copilot-instructions.md` Extended agent instructions with troubleshooting
+4 -4
View File
@@ -69,7 +69,7 @@ gem "scimitar", "~> 2.13"
gem "acts_as_list", "~> 1.2.6"
gem "acts_as_tree", "~> 2.9.0"
gem "awesome_nested_set", "~> 3.9.0"
gem "closure_tree", "~> 9.6.0"
gem "closure_tree", "~> 9.6.1"
gem "rubytree", "~> 2.2.0"
gem "addressable", "~> 2.8.9"
@@ -124,7 +124,7 @@ gem "sys-filesystem", "~> 1.5.0", require: false
gem "bcrypt", "~> 3.1.6"
gem "multi_json", "~> 1.19.0"
gem "oj", "~> 3.16.12"
gem "oj", "~> 3.16.16"
gem "daemons"
gem "good_job", "~> 4.13.3" # update should be done manually in sync with saas-openproject version.
@@ -208,7 +208,7 @@ gem "aws-sdk-core", "~> 3.241"
# File upload via fog + screenshots on travis
gem "aws-sdk-s3", "~> 1.213"
gem "openproject-token", "~> 8.8.0"
gem "openproject-token", "~> 8.8.2"
gem "plaintext", "~> 0.3.7"
@@ -274,7 +274,7 @@ group :test do
gem "rack_session_access"
gem "rspec", "~> 3.13.2"
# also add to development group, so 'spec' rake task gets loaded
gem "rspec-rails", "~> 8.0.3", group: :development
gem "rspec-rails", "~> 8.0.4", group: :development
# Retry failures within the same environment
gem "retriable", "~> 3.2.1"
+35 -28
View File
@@ -213,6 +213,11 @@ PATH
specs:
openproject-webhooks (1.0.0)
PATH
remote: modules/wikis
specs:
openproject-wikis (1.0.0)
PATH
remote: modules/xls_export
specs:
@@ -223,7 +228,7 @@ GEM
remote: https://rubygems.org/
specs:
Ascii85 (2.0.1)
action_text-trix (2.1.16)
action_text-trix (2.1.17)
railties
actioncable (8.1.2)
actionpack (= 8.1.2)
@@ -424,7 +429,7 @@ GEM
childprocess (5.1.0)
logger (~> 1.5)
climate_control (1.2.0)
closure_tree (9.6.0)
closure_tree (9.6.1)
activerecord (>= 7.2.0)
with_advisory_lock (>= 7.5.0)
zeitwerk (~> 2.7)
@@ -573,7 +578,7 @@ GEM
faraday (>= 1, < 3)
faraday-net_http (3.4.2)
net-http (~> 0.5)
fastimage (2.4.0)
fastimage (2.4.1)
ferrum (0.17.1)
addressable (~> 2.5)
base64 (~> 0.2)
@@ -740,7 +745,7 @@ GEM
jmespath (1.6.2)
job-iteration (1.12.0)
activejob (>= 6.1)
json (2.18.1)
json (2.19.1)
json-jwt (1.17.0)
activesupport (>= 4.2)
aes_key_wrap
@@ -767,7 +772,7 @@ GEM
addressable (~> 2.8)
childprocess (~> 5.0)
logger (~> 1.6)
lefthook (2.1.2)
lefthook (2.1.4)
letter_opener (1.10.0)
launchy (>= 2.2, < 4)
letter_opener_web (3.0.0)
@@ -868,7 +873,7 @@ GEM
racc (~> 1.4)
nokogiri (1.19.1-x86_64-linux-musl)
racc (~> 1.4)
oj (3.16.15)
oj (3.16.16)
bigdecimal (>= 3.0)
ostruct (>= 0.2)
okcomputer (1.19.1)
@@ -900,7 +905,7 @@ GEM
activesupport (>= 7.2.0)
openproject-octicons (>= 19.30.1)
view_component (>= 3.1, < 5.0)
openproject-token (8.8.0)
openproject-token (8.8.2)
activemodel
openssl (4.0.1)
openssl-signature_algorithm (1.3.0)
@@ -1083,7 +1088,7 @@ GEM
ostruct (0.6.3)
ox (2.14.23)
bigdecimal (>= 3.0)
pagy (43.3.1)
pagy (43.3.3)
json
uri
yaml
@@ -1310,14 +1315,14 @@ GEM
rspec-mocks (3.13.8)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.3)
rspec-rails (8.0.4)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-core (>= 3.13.0, < 5.0.0)
rspec-expectations (>= 3.13.0, < 5.0.0)
rspec-mocks (>= 3.13.0, < 5.0.0)
rspec-support (>= 3.13.0, < 5.0.0)
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.13.7)
@@ -1452,7 +1457,7 @@ GEM
thor (1.5.0)
thread_safe (0.3.6)
timecop (0.9.10)
timeout (0.6.0)
timeout (0.6.1)
tpm-key_attestation (0.14.1)
bindata (~> 2.4)
openssl (> 2.0)
@@ -1588,7 +1593,7 @@ DEPENDENCIES
carrierwave (~> 2.2.6)
carrierwave_direct (~> 3.0.0)
climate_control
closure_tree (~> 9.6.0)
closure_tree (~> 9.6.1)
colored2
commonmarker (~> 2.6.0)
compare-xml (~> 0.66)
@@ -1656,7 +1661,7 @@ DEPENDENCIES
my_page!
net-ldap (~> 0.20.0)
nokogiri (~> 1.19.1)
oj (~> 3.16.12)
oj (~> 3.16.16)
okcomputer (~> 1.19.1)
omniauth!
omniauth-openid-connect!
@@ -1684,9 +1689,10 @@ DEPENDENCIES
openproject-reporting!
openproject-storages!
openproject-team_planner!
openproject-token (~> 8.8.0)
openproject-token (~> 8.8.2)
openproject-two_factor_authentication!
openproject-webhooks!
openproject-wikis!
openproject-xls_export!
opentelemetry-exporter-otlp (~> 0.31.0)
opentelemetry-instrumentation-all (~> 0.90.0)
@@ -1726,7 +1732,7 @@ DEPENDENCIES
roar (~> 1.2.0)
rouge (~> 4.7.0)
rspec (~> 3.13.2)
rspec-rails (~> 8.0.3)
rspec-rails (~> 8.0.4)
rspec-retry (~> 0.6.1)
rspec-wait
rubocop
@@ -1785,7 +1791,7 @@ DEPENDENCIES
CHECKSUMS
Ascii85 (2.0.1) sha256=15cb5d941808543cbb9e7e6aea3c8ec3877f154c3461e8b3673e97f7ecedbe5a
action_text-trix (2.1.16) sha256=f645a2c21821b8449fd1d6770708f4031c91a2eedf9ef476e9be93c64e703a8a
action_text-trix (2.1.17) sha256=b44691639d77e67169dc054ceacd1edc04d44dc3e4c6a427aa155a2beb4cc951
actioncable (8.1.2) sha256=dc31efc34cca9cdefc5c691ddb8b4b214c0ea5cd1372108cbc1377767fb91969
actionmailbox (8.1.2) sha256=058b2fb1980e5d5a894f675475fcfa45c62631103d5a2596d9610ec81581889b
actionmailer (8.1.2) sha256=f4c1d2060f653bfe908aa7fdc5a61c0e5279670de992146582f2e36f8b9175e9
@@ -1848,7 +1854,7 @@ CHECKSUMS
cgi (0.5.1) sha256=e93fcafc69b8a934fe1e6146121fa35430efa8b4a4047c4893764067036f18e9
childprocess (5.1.0) sha256=9a8d484be2fd4096a0e90a0cd3e449a05bc3aa33f8ac9e4d6dcef6ac1455b6ec
climate_control (1.2.0) sha256=36b21896193fa8c8536fa1cd843a07cf8ddbd03aaba43665e26c53ec1bd70aa5
closure_tree (9.6.0) sha256=75aac8f058597b0d96f2052f1419c912e8f4e92425e56273db122913cdae5d1e
closure_tree (9.6.1) sha256=f6af11243dea13d888788ffb0fd28014bd1077abe3a4233ea1e7044e52fc6377
coderay (1.1.3) sha256=dc530018a4684512f8f38143cd2a096c9f02a1fc2459edcfe534787a7fc77d4b
coercible (1.0.0) sha256=5081ad24352cc8435ce5472bc2faa30260c7ea7f2102cc6a9f167c4d9bffaadc
color_conversion (0.1.2) sha256=99bea5fa412e1527a11389975aa6ad445ff8528ebae202c11d08c45ea2b94c96
@@ -1915,7 +1921,7 @@ CHECKSUMS
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.0) sha256=5fce375e27d3bdbb46c18dbca6ba9af29d3304801ae1eb995771c4796c5ac7e8
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
@@ -1981,7 +1987,7 @@ CHECKSUMS
iso8601 (0.13.0) sha256=298c2b15b7be5fa95a1372813d36a2257656cd8e906dfbc1f5cb409851425aa2
jmespath (1.6.2) sha256=238d774a58723d6c090494c8879b5e9918c19485f7e840f2c1c7532cf84ebcb1
job-iteration (1.12.0) sha256=0164057417750f6e9c3ed548f029f1136b18eb53975fa438b09304a525d6c6c0
json (2.18.1) sha256=fe112755501b8d0466b5ada6cf50c8c3f41e897fa128ac5d263ec09eedc9f986
json (2.19.1) sha256=dd94fdc59e48bff85913829a32350b3148156bc4fd2a95a2568a78b11344082d
json-jwt (1.17.0) sha256=6ff99026b4c54281a9431179f76ceb81faa14772d710ef6169785199caadc4cc
json-schema (4.3.1) sha256=d5e68dc32b94408d0b06ad04f9382ccbb6fe5a44910e066f8547f56c471a7825
json_schemer (2.5.0) sha256=2f01fb4cce721a4e08dd068fc2030cffd0702a7f333f1ea2be6e8991f00ae396
@@ -1990,7 +1996,7 @@ 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.2) sha256=da5a2484d68ee00d7fcc7e072e925c0246363eb20d77499d536bea209ae6ae06
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
@@ -2034,7 +2040,7 @@ CHECKSUMS
nokogiri (1.19.1-x86_64-darwin) sha256=7093896778cc03efb74b85f915a775862730e887f2e58d6921e3fa3d981e68bf
nokogiri (1.19.1-x86_64-linux-gnu) sha256=1a4902842a186b4f901078e692d12257678e6133858d0566152fe29cdb98456a
nokogiri (1.19.1-x86_64-linux-musl) sha256=4267f38ad4fc7e52a2e7ee28ed494e8f9d8eb4f4b3320901d55981c7b995fc23
oj (3.16.15) sha256=4d3324cac3e8fef54c0fa250b2af26a16dadd9f9788a1d6b1b2098b793a1b2cd
oj (3.16.16) sha256=3635b36128991796434f55da8decc0de236a323535adcb36fc04e6d0253c013d
okcomputer (1.19.1) sha256=7df770e768434816d228407f0786563827cbf34cb379933578829720cb4f1e77
omniauth (1.9.2)
omniauth-openid-connect (0.5.0)
@@ -2065,9 +2071,10 @@ CHECKSUMS
openproject-reporting (1.0.0)
openproject-storages (1.0.0)
openproject-team_planner (1.0.0)
openproject-token (8.8.0) sha256=832a493e05dcce806134faf63ae8011cc5a48422fbed9ebb552f8028912954d4
openproject-token (8.8.2) sha256=081cbff7269d92a82fa1d63e9e09c87b70d47d7aefadcbb80d1e7368bc2cf096
openproject-two_factor_authentication (1.0.0)
openproject-webhooks (1.0.0)
openproject-wikis (1.0.0)
openproject-xls_export (1.0.0)
openssl (4.0.1) sha256=e27974136b7b02894a1bce46c5397ee889afafe704a839446b54dc81cb9c5f7d
openssl-signature_algorithm (1.3.0) sha256=a3b40b5e8276162d4a6e50c7c97cdaf1446f9b2c3946a6fa2c14628e0c957e80
@@ -2131,7 +2138,7 @@ CHECKSUMS
ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912
overviews (1.0.0)
ox (2.14.23) sha256=4a9aedb4d6c78c5ebac1d7287dc7cc6808e14a8831d7adb727438f6a1b461b66
pagy (43.3.1) sha256=78e6c3e5125463b817cbe48eb5ed7b552af062c7db90bef4810d1f442ec61744
pagy (43.3.3) sha256=26b822c32ac5452f733736aa0e56bfd45d7fd02358c7d91c7d31bae61164e758
paper_trail (17.0.0) sha256=1c2842061d3874ca7015908e821e2aa14f9b982af2acb2a7974713bf79021c85
parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130
parallel_tests (4.10.1) sha256=df05458c691462b210f7a41fc2651d4e4e8a881e8190e6d1e122c92c07735d70
@@ -2215,7 +2222,7 @@ CHECKSUMS
rspec-core (3.13.6) sha256=a8823c6411667b60a8bca135364351dda34cd55e44ff94c4be4633b37d828b2d
rspec-expectations (3.13.5) sha256=33a4d3a1d95060aea4c94e9f237030a8f9eae5615e9bd85718fe3a09e4b58836
rspec-mocks (3.13.8) sha256=086ad3d3d17533f4237643de0b5c42f04b66348c28bf6b9c2d3f4a3b01af1d47
rspec-rails (8.0.3) sha256=b0a440e7a10700317d898a014852e26660867298c4076dbc3baa99c768b79dc1
rspec-rails (8.0.4) sha256=06235692fc0892683d3d34977e081db867434b3a24ae0dd0c6f3516bad4e22df
rspec-retry (0.6.2) sha256=6101ba23a38809811ae3484acde4ab481c54d846ac66d5037ccb40131a60d858
rspec-support (3.13.7) sha256=0640e5570872aafefd79867901deeeeb40b0c9875a36b983d85f54fb7381c47c
rspec-wait (1.0.2) sha256=865f921239325d3d26fc10ded4bdd485d8b58bcaaad1a28dd85ed15266b5a912
@@ -2274,7 +2281,7 @@ CHECKSUMS
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
thread_safe (0.3.6) sha256=9ed7072821b51c57e8d6b7011a8e282e25aeea3a4065eab326e43f66f063b05a
timecop (0.9.10) sha256=12ba45ce57cdcf6b1043cb6cdffa6381fd89ce10d369c28a7f6f04dc1b0cd8eb
timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af
timeout (0.6.1) sha256=78f57368a7e7bbadec56971f78a3f5ecbcfb59b7fcbb0a3ed6ddc08a5094accb
tpm-key_attestation (0.14.1) sha256=7fd4e4653a7afd0a386632ddfb05d10ecfdd47678299c5e69165bc9ae111193f
trailblazer-option (0.1.2) sha256=20e4f12ea4e1f718c8007e7944ca21a329eee4eed9e0fa5dde6e8ad8ac4344a3
tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
+1
View File
@@ -40,6 +40,7 @@ group :opf_plugins do
gem 'openproject-gantt', path: 'modules/gantt'
gem 'openproject-calendar', path: 'modules/calendar'
gem 'openproject-storages', path: 'modules/storages'
gem 'openproject-wikis', path: 'modules/wikis'
gem 'openproject-documents', path: 'modules/documents'
gem 'openproject-bim', path: 'modules/bim'
+31
View File
@@ -0,0 +1,31 @@
# App
## Directory Structure
- `app/components/` - ViewComponent-based UI components (Ruby + ERB)
- `app/contracts/` - Validation and authorization contracts
- `app/controllers/` - Rails controllers
- `app/models/` - ActiveRecord models
- `app/services/` - Service objects (business logic)
- `app/workers/` - Background job workers
## Code Style
### Ruby
- Follow [Ruby community style guide](https://github.com/bbatsov/ruby-style-guide)
- Use service objects for complex business logic (return `ServiceResult`)
- Use contracts for validation and authorization
- Keep controllers thin, models focused
- Document with [YARD](https://yardoc.org/)
- Write RSpec tests for all new features
### Templates
- Use ERB for server-rendered views
- Use ViewComponents for reusable UI (with Lookbook previews)
- Lint with erb_lint before committing
## Translations
- UI strings must use translation keys (never hard-coded)
+1
View File
@@ -0,0 +1 @@
AGENTS.md
@@ -0,0 +1,64 @@
<%#
-- 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: "change-identifiers-dialog",
title: I18n.t("admin.settings.work_packages_identifier.dialog.title"),
confirm_button_text: I18n.t("admin.settings.work_packages_identifier.dialog.confirm_button"),
cancel_button_text: I18n.t("button_close"),
size: :large,
form_arguments: {
action: admin_settings_work_packages_identifier_path,
method: :patch
}
)
) do |dialog|
dialog.with_confirmation_message do |message|
message.with_heading(tag: :h2) do
I18n.t("admin.settings.work_packages_identifier.dialog.heading")
end
message.with_description_content(
I18n.t("admin.settings.work_packages_identifier.dialog.description")
)
end
dialog.with_confirmation_check_box_content(
I18n.t("admin.settings.work_packages_identifier.dialog.checkbox_label")
)
dialog.with_additional_details(display: :none) do
hidden_field_tag("settings[work_packages_identifier]", Setting::WorkPackageIdentifier::ALPHANUMERIC)
end
end
%>
@@ -0,0 +1,40 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
module WorkPackages
module Admin
module Settings
class ChangeIdentifiersDialogComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable
end
end
end
end
@@ -0,0 +1,109 @@
<%#
-- 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::Banner.new(scheme: :warning, my: 3)) do
I18n.t(
"admin.settings.work_packages_identifier.banner.existing_identifiers_notice",
project_count: total_count
)
end
%>
<%=
render(border_box_container(mb: 3)) do |component|
component.with_header(font_weight: :bold) do
flex_layout do |header|
header.with_column(flex: 1) do
render(Primer::Beta::Text.new(font_weight: :semibold)) do
I18n.t("admin.settings.work_packages_identifier.box_header.label_project")
end
end
header.with_column(flex: 1) do
render(Primer::Beta::Text.new(font_weight: :semibold)) do
I18n.t("admin.settings.work_packages_identifier.box_header.label_previous_identifier")
end
end
header.with_column(flex: 1) do
render(Primer::Beta::Text.new(font_weight: :semibold)) do
I18n.t("admin.settings.work_packages_identifier.box_header.label_autofixed_suggestion")
end
end
header.with_column(flex: 1) do
render(Primer::Beta::Text.new(font_weight: :semibold)) do
I18n.t("admin.settings.work_packages_identifier.box_header.label_example_work_package_id")
end
end
end
end
displayed.each do |entry|
component.with_row do
flex_layout(align_items: :center) do |row|
row.with_column(flex: 1) do
render(Primer::Beta::Link.new(href: project_path(entry[:project]))) do
entry[:project].name
end
end
row.with_column(flex: 1) do
flex_layout(direction: :column) do |col|
col.with_row do
render(Primer::Beta::Text.new) { entry[:current_identifier] }
end
col.with_row do
render(Primer::Beta::Text.new(color: :danger, font_size: :small)) do
error_label(entry[:error_reason])
end
end
end
end
row.with_column(flex: 1) do
render(Primer::Beta::Text.new) { entry[:suggested_identifier] }
end
row.with_column(flex: 1) do
render(Primer::Beta::Text.new) { sample_wp_id(entry[:suggested_identifier]) }
end
end
end
end
if remaining_count.positive?
component.with_row do
render(Primer::Beta::Text.new(color: :muted)) do
I18n.t(
"admin.settings.work_packages_identifier.autofix_preview.remaining_projects",
count: remaining_count
)
end
end
end
end
%>
@@ -0,0 +1,65 @@
# 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 Admin
module Settings
class IdentifierAutofixSectionComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
DISPLAY_COUNT = WorkPackages::IdentifierAutofix::PreviewQuery::DISPLAY_COUNT
def initialize(projects_data:, total_count: projects_data.size)
super()
@total_count = total_count
@displayed = projects_data.first(DISPLAY_COUNT)
@remaining_count = [total_count - @displayed.size, 0].max
end
private
attr_reader :total_count, :displayed, :remaining_count
def error_label(error_reason)
I18n.t("admin.settings.work_packages_identifier.autofix_preview.error_#{error_reason}",
default: "")
end
# Produces a realistic-looking example work package ID for the preview table.
# The sequence number is derived deterministically from the identifier so it looks
# varied across projects but is stable across renders. Range: 1500.
def sample_wp_id(identifier)
n = (identifier.bytes.sum % 500) + 1
"#{identifier}-#{n}"
end
end
end
end
end
@@ -0,0 +1,99 @@
<%#
-- 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(**wrapper_data_attrs) do %>
<%=
settings_primer_form_with(
scope: :settings, action: :update, method: :patch,
html: change_in_progress? ? {} : { id: form_id }
) do |f|
render_inline_settings_form(f) do |form|
form.radio_button_group(
name: :work_packages_identifier,
label: I18n.t("settings.work_packages.work_package_identifier"),
required: true,
**radio_button_options
)
form.html_content do
if change_in_progress?
render(Primer::Beta::Text.new(my: 3)) do
render(Primer::Beta::Spinner.new(size: :small, mr: 2)).to_s +
I18n.t("admin.settings.work_packages_identifier.in_progress.banner_message")
end
elsif completed?
render(Primer::Alpha::Banner.new(scheme: :success, dismiss_scheme: :remove, mb: 3)) do
I18n.t("admin.settings.work_packages_identifier.success_banner")
end
end
end
end
end
%>
<% unless change_in_progress? %>
<%= tag.div(
hidden: !show_autofix_section?,
data: { admin__work_packages_identifier_target: "autofixSection" }
) do %>
<%= render(
WorkPackages::Admin::Settings::IdentifierAutofixSectionComponent.new(
projects_data:,
total_count:
)
) %>
<% end %>
<div class="op-admin-settings-form-wrapper">
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
type: :submit,
form: form_id,
hidden: show_autofix_section?,
data: { admin__work_packages_identifier_target: "saveButton" }
)
) { t("button_save") } %>
<%= render(
Primer::Beta::Button.new(
tag: :a,
href: confirm_dialog_admin_settings_work_packages_identifier_path,
scheme: :primary,
hidden: !show_autofix_section?,
data: {
turbo_stream: true,
admin__work_packages_identifier_target: "autofixButton"
}
)
) { t("admin.settings.work_packages_identifier.button_autofix") } %>
</div>
<% end %>
<% end %>
@@ -0,0 +1,110 @@
# 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 Admin
module Settings
class IdentifierSettingsFormComponent < ApplicationComponent
include OpPrimer::FormHelpers
include OpTurbo::Streamable
STATES = %i[edit change_in_progress completed].freeze
attr_reader :projects_data, :total_count, :state
def initialize(state: :edit)
raise ArgumentError, "Unknown state: #{state}" unless STATES.include?(state)
super()
@state = state
if state == :edit
result = WorkPackages::IdentifierAutofix::PreviewQuery.new.call
@projects_data = result.projects_data
@total_count = result.total_count
else
@projects_data = []
@total_count = 0
end
end
def has_problematic_projects?
total_count > 0
end
private
def form_id = "wp-identifier-settings-form"
def show_autofix_section?
state == :edit && Setting::WorkPackageIdentifier.alphanumeric? && has_problematic_projects?
end
def change_in_progress? = state == :change_in_progress
def completed? = state == :completed
def wrapper_data_attrs
if change_in_progress?
poll_for_changes_controller_attrs
else
work_package_identifier_controller_attrs
end
end
def poll_for_changes_controller_attrs
{
data: {
controller: "poll-for-changes",
poll_for_changes_url_value: url_helpers.status_admin_settings_work_packages_identifier_path,
poll_for_changes_interval_value: 5000
}
}
end
def work_package_identifier_controller_attrs
{
data: {
controller: "admin--work-packages-identifier",
admin__work_packages_identifier_has_problematic_projects_value: has_problematic_projects?
}
}
end
def radio_button_options
if change_in_progress?
{ button_options: { disabled: true } }
else
{ button_options: { data: { action: "change->admin--work-packages-identifier#handleChange" } } }
end
end
end
end
end
end
@@ -0,0 +1,85 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
module Admin::Settings
class WorkPackagesIdentifierController < ::Admin::SettingsController
include OpTurbo::ComponentStream
before_action :check_feature_flag
current_menu_item :show do
:work_packages_identifier
end
def show
@form_state = WorkPackages::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
end
end
def confirm_dialog
respond_with_dialog WorkPackages::Admin::Settings::ChangeIdentifiersDialogComponent.new
end
def status
if WorkPackages::IdentifierAutofix.job_in_progress?
head :no_content
else
replace_via_turbo_stream(
component: WorkPackages::Admin::Settings::IdentifierSettingsFormComponent.new(state: :completed)
)
respond_with_turbo_streams
end
end
private
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
+4 -2
View File
@@ -111,8 +111,10 @@ class AdminController < ApplicationController
@smtp_addr = ActionMailer::Base.smtp_settings[:address]
@safe_ip = OpenProject::SsrfProtection.safe_ip?(@smtp_addr)
if !@safe_ip
flash[:error] = I18n.t :notice_smtp_address_unsafe, address: @smtp_addr
unless @safe_ip
flash[:error] = I18n.t :notice_smtp_address_unsafe_env_hint,
address: @smtp_addr,
env_name: Settings::Definition[:ssrf_protection_ip_allowlist].env_name
redirect_to admin_settings_mail_notifications_path, status: :see_other
end
@@ -74,8 +74,8 @@ class Projects::CreationWizardController < ApplicationController
def create_work_package_artifact # rubocop:disable Metrics/AbcSize
creation_call = User.execute_as_admin(current_user) do
Projects::CreationWizard::CreateArtifactWorkPackageService
.new(user: current_user, model: @project)
Projects::CreationWizard::SubmitArtifactService
.new(user: current_user, project: @project)
.call
end
+5 -5
View File
@@ -446,11 +446,11 @@ class RepositoriesController < ApplicationController
end
def send_raw(content, path)
# Force the download
send_opt = { filename: filename_for_content_disposition(path.split("/").last) }
send_type = OpenProject::MimeType.of(path)
send_opt[:type] = send_type.to_s if send_type
send_data content, send_opt
# Force the download as binary to prevent CSP bypass
send_data content,
filename: filename_for_content_disposition(path.split("/").last),
type: "application/octet-stream",
disposition: :attachment
end
def render_text_entry
@@ -67,12 +67,11 @@ class WikiMenuItemsController < ApplicationController
def update # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
wiki_menu_setting = wiki_menu_item_params[:setting]
parent_wiki_menu_item = params[:parent_wiki_menu_item]
get_data_from_params(params)
if wiki_menu_setting == "no_item"
unless @wiki_menu_item.nil?
if @wiki_menu_item
if @wiki_menu_item.is_only_main_item?
if @page.only_wiki_page?
flash.now[:error] = t(:wiki_menu_item_delete_not_permitted)
@@ -89,12 +88,8 @@ class WikiMenuItemsController < ApplicationController
@wiki_menu_item.name = @page.slug
@wiki_menu_item.title = wiki_menu_item_params[:title] || @page_title
if wiki_menu_setting == "sub_item"
@wiki_menu_item.parent_id = parent_wiki_menu_item
elsif wiki_menu_setting == "main_item"
@wiki_menu_item.parent_id = nil
assign_wiki_menu_item_params @wiki_menu_item
end
@wiki_menu_item.parent_id = nil
assign_wiki_menu_item_params @wiki_menu_item
end
if @wiki_menu_item.destroyed? || @wiki_menu_item.save
@@ -0,0 +1,47 @@
# 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 Settings
class AggregationSettingsForm < ApplicationForm
include Redmine::I18n
settings_form do |f|
f.text_field name: :journal_aggregation_time_minutes,
type: :number,
min: 0,
input_width: :medium,
trailing_visual: { text: { text: I18n.t("datetime.units.minute_abbreviated", count: 2) } }
f.submit
end
end
end
end
@@ -0,0 +1,8 @@
<%= render(Primer::Beta::Text.new(tag: :p)) do %>
<%= link_translate("admin.journal_aggregation.caption", links: { webhook_link: url_helpers.admin_outgoing_webhooks_path }) %>
<% end %>
<%= render(Primer::OpenProject::InlineMessage.new(scheme: :warning, size: :small)) do %>
<%= render(Primer::Beta::Text.new(tag: :p)) do %>
<%= I18n.t(:text_hint_disable_with_0) %>
<% end %>
<% end %>
@@ -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 Admin
module Settings
class MailNotificationsSettingForm < ApplicationForm
include ::Settings::FormHelper
settings_form do |f|
if @deliveries
f.text_field name: :mail_from, input_width: :medium
f.check_box name: :bcc_recipients
f.check_box name: :plain_text_mail
f.select_list name: :emails_salutation,
values: [
[User.human_attribute_name(:firstname), :firstname],
[I18n.t("mail.salutation_full_name"), :name]
],
input_width: :medium
f.fieldset_group(title: "#{I18n.t(:setting_emails_header)} & #{I18n.t(:setting_emails_footer)}", mt: 4) do |fg|
fg.multi_language_text_select(name: :emails_header)
fg.multi_language_text_select(name: :emails_footer)
end
end
unless OpenProject::Configuration["email_delivery_configuration"] == "legacy"
email_methods = %i[smtp sendmail]
email_methods += [:letter_opener] if Rails.env.development?
f.fieldset_group(title: I18n.t(:text_setup_mail_configuration), mt: 4) do |fg|
fg.select_list(
name: :email_delivery_method,
values: email_methods.map { |m| [m.to_s, m] },
input_width: :small,
data: {
show_when_value_selected_target: "cause",
target_name: "email_delivery_method_settings"
}
)
end
f.group(
hidden: { true => Setting.email_delivery_method != :smtp },
data: {
show_when_value_selected_target: "effect",
target_name: "email_delivery_method_settings",
value: "smtp"
}
) do |smtp|
smtp.text_field(name: :smtp_address, input_width: :medium)
smtp.text_field(name: :smtp_port, type: :number, input_width: :xsmall)
smtp.text_field(name: :smtp_domain, input_width: :medium)
smtp.select_list(name: :smtp_authentication,
values: %i[none plain login cram_md5].map { |m| [m.to_s, m] },
input_width: :small)
smtp.text_field(name: :smtp_user_name, input_width: :medium)
smtp.text_field(name: :smtp_password, input_width: :medium)
smtp.check_box(name: :smtp_enable_starttls_auto)
smtp.check_box(name: :smtp_ssl)
end
f.group(
hidden: { true => Setting.email_delivery_method != :sendmail },
data: {
show_when_value_selected_target: "effect",
target_name: "email_delivery_method_settings",
value: "sendmail"
}
) do |sendmail|
sendmail.text_field(name: :sendmail_location)
sendmail.text_field(name: :sendmail_arguments)
end
end
f.submit
end
def initialize(deliveries:)
super()
@deliveries = deliveries
end
end
end
end
+6
View File
@@ -163,6 +163,12 @@ module Versions
end
end
f.hidden(
name: "project_id",
value: project.id,
scope_name_to_model: false
)
render_custom_fields(form: f)
f.submit(
+30 -31
View File
@@ -114,13 +114,13 @@ module RepositoriesHelper
end
def render_changes_tree(tree)
return "" if tree.nil?
return "".html_safe if tree.nil?
output = +"<ul>"
tree.keys.sort.each do |file|
style = +"change"
items = tree.keys.sort.flat_map do |file|
style = "change"
text = File.basename(file)
if s = tree[file][:s]
if (s = tree[file][:s])
style += " folder"
path_param = without_leading_slash(to_path_param(@repository.relative_path(file)))
text = link_to(h(text),
@@ -129,38 +129,40 @@ module RepositoriesHelper
rev: @changeset.identifier),
title: I18n.t(:label_folder))
output += "<li class='#{style} icon icon-folder-#{calculate_folder_action(s)}'>#{text}</li>"
output += render_changes_tree(s)
elsif c = tree[file][:c]
folder_li = content_tag(:li, text,
class: "#{style} icon icon-folder-#{calculate_folder_action(s)}")
[folder_li, render_changes_tree(s)]
elsif (c = tree[file][:c])
style += " change-#{c.action}"
path_param = without_leading_slash(to_path_param(@repository.relative_path(c.path)))
unless c.action == "D"
title_text = changes_tree_change_title c.action
text_parts = []
unless c.action == "D"
text = link_to(h(text),
entry_revision_project_repository_path(project_id: @project,
repo_path: path_param,
rev: @changeset.identifier),
title: title_text)
title: changes_tree_change_title(c.action))
end
text << raw(" - #{h(c.revision)}") if c.revision.present?
text_parts << text
text_parts << " - " << h(c.revision) if c.revision.present?
if c.action == "M"
text << raw(" (" + link_to(I18n.t(:label_diff),
diff_revision_project_repository_path(project_id: @project,
repo_path: path_param,
rev: @changeset.identifier)) + ") ")
text_parts << " (" << link_to(I18n.t(:label_diff),
diff_revision_project_repository_path(project_id: @project,
repo_path: path_param,
rev: @changeset.identifier)) << ") "
end
text << raw(" " + content_tag("span", h(c.from_path), class: "copied-from")) if c.from_path.present?
text_parts << " " << content_tag(:span, c.from_path, class: "copied-from") if c.from_path.present?
output += changes_tree_li_element(c.action, text, style)
[changes_tree_li_element(c.action, safe_join(text_parts), style)]
end
end
output += "</ul>"
output.html_safe
end.compact
content_tag(:ul, safe_join(items))
end
def to_utf8_for_repositories(str)
@@ -296,19 +298,16 @@ module RepositoriesHelper
def changes_tree_li_element(action, text, style)
icon_name = case action
when "A"
"icon-add"
when "D"
"icon-delete"
when "C"
"icon-copy"
when "R"
"icon-rename"
when "A" then "icon-add"
when "D" then "icon-delete"
when "C" then "icon-copy"
when "R" then "icon-rename"
else
"icon-arrow-left-right"
end
"<li class='#{style} icon #{icon_name}'
title='#{changes_tree_change_title(action)}'>#{text}</li>"
content_tag(:li, text,
class: "#{style} icon #{icon_name}",
title: changes_tree_change_title(action))
end
end
+2
View File
@@ -32,6 +32,8 @@ class CustomField < ApplicationRecord
include CustomField::OrderStatements
include CustomField::CalculatedValue
normalizes :name, with: OpenProject::RemoveAsciiControlCharacters
has_many :custom_values, dependent: :delete_all
# WARNING: the inverse_of option is also required in order
# for the 'touch: true' option on the custom_field association in CustomOption
+3 -1
View File
@@ -50,7 +50,9 @@ class MenuItem < ApplicationRecord
elsif is_main_item?
:main_item
else
:sub_item
# backwards compatibility for removed configuration option
# sub items are not offered anymore and are effectively not visible
:no_item
end
end
+9 -2
View File
@@ -77,7 +77,7 @@ class Project < ApplicationRecord
has_many :principals, through: :member_principals, source: :principal
has_many :calculated_value_errors, dependent: :delete_all, as: :customized
has_many :enabled_modules, dependent: :delete_all
has_many :enabled_modules, dependent: :delete_all, after_remove: :module_disabled
has_and_belongs_to_many :types, -> {
order("#{::Type.table_name}.position")
}
@@ -221,7 +221,8 @@ class Project < ApplicationRecord
:assignable_parents,
:available_custom_fields,
:available_templates,
:visible
:visible,
:with_settings
scope :has_module, ->(mod) {
where(["#{Project.table_name}.id IN (SELECT em.project_id FROM #{EnabledModule.table_name} em WHERE em.name=?)", mod.to_s])
@@ -349,4 +350,10 @@ class Project < ApplicationRecord
OpenProject::AccessControl.allowed_actions(permission)
end
end
def module_disabled(disabled_module)
OpenProject::Notifications.send(
OpenProject::Events::MODULE_DISABLED, disabled_module:
)
end
end
@@ -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 Projects::Scopes
module WithSettings
extend ActiveSupport::Concern
class_methods do
def with_settings(**kwargs)
raise ArgumentError, "Provide at least one setting" if kwargs.empty?
kwargs.reduce(all) do |scope, (key, value)|
if value.nil?
scope.where("settings->>? IS NULL", key)
else
scope.where("settings->>? = ?", key, value)
end
end
end
end
end
end
@@ -0,0 +1,40 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
class Setting
module WorkPackageIdentifier
NUMERIC = "numeric"
ALPHANUMERIC = "alphanumeric"
ALLOWED_VALUES = [NUMERIC, ALPHANUMERIC].freeze
def self.alphanumeric? = Setting[:work_packages_identifier] == ALPHANUMERIC
def self.numeric? = Setting[:work_packages_identifier] == NUMERIC
end
end
+2 -2
View File
@@ -161,7 +161,7 @@ class WikiPage < ApplicationRecord
content_to = journals.find_by(version: version_to)
content_from = journals.find_by(version: version_from)
content_to && content_from ? Wikis::Diff.new(content_to, content_from) : nil
content_to && content_from ? WikiPage::Diff.new(content_to, content_from) : nil
end
def version
@@ -171,7 +171,7 @@ class WikiPage < ApplicationRecord
def annotate(compare_version = nil)
compare_version = compare_version ? compare_version.to_i : version
c = journals.find_by(version: compare_version)
c ? Wikis::Annotate.new(c) : nil
c ? WikiPage::Annotate.new(c) : nil
end
# Returns true if usr is allowed to edit the page, otherwise false
@@ -28,7 +28,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
class Wikis::Annotate
class WikiPage::Annotate
attr_reader :lines, :content
def initialize(content)
@@ -28,7 +28,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++
class Wikis::Diff < Redmine::Helpers::Diff
class WikiPage::Diff < Redmine::Helpers::Diff
attr_reader :content_to, :content_from
def initialize(content_to, content_from)
@@ -39,7 +39,6 @@ module Projects::CreationWizard
def initialize(user:, model:, contract_class: Projects::CreateArtifactWorkPackageContract)
super(user:, contract_class:)
self.model = model
@skip_creation = false
end
def project = model
@@ -48,26 +47,7 @@ module Projects::CreationWizard
attr_accessor :artifact_work_package
def skip_creation? = @skip_creation
def skip_creation! = @skip_creation = true
def before_perform(service_call)
if WorkPackage.exists?(project.project_creation_wizard_artifact_work_package_id)
skip_creation!
end
service_call
end
def validate_contract(service_call)
return service_call if skip_creation?
super
end
def persist(service_call)
return service_call if skip_creation?
creation_call = create_artifact_work_package
creation_call.on_success do
@@ -86,7 +66,7 @@ module Projects::CreationWizard
def after_perform(service_call)
send_notification_email
return service_call if store_attachment_locally? || skip_creation?
return service_call if store_attachment_locally?
if project_storage.nil?
service_call.errors.add(:base, I18n.t("projects.wizard.create_artifact_storage_error"))
@@ -30,10 +30,6 @@
module Projects::CreationWizard
class ReuploadArtifactOnStatusChangesService
include Contracted
include ProjectsHelper
include ArtifactExporter
include Rails.application.routes.url_helpers
prepend Projects::Concerns::UpdateDemoData
attr_reader :current_user, :artifact_work_package
@@ -61,45 +57,15 @@ module Projects::CreationWizard
private
def update_artifact
call = store_artifact
call = UploadArtifactService
.new(user: current_user, project:, work_package: artifact_work_package)
.call
if call.success?
Rails.logger.debug { "Updated artifact for creation wizard in ##{artifact_work_package.id}" }
else
Rails.logger.error("Failed to process artifact change for ##{artifact_work_package.id}: ##{call.message}")
end
end
def store_artifact
if store_attachment_locally?
return add_attachment_locally
end
if project_storage.nil?
return ServiceResult.failure(message: I18n.t("projects.wizard.create_artifact_storage_error"))
end
upload_artifact_to_storage
end
def add_attachment_locally
export = create_pdf_export!
file = OpenProject::Files.create_uploaded_file(
name: export.title,
content_type: export.mime_type,
content: export.content,
binary: true
)
attachment = artifact_work_package.attachments.create(
author: current_user,
file:
)
if attachment.persisted?
ServiceResult.success(result: attachment)
else
ServiceResult.failure(result: attachment, errors: attachment.errors)
end
end
end
end
@@ -0,0 +1,73 @@
# 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::CreationWizard
class SubmitArtifactService
attr_reader :user, :project
def initialize(user:, project:)
@user = user
@project = project
end
def call
if artifact_work_package_exists?
upload_artifact
else
create_artifact_work_package
end
end
private
def artifact_work_package_exists?
WorkPackage.exists?(project.project_creation_wizard_artifact_work_package_id)
end
def create_artifact_work_package
CreateArtifactWorkPackageService
.new(user:, model: project)
.call
end
def upload_artifact
work_package = WorkPackage.find(project.project_creation_wizard_artifact_work_package_id)
upload_call = UploadArtifactService
.new(user:, project:, work_package:)
.call
service_call = ServiceResult.success(result: project)
upload_call.on_failure do
service_call.merge!(upload_call, without_success: true)
end
service_call
end
end
end
@@ -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 Projects::CreationWizard
class UploadArtifactService
include ArtifactExporter
attr_reader :user, :project, :artifact_work_package
def initialize(user:, project:, work_package:)
@user = user
@project = project
@artifact_work_package = work_package
end
def call
if store_attachment_locally?
return add_attachment_locally
end
if project_storage.nil?
return ServiceResult.failure(message: I18n.t("projects.wizard.create_artifact_storage_error"))
end
upload_artifact_to_storage
end
private
def add_attachment_locally
export = create_pdf_export!
file = OpenProject::Files.create_uploaded_file(
name: export.title,
content_type: export.mime_type,
content: export.content,
binary: true
)
attachment = artifact_work_package.attachments.create(
author: user,
file:
)
if attachment.persisted?
ServiceResult.success(result: attachment)
else
ServiceResult.failure(result: attachment, errors: attachment.errors)
end
end
end
end
@@ -0,0 +1,39 @@
# 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
def self.job_in_progress?
GoodJob::Job
.where(job_class: WorkPackages::IdentifierAutofix::ApplyHandlesJob.name)
.exists?(finished_at: nil)
end
end
end
@@ -0,0 +1,90 @@
# 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,
in_use_identifiers:,
reserved_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
@@ -0,0 +1,217 @@
# 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
# Generates a short uppercase semantic identifier for each project.
#
# Identifiers are 210 uppercase alphanumeric characters that always start
# with a letter.
#
# == Algorithm
#
# *Multi-word names* use word initials, truncated to +IDENTIFIER_LENGTH[:base]+ (5):
# "Flight Planning Algorithm" → "FPA"
# "A B C D E F G H I J K" → "ABCDE"
#
# *Single-word names* use the first +IDENTIFIER_LENGTH[:single_word]+ (3) characters:
# "Banana" → "BAN"
#
# *Accented characters* are transliterated ("Cécile" → "CEC").
# *Non-Latin scripts* that have no transliteration fall back to "PROJ".
#
# == Collision resolution
#
# When a candidate is already taken, the identifier is progressively widened
# with more characters from the name, up to +IDENTIFIER_LENGTH[:max]+ (10):
#
# Multi-word: "SC" → "STC" → "STCO" → "STRCO" → … → "STREACOMMU"
# Single-word: "BAN" → "BANA" → "BANAN" → "BANANA"
# Initials: "ABCDE" → "ABCDEF" → … → "ABCDEFGHIJ"
#
# If all expansion candidates are exhausted, a numeric suffix is appended
# as a last resort ("GO" → "GO2").
#
class ProjectIdentifierSuggestionGenerator
IDENTIFIER_LENGTH = { min: 2, max: 10, base: 5, single_word: 3 }.freeze
FALLBACK_IDENTIFIER = "PROJ"
SUFFIX_LIMIT = 10_000
def self.call(projects, reserved_identifiers: Set.new, in_use_identifiers: Set.new)
new.call(projects, reserved_identifiers:, in_use_identifiers:)
end
# Returns a single suggested identifier string for the given project name.
#
def self.suggest_identifier(name, reserved_identifiers: Set.new, in_use_identifiers: Set.new)
new.suggest_identifier(name, reserved_identifiers:, in_use_identifiers:)
end
def call(projects, reserved_identifiers:, in_use_identifiers:)
generate_suggestions(projects, reserved_identifiers:, in_use_identifiers:)
end
def suggest_identifier(name, reserved_identifiers: Set.new, in_use_identifiers: Set.new)
used = reserved_identifiers | in_use_identifiers
candidates = identifier_candidates(name)
find_unique(candidates, used)
end
private
def generate_suggestions(projects, reserved_identifiers:, in_use_identifiers:)
used_identifiers = reserved_identifiers | in_use_identifiers
projects.map do |project|
candidates = identifier_candidates(project.name)
identifier = find_unique(candidates, used_identifiers)
used_identifiers << identifier
{
project:,
current_identifier: project.identifier,
suggested_identifier: identifier
}
end
end
# Returns an ordered list of progressively longer identifier candidates
# derived from the project name. The first unique candidate wins.
def identifier_candidates(name)
words = transliterated_words(name)
return [FALLBACK_IDENTIFIER] if words.empty?
candidates = words.size == 1 ? single_word_candidates(words.first) : multi_word_candidates(words)
candidates = candidates.filter_map do |c|
stripped = ensure_starts_with_letter(c)
stripped if stripped&.length.to_i >= IDENTIFIER_LENGTH[:min]
end
candidates.presence || [FALLBACK_IDENTIFIER]
end
# Splits a name into words and transliterates each, returning only words
# that contain at least one ASCII-alphanumeric character.
def transliterated_words(name)
# Use POSIX [[:alpha:]] so accented letters (é, ñ, ü…) are kept inside
# their word rather than treated as separators by the ASCII-only [a-zA-Z].
raw_words = name.to_s.scan(/[[:alpha:][:digit:]]+/)
raw_words.filter_map do |word|
t = I18n.with_locale(:en) { I18n.transliterate(word) }
clean = t.gsub(/[^A-Za-z0-9]/, "")
clean.presence
end
end
# "Banana" → ["BAN", "BANA", "BANAN", "BANANA"]
def single_word_candidates(word)
chars = word.upcase
max_len = [chars.length, IDENTIFIER_LENGTH[:max]].min
return [] if max_len < IDENTIFIER_LENGTH[:min]
start_len = IDENTIFIER_LENGTH[:single_word].clamp(IDENTIFIER_LENGTH[:min], max_len)
(start_len..max_len).map { chars[0, it] }
end
# "Stream Communicator" → ["SC", "STC", "STCO", "STRCO", …]
# "A B C D E F G H I J K" → ["ABCDE", "ABCDEF", …, "ABCDEFGHIJ"]
#
# Starts with initials truncated to IDENTIFIER_LENGTH[:base], progressively
# includes more initials, then expands words beyond single chars.
def multi_word_candidates(words)
upcased_words = words.map(&:upcase)
candidates = initial_candidates(upcased_words)
append_expansion_candidates!(candidates, upcased_words) if candidates.last.length < IDENTIFIER_LENGTH[:max]
candidates
end
def initial_candidates(upcased_words)
initials = upcased_words.pluck(0).join[0, IDENTIFIER_LENGTH[:max]]
start = [IDENTIFIER_LENGTH[:base], initials.length].min
(start..initials.length).map { initials[0, it] }
end
# Progressively pulls more characters from each word left-to-right.
def append_expansion_candidates!(candidates, upcased_words)
chars_per_word = upcased_words.map { 1 }
loop do
expandable = upcased_words.each_index.find { |i| chars_per_word[i] < upcased_words[i].length }
break unless expandable
chars_per_word[expandable] += 1
candidate = build_candidate(upcased_words, chars_per_word)
candidates << candidate unless candidates.include?(candidate)
break if candidate.length >= IDENTIFIER_LENGTH[:max]
end
end
def build_candidate(upcased_words, chars_per_word)
parts = upcased_words.each_with_index.map { |w, i| w[0, chars_per_word[i]] }
parts.join[0, IDENTIFIER_LENGTH[:max]]
end
# Strips leading digits so identifiers always start with a letter.
# For names like "3D Printing Lab", initials "3PL" become "PL".
# This is lossy but acceptable for auto-generated suggestions.
def ensure_starts_with_letter(candidate)
candidate.sub(/\A\d+/, "").presence
end
# Iterates through expansion candidates, then falls back to numeric suffix.
# Candidates are already filtered to start with a letter and meet min length.
def find_unique(candidates, used_identifiers)
candidates.each do |candidate|
return candidate unless used_identifiers.include?(candidate)
end
base = candidates.last || FALLBACK_IDENTIFIER
numeric_suffix_fallback(base, used_identifiers)
end
def numeric_suffix_fallback(base, used_identifiers)
# Ensure the base itself starts with a letter before appending digits.
base = ensure_starts_with_letter(base) || FALLBACK_IDENTIFIER
counter = 2
loop do
raise "Could not find a unique identifier for base '#{base}' within #{SUFFIX_LIMIT} attempts" \
if counter > SUFFIX_LIMIT
suffix = counter.to_s
candidate = "#{base[0, IDENTIFIER_LENGTH[:max] - suffix.length]}#{suffix}"
return candidate unless used_identifiers.include?(candidate)
counter += 1
end
end
end
end
end
@@ -40,25 +40,13 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
<%= styled_form_tag(admin_settings_aggregation_path, method: :patch) do %>
<div class="form--field">
<%= setting_number_field :journal_aggregation_time_minutes,
unit: t(:label_minute_plural),
min: 0,
container_class: "-xslim" %>
<span class="form--field-instructions">
<%= t(
:"admin.journal_aggregation.explanation.text",
webhook_link: link_to(
t(:"admin.journal_aggregation.explanation.link"),
admin_outgoing_webhooks_path,
target: "_blank"
)
).html_safe %>
<br>
<%= t(:text_hint_disable_with_0) %>
</span>
</div>
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<% end %>
<%=
settings_primer_form_with(
url: admin_settings_aggregation_path,
scope: :settings,
method: :patch,
data: { turbo: false }
) do |form|
render Admin::Settings::AggregationSettingsForm.new(form)
end
%>
@@ -40,40 +40,38 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
<%= styled_form_tag(
admin_settings_date_format_path,
method: :patch,
class: "op-date-format-admin-settings"
) do %>
<%=
settings_primer_form_with(
url: admin_settings_date_format_path,
scope: :settings,
method: :patch,
class: "op-date-format-admin-settings",
data: { turbo: false }
) do |form|
render_inline_settings_form(form) do |f|
f.select_list name: :date_format,
values: Settings::Definition[:date_format].allowed.collect { |f| [Date.today.strftime(f), f] },
input_width: :medium,
include_blank: t(:label_language_based)
<section class="form--section">
f.select_list name: :time_format,
values: Settings::Definition[:time_format].allowed.collect { |f| [Time.now.strftime(f), f] },
input_width: :medium,
include_blank: t(:label_language_based)
<div class="form--field">
<%= setting_select :date_format,
Settings::Definition[:date_format].allowed.collect { |f| [Date.today.strftime(f), f] },
blank: :label_language_based,
container_class: "-wide" %>
</div>
f.select_list name: :start_of_week,
values: [[day_name(1), 1], [day_name(6), 6], [day_name(7), 7]],
input_width: :medium,
include_blank: t(:label_language_based)
<div class="form--field">
<%= setting_select :time_format,
Settings::Definition[:time_format].allowed.collect { |f| [Time.now.strftime(f), f] },
blank: :label_language_based,
container_class: "-wide" %>
</div>
f.select_list name: :first_week_of_year,
values: [[day_name(1), 1], [day_name(4), 4]],
input_width: :medium,
include_blank: t(:label_language_based),
caption: t("settings.date_format.first_week_of_year_text_html",
link: OpenProject::Static::Links.url_for(:date_format_settings_documentation))
<div class="form--field">
<%= setting_select :start_of_week, [[day_name(1), "1"], [day_name(6), "6"], [day_name(7), "7"]], blank: :label_language_based, container_class: "-wide" %>
</div>
<div class="form--field">
<%= setting_select :first_week_of_year, [[day_name(1), "1"], [day_name(4), "4"]], blank: :label_language_based, container_class: "-wide" %>
<div class="form--field-instructions">
<p><%= t("settings.date_format.first_week_of_year_text_html", link: OpenProject::Static::Links.url_for(:date_format_settings_documentation)) %></p>
</div>
</div>
</section>
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<% end %>
f.submit
end
end
%>
@@ -40,20 +40,20 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
<%= styled_form_tag(
admin_settings_icalendar_path,
method: :patch,
class: "op-icalendar-admin-settings"
) do %>
<%=
settings_primer_form_with(
url: admin_settings_icalendar_path,
scope: :settings,
method: :patch,
class: "op-icalendar-admin-settings",
data: { turbo: false }
) do |form|
render_inline_settings_form(form) do |f|
f.check_box name: :ical_enabled,
caption: t("settings.icalendar.enable_subscriptions_text_html",
link: OpenProject::Static::Links.url_for(:ical_docs))
<section class="form--section">
<div class="form--field">
<%= setting_check_box :ical_enabled, size: 6 %>
<div class="form--field-instructions">
<p><%= t("settings.icalendar.enable_subscriptions_text_html", link: OpenProject::Static::Links.url_for(:ical_docs)) %></p>
</div>
</div>
</section>
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<% end %>
f.submit
end
end
%>
@@ -40,21 +40,26 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
<%= styled_form_tag(admin_settings_incoming_mails_path, method: :patch) do %>
<section class="form--section">
<div class="form--field">
<%= setting_text_area :mail_handler_body_delimiters, rows: 5, container_class: "-wide" %>
<div class="form--field-instructions"><%= t(:text_line_separated) %></div>
</div>
<div class="form--field">
<%= setting_text_field :mail_handler_body_delimiter_regex, container_class: "-wide" %>
<div class="form--field-instructions"><%= t(:text_regexp_multiline) %></div>
</div>
<div class="form--field">
<%= setting_text_area :mail_handler_ignore_filenames, rows: 5, container_class: "-wide" %>
<div class="form--field-instructions"><%= t("incoming_mails.ignore_filenames") %></div>
</div>
</section>
<%=
settings_primer_form_with(
url: admin_settings_incoming_mails_path,
scope: :settings,
method: :patch,
data: { turbo: false }
) do |form|
render_inline_settings_form(form) do |f|
f.text_area name: :mail_handler_body_delimiters,
rows: 5,
caption: t(:text_line_separated)
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<% end %>
f.text_field name: :mail_handler_body_delimiter_regex,
caption: t(:text_regexp_multiline)
f.text_area name: :mail_handler_ignore_filenames,
rows: 5,
caption: t("incoming_mails.ignore_filenames")
f.submit
end
end
%>
@@ -40,98 +40,34 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
<%=
styled_form_tag(
admin_settings_mail_notifications_path,
method: :patch,
data: { controller: "show-when-value-selected" }
) do
%>
<% if @deliveries %>
<section class="form--section">
<div class="form--field"><%= setting_text_field :mail_from, size: 60, container_class: "-middle" %></div>
<div class="form--field"><%= setting_check_box :bcc_recipients %></div>
<div class="form--field"><%= setting_check_box :plain_text_mail %></div>
<div class="form--field">
<%= setting_select :emails_salutation,
[
[User.human_attribute_name(:firstname), :firstname],
[t("mail.salutation_full_name"), :name]
],
container_class: "-middle" %>
</div>
</section>
<fieldset id="emails_decorators" class="form--fieldset">
<legend class="form--fieldset-legend"><%= t(:setting_emails_header) %>
& <%= I18n.t(:setting_emails_footer) %></legend>
<%= render Settings::TextSettingComponent.new(I18n.locale, name: "emails_header") %>
<%= render Settings::TextSettingComponent.new(I18n.locale, name: "emails_footer") %>
</fieldset>
<% else %>
<div class="nodata">
<%= simple_format(t(:text_email_delivery_not_configured)) %>
</div>
<% end %>
<%
email_methods = %i[smtp sendmail]
email_methods << :letter_opener if Rails.env.development?
<% unless @deliveries %>
<%=
render Primer::Alpha::Banner.new(scheme: :default) do
t(:text_email_delivery_not_configured)
end
%>
<%= content_tag :fieldset, class: "form--fieldset" do %>
<legend class="form--fieldset-legend"><%= t(:text_setup_mail_configuration) %></legend>
<div class="form--field">
<%=
setting_select(
:email_delivery_method,
email_methods,
container_class: "-slim",
data: {
show_when_value_selected_target: "cause",
target_name: "email_delivery_method_settings"
}
)
%>
</div>
<div
data-show-when-value-selected-target="effect"
data-target-name="email_delivery_method_settings"
data-value="smtp"
<%= "hidden" unless Setting.email_delivery_method == :smtp %>>
<div class="form--field"><%= setting_text_field :smtp_address, container_class: "-middle" %></div>
<div class="form--field"><%= setting_text_field :smtp_port, size: 6, container_class: "-xslim" %></div>
<div class="form--field"><%= setting_text_field :smtp_domain, container_class: "-middle" %></div>
<div class="form--field"><%= setting_select(:smtp_authentication, %i[none plain login cram_md5], container_class: "-slim") %></div>
<div class="form--field"><%= setting_text_field :smtp_user_name, container_class: "-middle" %></div>
<div class="form--field"><%= setting_password :smtp_password, container_class: "-middle" %></div>
<div class="form--field"><%= setting_check_box :smtp_enable_starttls_auto %></div>
<div class="form--field"><%= setting_check_box :smtp_ssl %></div>
</div>
<div
data-show-when-value-selected-target="effect"
data-target-name="email_delivery_method_settings"
data-value="sendmail"
<%= "hidden" unless Setting.email_delivery_method == :sendmail %>>
<div class="form--field"><%= setting_text_field :sendmail_location %></div>
<div class="form--field"><%= setting_text_field :sendmail_arguments %></div>
</div>
<div
data-show-when-value-selected-target="effect"
data-target-name="email_delivery_method_settings"
data-value="letter_opener"
<%= "hidden" unless Setting.email_delivery_method == :letter_opener %>>
<p>Letter opener is used to render emails as a file in your Rails tmp folder. Mails will automatically open in
your browser if supported.</p>
</div>
<% end unless OpenProject::Configuration['email_delivery_configuration'] == 'legacy' %>
<%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
<% if @deliveries %>
<div style="float:none;display:inline-block;font-weight:bold;">
<%= link_to t(:label_send_test_email),
{ controller: "/admin", action: "test_email" },
data: { turbo_method: :post } %>
</div>
<% end %>
<% end %>
<%=
settings_primer_form_with(
url: admin_settings_mail_notifications_path,
scope: :settings,
method: :patch,
data: { turbo: false,
controller: "show-when-value-selected" }
) do |form|
render Admin::Settings::MailNotificationsSettingForm.new(form, deliveries: @deliveries)
end
%>
<% if @deliveries %>
<%= render Primer::Beta::Link.new(
href: test_email_admin_index_path,
data: { turbo_method: :post },
font_weight: :bold,
display: :block,
mt: 3
) do
t(:label_send_test_email)
end %>
<% end %>
@@ -0,0 +1,48 @@
<%#
-- copyright
OpenProject is an open source project management software.
Copyright (C) the OpenProject GmbH
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 3.
OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
Copyright (C) 2006-2013 Jean-Philippe Lang
Copyright (C) 2010-2013 the ChiliProject Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
See COPYRIGHT and LICENSE files for more details.
++#
%>
<% html_title t(:label_administration), t(:label_work_package_plural), t(:label_identifier) -%>
<%=
render Primer::OpenProject::PageHeader.new do |header|
header.with_title { t(:label_identifier) }
header.with_breadcrumbs(
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_work_packages_identifier_path, text: t(:label_work_package_plural), skip_for_mobile: true },
t(:label_identifier)]
)
header.with_description do
t("admin.settings.work_packages_identifier.page_header.description")
end
end
%>
<%= render(WorkPackages::Admin::Settings::IdentifierSettingsFormComponent.new(state: @form_state)) %>
+1 -1
View File
@@ -74,7 +74,7 @@ See COPYRIGHT and LICENSE files for more details.
</a>
<%= render_top_menu_left %>
</div>
<div class="op-app-header--center">
<div class="op-app-header--center op-app-header--center_mobile-end">
<%= render_top_menu_center %>
</div>
<div class="op-app-header--end">
+7 -2
View File
@@ -39,8 +39,13 @@ See COPYRIGHT and LICENSE files for more details.
data: body_data_attributes(local_assigns) do %>
<div id="wrapper">
<header class="op-app-header<%= " op-app-header_development" if OpenProject::Configuration.development_highlight_enabled? %>">
<div class="op-app-header--center op-logo">
<%= link_to(I18n.t("label_home"), home_url, class: "op-logo--link") %>
<div class="op-app-header--center">
<div class="op-logo">
<%= link_to(I18n.t("label_home"), configurable_home_url, class: "op-logo--link") %>
</div>
<% if CustomStyle.current&.logo_mobile.present? || !custom_logo? %>
<%= link_to(I18n.t("label_home"), configurable_home_url, class: ["op-logo--icon", "op-logo--link"].compact) %>
<% end %>
</div>
</header>
<main id="content-wrapper">
-6
View File
@@ -57,12 +57,6 @@ See COPYRIGHT and LICENSE files for more details.
<%= form.radio_button "setting", :main_item %>
<%= form.label "setting_main_item", t(:label_wiki_show_menu_item) %>
</p>
<p>
<% disabled = @parent_menu_item_options.empty? %>
<%= form.radio_button "setting", :sub_item, disabled: disabled %>
<%= form.label "setting_sub_item", t(:label_wiki_show_submenu_item), { id: "with-select" } %>
<%= select_tag "parent_wiki_menu_item", options_for_select(@parent_menu_item_options, @selected_parent_menu_item_id), disabled: disabled %>
</p>
</fieldset>
<p>
<%= styled_button_tag t(:button_save), method: :post,
@@ -68,11 +68,12 @@ 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
service_call = Projects::CreateService
.new(user:)
.call(
name: jira_project.payload.fetch("name"),
identifier: jira_project.payload.fetch("key").downcase,
identifier:,
description: jira_project.payload.fetch("description"),
active: true,
public: false,
@@ -231,6 +232,11 @@ module Import
raise service_call.message
end
end
elsif (error = service_call.errors.find { |e| e.attribute == :identifier && e.type == :taken }) && error.present?
taken_identifier = error.options[:value]
project = Project.find_by!(identifier: taken_identifier)
raise "You are trying to import a project with already used " \
"identifier: #{taken_identifier}. Existing project: #{project}."
else
raise service_call.message
end
@@ -0,0 +1,40 @@
# frozen_string_literal: true
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
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
end
end
+1 -2
View File
@@ -1,4 +1,3 @@
#!/bin/bash
docker build -t openproject/openproject:$(git rev-parse --abbrev-ref HEAD | tr '/' '-') --build-arg DEBIAN_BASE=bookworm -f docker/prod/Dockerfile .
docker build -t openproject/openproject:$(git rev-parse --abbrev-ref HEAD | tr '/' '-') -f docker/prod/Dockerfile .
+14
View File
@@ -0,0 +1,14 @@
# Config
## Translations
- UI strings must use translation keys (never hard-coded)
- Source translations in `**/config/locales/en.yml` can be modified directly
- Other translations managed via Crowdin
```bash
bundle exec i18n-tasks missing # Show missing translation keys
bundle exec i18n-tasks unused # Show unused translation keys
bundle exec i18n-tasks normalize # Fix/normalize translation files
bundle exec i18n-tasks check-consistent-interpolations # Check interpolation consistency
```
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+21 -4
View File
@@ -1321,6 +1321,15 @@ module Settings
work_packages_bulk_request_limit: {
default: 10
},
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 " \
"(e.g. 'PROJA-123').",
format: :string,
allowed: -> { Setting::WorkPackageIdentifier::ALLOWED_VALUES },
default: "numeric"
},
work_package_list_default_highlighted_attributes: {
default: ["status", "priority", "due_date"],
allowed: -> {
@@ -1400,6 +1409,14 @@ module Settings
end
end
def env_name
self.class.env_name(self)
end
def possible_env_names
self.class.possible_env_names(self)
end
def derive_default(default)
@default = default.is_a?(Hash) ? default.deep_stringify_keys : default
@default.freeze
@@ -1633,8 +1650,8 @@ module Settings
env_var_hash_part
.scan(/(?:[a-zA-Z0-9]|__)+/)
.map do |seg|
unescape_underscores(seg.downcase)
end
unescape_underscores(seg.downcase)
end
end
# takes the path provided and transforms it into a deeply nested hash
@@ -1689,8 +1706,6 @@ module Settings
].compact
end
public :possible_env_names
def env_name_nested(definition)
"#{ENV_PREFIX}#{definition.name.upcase.gsub('_', '__')}"
end
@@ -1709,6 +1724,8 @@ module Settings
definition.env_alias.upcase
end
public :possible_env_names, :env_name
##
# Extract the configuration value from the given environment variable
# using YAML.
+10 -1
View File
@@ -31,7 +31,16 @@
# TODO: check if this can be postponed and if some plugins can make use of the ActiveSupport.on_load hooks
# Loads the core plugins located in lib_static/plugins
Dir.glob(Rails.root.join("lib_static/plugins/*")).each do |directory|
CORE_PLUGINS = %w[
acts_as_attachable
acts_as_customizable
acts_as_event
acts_as_journalized
acts_as_searchable
verification
].freeze
CORE_PLUGINS.map { |name| Rails.root.join("lib_static/plugins", name).to_s }.each do |directory|
if File.directory?(directory)
lib = File.join(directory, "lib")
+5
View File
@@ -71,3 +71,8 @@ OpenProject::FeatureDecisions.add :scrum_projects,
OpenProject::FeatureDecisions.add :user_working_times,
description: "Enables tracking of user working hours and non-working days."
OpenProject::FeatureDecisions.add :semantic_work_package_ids,
description: "Enables the use of semantic work package IDs, " \
"in the schema <project identifier>-<sequence number>. " \
"See #71626 for details."
+6
View File
@@ -413,6 +413,12 @@ Redmine::MenuManager.map :admin_menu do |menu|
caption: IssuePriority.model_name.human(count: :other),
parent: :admin_work_packages
menu.push :work_packages_identifier,
{ controller: "/admin/settings/work_packages_identifier", action: :show },
if: ->(_) { OpenProject::FeatureDecisions.semantic_work_package_ids_active? && User.current.admin? },
caption: :label_identifier,
parent: :admin_work_packages
menu.push :progress_tracking,
{ controller: "/admin/settings/progress_tracking", action: :show },
if: ->(_) { User.current.admin? },
+2 -1
View File
@@ -407,7 +407,8 @@ Rails.application.reloader.to_prepare do
wpt.permission :add_work_package_attachments,
{},
permissible_on: %i[work_package project],
dependencies: :view_work_packages
dependencies: :view_work_packages,
contract_actions: { work_package_attachments: %i[create] }
# WorkPackage categories
wpt.permission :manage_categories,
+5
View File
@@ -31,4 +31,9 @@
# From v1.0 to v2.0 of store_attribute, the value for store_attribute_unset_values_fallback_to_default changed from
# false to true. This initializer sets it back to false to keep the behavior consistent with the previous version.
# Keeping this false also avoids a subtle dirty-tracking issue with the `default:` option: assigning the
# default value to an attribute that has never been persisted is a no-op from dirty-tracking's perspective,
# so the store column is never written. Concretely, `create(:project, sprint_sharing: "no_sharing")` leaves
# `project.settings` as `{}` because "no_sharing" equals the declared default and is never saved.
StoreAttribute.store_attribute_unset_values_fallback_to_default = false
+3 -11
View File
@@ -107,9 +107,8 @@ af:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ af:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anoniem"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Net vir die dinge wat ek dophou of betrokke in is"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ af:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Begin bladsy"
label_work: "Work"
label_work_package: "Werkspakket"
@@ -4217,7 +4209,7 @@ af:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ ar:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -4114,12 +4113,6 @@ ar:
label_user_named: "User %{name}"
label_user_activity: "نشاط %{value}'s"
label_user_anonymous: "مجهول"
label_user_mail_option_all: "من أجل أي حدث في كافة المشاريع"
label_user_mail_option_none: "لا يوجد أحداث"
label_user_mail_option_only_assigned: "فقط لأشياء موكلة لي"
label_user_mail_option_only_my_events: "فقط لأشياء أشاهدها أو أشارك فيها"
label_user_mail_option_only_owner: "فقط لأشياء أملكها"
label_user_mail_option_selected: "من أجل أي حدث في المشاريع المحددة فقط"
label_user_menu: "User menu"
label_user_new: "مستخدم جديد"
label_user_plural: "المستخدمين"
@@ -4159,7 +4152,6 @@ ar:
label_wiki_show_index_page_link: "إظهار عنصر القائمة الفرعية ’جدول المحتويات’"
label_wiki_show_menu_item: "إظهار كعنصر قائمة في مشروع الملاحة"
label_wiki_show_new_page_link: "إظهار عنصر القائمة الفرعية 'إنشاء صفحة فرعية جديدة'"
label_wiki_show_submenu_item: "إظهار كعنصر قائمة فرعية من "
label_wiki_start: "صفحة البداية"
label_work: "Work"
label_work_package: "مجموعة العمل"
@@ -4445,7 +4437,7 @@ ar:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "لم يتم حذف المشروع."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "اتصال ناجح."
notice_successful_create: "إنشاء ناجح."
notice_successful_delete: "حذف ناجح."
+3 -11
View File
@@ -107,9 +107,8 @@ az:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ az:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ az:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ az:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ be:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -4002,12 +4001,6 @@ be:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -4047,7 +4040,6 @@ be:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4331,7 +4323,7 @@ be:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ bg:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ bg:
label_user_named: "Потребител %{name}"
label_user_activity: "дейност на %{value}"
label_user_anonymous: "Анонимен"
label_user_mail_option_all: "За всяко събитие на всичките ми проекти"
label_user_mail_option_none: "Няма събития"
label_user_mail_option_only_assigned: "Само за неща, възложени на мен"
label_user_mail_option_only_my_events: "Само за неща, които наблюдавам или съм включен в тях"
label_user_mail_option_only_owner: "Само за неща, на които аз съм собственик"
label_user_mail_option_selected: "За всяко събитие само в избраните проекти"
label_user_menu: "User menu"
label_user_new: "Нов потребител"
label_user_plural: "Потребители"
@@ -3935,7 +3928,6 @@ bg:
label_wiki_show_index_page_link: "Показване на елемент от подменюто \"Съдържание\""
label_wiki_show_menu_item: "Покажи като меню в проектната навигация"
label_wiki_show_new_page_link: "Показване на елемент от подменю \"Създай нова подстраница\""
label_wiki_show_submenu_item: "Покажи като елемент от подменюто на "
label_wiki_start: "Начална страница"
label_work: "Работа"
label_work_package: "Работен пакет"
@@ -4217,7 +4209,7 @@ bg:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Проектът не е изтрит."
notice_project_not_found: "Проектът не е намерен."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Успешна връзка."
notice_successful_create: "Успешно създаване."
notice_successful_delete: "Успешно изтриване."
+3 -11
View File
@@ -107,9 +107,8 @@ ca:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Les accions individuals d'un sol usuari (per exemple actualitzar dos cops un paquet de treball) seran agregades en una sola acció si la diferència temporal és menor a l'especificada. Aquests seran exposats com una acció individual dins l'aplicació. Això, també reduïra el número d'emails enviats i el retràs en el %{webhook_link} ja que les notificacións també seran retrasades."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3887,12 +3886,6 @@ ca:
label_user_named: "Usuari %{name}"
label_user_activity: "Activitat de %{value}"
label_user_anonymous: "Anònim"
label_user_mail_option_all: "Per qualsevol esdeveniment en tots els meus projectes"
label_user_mail_option_none: "No hi ha esdeveniments"
label_user_mail_option_only_assigned: "Només pels objectes on estic assignat"
label_user_mail_option_only_my_events: "Només pels objectes que estic en observant o involucrat"
label_user_mail_option_only_owner: "Només pels objectes dels que en sóc propietari"
label_user_mail_option_selected: "Només per qualsevol esdeveniment dels projectes seleccionats"
label_user_menu: "User menu"
label_user_new: "Nou usuari"
label_user_plural: "Usuaris"
@@ -3932,7 +3925,6 @@ ca:
label_wiki_show_index_page_link: "Mostra l'element del submenú 'Taula de continguts'"
label_wiki_show_menu_item: "Mostrar com a element de menú en la navegació del projecte"
label_wiki_show_new_page_link: "Mostra l'element submenú 'Crea nova pàgina fill'"
label_wiki_show_submenu_item: "Mostrar com element de submenú de "
label_wiki_start: "Pàgina d'inici"
label_work: "Treball"
label_work_package: "Paquet de treball"
@@ -4211,7 +4203,7 @@ ca:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "El projecte no s'ha suprimit."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "S'ha connectat correctament."
notice_successful_create: "Creat correctament."
notice_successful_delete: "Esborrat correctament."
+3 -11
View File
@@ -107,9 +107,8 @@ ckb-IR:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ ckb-IR:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ ckb-IR:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ ckb-IR:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+4 -12
View File
@@ -107,9 +107,8 @@ cs:
trial: "Trial"
jemalloc_allocator: Jemalloc alokátor paměti
journal_aggregation:
explanation:
text: "Individuální akce/úpravy uživatele (např. dvojnásobná aktualizace pracovního balíčku se sečtou do jediné akce, pokud je jejich časový rozdíl menší než stanovený čas. Budou zobrazeny jako jedna akce v rámci aplikace. Toto také zpozdí oznámení o stejný čas a sníží tak počet zasílaných e-mailů a ovlivní se také zpoždění na adrese %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3960,7 +3959,7 @@ cs:
label_subproject: "Podprojekt"
label_subproject_new: "Nový podprojekt"
label_subproject_plural: "Podprojekty"
label_subitems: "Subitems"
label_subitems: "Dílčí položky"
label_subtask_plural: "Podúkoly"
label_summary: "Souhrn"
label_system: "Systém"
@@ -4002,12 +4001,6 @@ cs:
label_user_named: "Uživatel %{name}"
label_user_activity: "Aktivita %{value}"
label_user_anonymous: "Anonymní"
label_user_mail_option_all: "Pro všechny události všech mých projektů"
label_user_mail_option_none: "Žádné události"
label_user_mail_option_only_assigned: "Pouze pro věci, na které jsem přidělen"
label_user_mail_option_only_my_events: "Pouze pro věci, které sleduji nebo jsem v nich zapojen"
label_user_mail_option_only_owner: "Pouze pro věci, kde jsem majitelem"
label_user_mail_option_selected: "Pouze pro každou událost na vybraných projektech"
label_user_menu: "User menu"
label_user_new: "Nový uživatel"
label_user_plural: "Uživatelé"
@@ -4047,7 +4040,6 @@ cs:
label_wiki_show_index_page_link: "Zobrazit položku podnabídky 'Obsah'"
label_wiki_show_menu_item: "Zobrazit jako položku nabídky navigaci projektu"
label_wiki_show_new_page_link: "Zobrazit položku menu \"Vytvořit novou podřízenou stránku\""
label_wiki_show_submenu_item: "Zobrazit jako položku podnabídky "
label_wiki_start: "Úvodní stránka"
label_work: "Práce"
label_work_package: "Pracovní balíček"
@@ -4330,7 +4322,7 @@ cs:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projekt nebyl odstraněn."
notice_project_not_found: "Projekt nebyl nalezen."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Úspěšné připojení."
notice_successful_create: "Úspěšné vytvoření."
notice_successful_delete: "Úspěšné odstranění."
+3 -11
View File
@@ -107,9 +107,8 @@ da:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3888,12 +3887,6 @@ da:
label_user_named: "User %{name}"
label_user_activity: "%{value}s aktivitet"
label_user_anonymous: "Anonymt"
label_user_mail_option_all: "For enhver hændelse i alle mine projekter"
label_user_mail_option_none: "Ingen hændelser"
label_user_mail_option_only_assigned: "Kun i forbindelse med det jeg er tilknyttet"
label_user_mail_option_only_my_events: "Kun for det jeg fører tilsyn med eller er involveret i"
label_user_mail_option_only_owner: "Kun for det jeg er ejer af"
label_user_mail_option_selected: "Kun for hændelser i de valgte projekter"
label_user_menu: "User menu"
label_user_new: "Ny bruger"
label_user_plural: "Brugere"
@@ -3933,7 +3926,6 @@ da:
label_wiki_show_index_page_link: "Vis undermenupunkt 'Indhold'"
label_wiki_show_menu_item: "Vis som menupunkt i projektnavigeringen"
label_wiki_show_new_page_link: "Vis undermenupunktet 'Opret ny underside'"
label_wiki_show_submenu_item: "Vis som punkt i undermenu til "
label_wiki_start: "Startside"
label_work: "Work"
label_work_package: "Arbejdspakke"
@@ -4215,7 +4207,7 @@ da:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projektet blev ikke slettet."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Forbindelse gennemført."
notice_successful_create: "Oprettelse gennemført."
notice_successful_delete: "Sletning gennemført."
+3 -11
View File
@@ -107,9 +107,8 @@ de:
trial: "Probezeitraum"
jemalloc_allocator: Jemalloc Speicher allocator
journal_aggregation:
explanation:
text: "Individuelle Aktionen eines Benutzers (z.B. ein Arbeitspaket zweimal aktualisieren) werden zu einer einzigen Aktion zusammengefasst, wenn ihr Altersunterschied kleiner ist als der angegebene Zeitraum. Sie werden als eine einzige Aktion innerhalb der Anwendung angezeigt. Dadurch werden Benachrichtigungen um die gleiche Zeit verzögert, wodurch die Anzahl der gesendeten E-Mails verringert wird. Dies wirkt sich auch auf die Verzögerung von %{webhook_link} aus."
link: "Webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3882,12 +3881,6 @@ de:
label_user_named: "Benutzer %{name}"
label_user_activity: "Aktivität von %{value}"
label_user_anonymous: "Anonym"
label_user_mail_option_all: "Für alle Ereignisse in all meinen Projekten"
label_user_mail_option_none: "Für keine Ereignisse"
label_user_mail_option_only_assigned: "Nur für Aufgaben, für die ich zuständig bin."
label_user_mail_option_only_my_events: "Nur für Aufgaben, die ich beobachte oder an welchen ich mitarbeite"
label_user_mail_option_only_owner: "Nur für Aufgaben, die ich angelegt habe"
label_user_mail_option_selected: "Für alle Ereignisse in den ausgewählten Projekten"
label_user_menu: "Benutzermenü"
label_user_new: "Neuer Benutzer"
label_user_plural: "Benutzer"
@@ -3927,7 +3920,6 @@ de:
label_wiki_show_index_page_link: "'Inhaltsverzeichnis' Link als Untermenüpunkt anzeigen"
label_wiki_show_menu_item: "als Menüpunkt in der Projektnavigation anzeigen"
label_wiki_show_new_page_link: "'Neue Unterseite anlegen' Link als Untermenüpunkt anzeigen"
label_wiki_show_submenu_item: "als Untermenüpunkt anzeigen von "
label_wiki_start: "Hauptseite"
label_work: "Aufwand"
label_work_package: "Arbeitspaket"
@@ -4209,7 +4201,7 @@ de:
notice_parent_item_not_found: "Übergeordnetes Element nicht gefunden."
notice_project_not_deleted: "Das Projekt wurde nicht gelöscht."
notice_project_not_found: "Projekt nicht gefunden."
notice_smtp_address_unsafe: "Die SMTP-Adresse %{address} ist nicht sicher. Bitte fügen Sie sie zu OPENPROJECT_SSRF_PROTECTION_ALLOWLIST hinzu."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Verbindung erfolgreich."
notice_successful_create: "Erfolgreich angelegt."
notice_successful_delete: "Erfolgreich gelöscht."
+3 -11
View File
@@ -107,9 +107,8 @@ el:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3886,12 +3885,6 @@ el:
label_user_named: "Χρήστης %{name}"
label_user_activity: "δραστηριότητα του %{value}"
label_user_anonymous: "Ανώνυμος"
label_user_mail_option_all: "Για όλα τα συμβάντα σε όλα τα έργα μου"
label_user_mail_option_none: "Κανένα συμβάν"
label_user_mail_option_only_assigned: "Μόνο για αντικείμενα που έχουν ανατεθεί σε μένα"
label_user_mail_option_only_my_events: "Μόνο για αντικείμενα που παρακολουθώ ή συμμετέχω"
label_user_mail_option_only_owner: "Μόνο για αντικείμενα που μου ανήκουν"
label_user_mail_option_selected: "Για όλες τις εξελίξεις μόνο στα επιλεγμένα έργα"
label_user_menu: "User menu"
label_user_new: "Νέος χρήστης"
label_user_plural: "Χρήστες"
@@ -3931,7 +3924,6 @@ el:
label_wiki_show_index_page_link: "Εμφάνιση του αντικειμένου υπομενού 'Πίνακας Περιεχομένων'"
label_wiki_show_menu_item: "Εμφάνιση ως αντικείμενο μενού στην πλοήγηση έργου"
label_wiki_show_new_page_link: "Εμφάνιση του αντικειμένου υπομενού 'Δημιουργία καινούργιας σελίδας παιδιού'"
label_wiki_show_submenu_item: "Εμφάνιση ως αντικείμενο υπομενού του "
label_wiki_start: "Σελίδα έναρξης"
label_work: "Work"
label_work_package: "Εργασία"
@@ -4212,7 +4204,7 @@ el:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Το έργο δεν διαγράφηκε."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Επιτυχής σύνδεση."
notice_successful_create: "Επιτυχής δημιουργία."
notice_successful_delete: "Επιτυχής διαγραφή."
+3 -11
View File
@@ -107,9 +107,8 @@ eo:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ eo:
label_user_named: "Uzanto %{name}"
label_user_activity: "Aktiveco de %{value}"
label_user_anonymous: "Aanonima"
label_user_mail_option_all: "Por ajna evento en ĉiuj miaj projektoj"
label_user_mail_option_none: "Ne estas eventoj"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "Nova uzanto"
label_user_plural: "Uzantoj"
@@ -3935,7 +3928,6 @@ eo:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Laborpakaĵo"
@@ -4217,7 +4209,7 @@ eo:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ es:
trial: "Prueba"
jemalloc_allocator: Asignador de memoria Jemalloc
journal_aggregation:
explanation:
text: "Las acciones individuales de un usuario (como actualizar dos veces un paquete de trabajo) se combinan en una sola acción si la diferencia de antigüedad es inferior al intervalo de tiempo especificado. Se mostrarán como una sola acción en la aplicación. También se retrasarán las notificaciones por la misma cantidad de tiempo, lo que reducirá el número de correos electrónicos enviados y causará también que se retrase el %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Importar"
jira:
@@ -3887,12 +3886,6 @@ es:
label_user_named: "Usuario %{name}"
label_user_activity: "Actividad de %{value} "
label_user_anonymous: "Anónimo"
label_user_mail_option_all: "Para cualquier evento en todos mis proyectos"
label_user_mail_option_none: "No hay eventos"
label_user_mail_option_only_assigned: "Sólo para cosas asignadas a mí"
label_user_mail_option_only_my_events: "Sólo para cosas que controlo o en las que participo"
label_user_mail_option_only_owner: "Sólo para cosas de las que soy el dueño"
label_user_mail_option_selected: "Únicamente para cualquier evento de los proyectos seleccionados"
label_user_menu: "Menú de usuario"
label_user_new: "Nuevo usuario"
label_user_plural: "Usuarios"
@@ -3932,7 +3925,6 @@ es:
label_wiki_show_index_page_link: "Mostrar el elemento de submenú 'Tabla de contenidos'"
label_wiki_show_menu_item: "Mostrar como elemento de menú de navegación de proyecto"
label_wiki_show_new_page_link: "Mostrar el elemento de submenú 'Crear nueva página hija'"
label_wiki_show_submenu_item: "Mostrar como elemento de submenú de "
label_wiki_start: "Página de inicio"
label_work: "Trabajo"
label_work_package: "Paquete de trabajo"
@@ -4214,7 +4206,7 @@ es:
notice_parent_item_not_found: "Elemento padre no encontrado."
notice_project_not_deleted: "El proyecto no fue eliminado."
notice_project_not_found: "Proyecto no encontrado."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Conexión exitosa."
notice_successful_create: "Creación exitosa."
notice_successful_delete: "Eliminado con éxito."
+3 -11
View File
@@ -107,9 +107,8 @@ et:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ et:
label_user_named: "User %{name}"
label_user_activity: "%{value}-s tegevus"
label_user_anonymous: "Anonüümne"
label_user_mail_option_all: "Kõigi sündmuste kohta minu projektides"
label_user_mail_option_none: "Sündmusi pole"
label_user_mail_option_only_assigned: "Ainult minule määratud tööde kohta"
label_user_mail_option_only_my_events: "Ainult tööde kohta, mida ma jälgin või millega olen seotud"
label_user_mail_option_only_owner: "Ainult minu omanduses olevate asjade kohta"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "Uus kasutaja"
label_user_plural: "Kasutajad"
@@ -3935,7 +3928,6 @@ et:
label_wiki_show_index_page_link: "Kuva alammenüü valik \"Sisukord\""
label_wiki_show_menu_item: "Näita lehe nime projektimenüüs"
label_wiki_show_new_page_link: "Näita alammenüüs valikut 'Loo uus alamleht'"
label_wiki_show_submenu_item: "Näita kui alammenüüd (<--) "
label_wiki_start: "Esileht"
label_work: "Töö"
label_work_package: "Teema"
@@ -4217,7 +4209,7 @@ et:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projekti ei ole kustutatud."
notice_project_not_found: "Projekti ei leitud."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Ühenduse loomine õnnestus."
notice_successful_create: "Loomine õnnestus."
notice_successful_delete: "Kustutamine õnnestus."
+3 -11
View File
@@ -107,9 +107,8 @@ eu:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ eu:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ eu:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ eu:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ fa:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ fa:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ fa:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "صفحه‌ی شروع"
label_work: "Work"
label_work_package: "کاربسته"
@@ -4217,7 +4209,7 @@ fa:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ fi:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ fi:
label_user_named: "Käyttäjä %{name}"
label_user_activity: "Käyttäjän %{value} historia"
label_user_anonymous: "Anonyymi"
label_user_mail_option_all: "Kaikista tapahtumista kaikissa projekteistani"
label_user_mail_option_none: "Ei tapahtumia"
label_user_mail_option_only_assigned: "Vain niistä joihin olen liittynyt"
label_user_mail_option_only_my_events: "Vain niistä, joita seuraan tai joissa olen mukana"
label_user_mail_option_only_owner: "Vain niistä, jotka omistan"
label_user_mail_option_selected: "Kaikista tapahtumista vain valitsemistani projekteista"
label_user_menu: "User menu"
label_user_new: "Uusi käyttäjä"
label_user_plural: "Käyttäjät"
@@ -3935,7 +3928,6 @@ fi:
label_wiki_show_index_page_link: "Näytä alivalikon vaihtoehto \"Sisällysluettelo\""
label_wiki_show_menu_item: "Näytä valikon kohta projekti navigaatio"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Aloitussivu"
label_work: "Work"
label_work_package: "Työpaketti"
@@ -4217,7 +4209,7 @@ fi:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Yhteyden muodostus onnistui."
notice_successful_create: "Luonti onnistui."
notice_successful_delete: "Poisto onnistui."
+3 -11
View File
@@ -107,9 +107,8 @@ fil:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ fil:
label_user_named: "User %{name}"
label_user_activity: "%{value} aktibidad"
label_user_anonymous: "Hindi kilala"
label_user_mail_option_all: "Sa kahit anong kaganapan sa lahat ng aking proyekto"
label_user_mail_option_none: "Walang mga kaganapan"
label_user_mail_option_only_assigned: "Sa mga bagay lamang ako nakatalaga sa"
label_user_mail_option_only_my_events: "Sa mga bagay ako tumingin o kasama ako sa"
label_user_mail_option_only_owner: "Sa mga bagay lamg ako na ako ang may-ari ng"
label_user_mail_option_selected: "Sa kahit anong kaganapan sa mga napiling proyekto lamang"
label_user_menu: "User menu"
label_user_new: "Bagong gumagamit"
label_user_plural: "Mga gumagamit"
@@ -3935,7 +3928,6 @@ fil:
label_wiki_show_index_page_link: "Ipakita ang aytem ng submenu 'Talaan ng Nilalaman'"
label_wiki_show_menu_item: "Ipakita bilanh aytem na pagpipilian sa proyektong nabigasyon"
label_wiki_show_new_page_link: "Ipakita ang submenu aytem 'Lumikha ng bagong bata na pahina'"
label_wiki_show_submenu_item: "Ipakita bilang submenu. aytem ng "
label_wiki_start: "Simulan ang pahina"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ fil:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Ang proyekto ay hindi nabura."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Matagumpay na ikonekta."
notice_successful_create: "Matagumpay pagkalikha."
notice_successful_delete: "Matagumpay ang pagtanggal."
+1 -1
View File
@@ -154,7 +154,7 @@ fr:
5. *Activez d'autres modules* : &rightarrow; Accédez à [Paramètres du projet &rightarrow; Modules]({{opSetting:base_url}}/projects/demo-project/settings/modules).
6. *Complétez vos tâches dans le projet* : &rightarrow; Accédez à [Lots de travaux &rightarrow; Tâches]({{opSetting:base_url}}/projects/demo-project/work_packages/details/##wp.id:set_date_and_location_of_conference/overview?query_id=##query.id:demo_project__query__tasks).
Vous trouverez ici nos [Guides de l'utilisateur] (https://www.openproject.org/docs/user-guide/).
Vous trouverez ici nos [Guides de l'utilisateur](https://www.openproject.org/docs/user-guide/).
Si vous avez des questions ou si avez besoin d'aide, n'hésitez pas à nous contacter : [support[at]openproject.com](mailto:support@openproject.com).
item_5:
options:
+51 -55
View File
@@ -20,7 +20,7 @@
#See COPYRIGHT and LICENSE files for more details.
#++
fr:
no_results_title_text: Il n'y a présentement rien à afficher.
no_results_title_text: Il n'y a actuellement rien à afficher.
activities:
index:
no_results_title_text: Il ny a pas eu d'activité pour le projet pendant cette période.
@@ -107,9 +107,8 @@ fr:
trial: "Essai"
jemalloc_allocator: Allocateur de mémoire Jemalloc
journal_aggregation:
explanation:
text: "Les actions individuelles d'un utilisateur (par ex. mis à jour un lot de travaux deux fois) sont agrégés en une seule action si leur différence d'âge est inférieure à la période spécifiée. Elles seront affichées en une seule action dans l'application. Cela retardera également les notifications du même temps réduisant donc le nombre d'e-mails envoyés et affectera également le délai %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Importation"
jira:
@@ -185,8 +184,8 @@ fr:
imported: "Mode révision"
reverting: "Rétablissement en cours"
revert_error: "Erreur lors de la restauration"
revert_cancelling: "Cancelling revert"
revert_cancelled: "Revert cancelled"
revert_cancelling: "Annulation de la réversion"
revert_cancelled: "Annulation de l'annulation"
reverted: "Restauré"
finalizing: "Finalisation"
finalizing_error: "Erreur lors de la finalisation"
@@ -446,7 +445,7 @@ fr:
Si vous cochez cette case, OpenProject créera automatiquement de nouveaux utilisateurs à partir de leurs entrées LDAP
lorsqu'ils s'authentifieront pour la première fois avec OpenProject.
Laissez ceci non coché pour permettre uniquement aux comptes existants dans OpenProject de s'authentifier via LDAP!
connection_encryption: "Cryptage de la connexion"
connection_encryption: "Chiffrement de la connexion"
encryption_details: "Options LDAPS / STARTTLS"
system_account: "Compte système"
system_account_legend: |
@@ -615,11 +614,13 @@ fr:
op_dry_validation:
or: "ou"
errors:
unexpected_key: "n'est pas autorisé."
array?: "doit être un tableau."
decimal?: "doit être une décimale."
defined: "ne doit pas être défini."
eql?: "doit être égal à %{left}."
filled?: "doit être rempli."
format?: "est dans un format non valide."
greater_or_equal_zero: "doit être supérieur ou égal à 0."
gteq?: "doit être supérieur ou égal à %{num}."
hash?: "doit être un hachage."
@@ -646,7 +647,9 @@ fr:
parent:
not_descendant: "doit être un descendant de la racine de la hiérarchie."
str?: "doit être une chaîne de caractères."
time?: "doit être un moment."
type?: "doit être de type : %{type}."
uri?: "nest pas une URL valide."
rules:
copy_workflow_from: "Type de copie du flux de travail"
enabled: "Activé"
@@ -1031,7 +1034,7 @@ fr:
no_results_user: "Aucun utilisateur n'a été trouvé"
invite_user: "Invité :"
no_results_placeholder: "Aucun utilisateur fictif n'a été trouvé"
create_new_placeholder: "Créer un nouveau utilisateur fictif :"
create_new_placeholder: "Créer un nouvel utilisateur fictif :"
no_results_group: "Aucun groupe n'a été trouvé"
invite_to_project: "Inviter à rejoindre %{project_name}"
required:
@@ -1051,7 +1054,7 @@ fr:
next_button: "Envoyer une invitation"
success_message:
user: "L'utilisateur peut maintenant se connecter pour accéder à %{project}. En attendant, vous pouvez déjà compter sur cet utilisateur et l'assigner à des lots de travaux, par exemple."
placeholder_user: "L'utilisateur fictif peut maintenant être utilisé dans %{project}. En attendant, vous pouvez déjà planifier des taches avec cet utilisateur et l'assigner à des lots de travaux, par exemple."
placeholder_user: "L'utilisateur fictif peut maintenant être utilisé dans %{project}. En attendant, vous pouvez déjà planifier des tâches avec cet utilisateur et l'assigner à des lots de travaux, par exemple."
group: "Le groupe fait maintenant partie du projet %{project}. En attendant, vous pouvez déjà compter sur ce groupe et l'assigner à des lots de travaux, par exemple."
page:
text: "Texte"
@@ -1178,7 +1181,7 @@ fr:
matrix_check_uncheck_all_in_col_label_html: "Activer/désactiver les transitions de tous les anciens statuts vers <em>%{new_status}</em>"
work_flows:
index:
no_results_title_text: Il n'y a actuellement aucun flux de travaux.
no_results_title_text: Il n'y a actuellement aucun flux de travail.
work_packages:
datepicker_modal:
banner:
@@ -1871,7 +1874,7 @@ fr:
reason:
no_notification_reason: "ne peut pas être vide car IAN est choisi comme canal."
reason_mail_digest:
no_notification_reason: "ne peut pas être vide car le digest d'email est est choisi comme un canal."
no_notification_reason: "ne peut pas être vide car le digest d'email est choisi comme un canal."
non_working_day:
attributes:
date:
@@ -2207,9 +2210,9 @@ fr:
created_on: "créé le %{datetime}"
created_on_time_entry: "temps enregistré le %{datetime}"
updated_by_on: "mis à jour par %{user} le %{datetime}"
updated_by_on_time_entry: "temps enregistré mis à jour par %{user} le %{datetime}"
updated_by_on_time_entry: "temps consigné mis à jour par %{user} le %{datetime}"
updated_on: "mis à jour le %{datetime}"
updated_on_time_entry: "temps enregistré mis à jour le %{datetime}"
updated_on_time_entry: "temps consigné mis à jour le %{datetime}"
deleted_on: "supprimé le %{datetime}"
deleted_by_on: "supprimé par %{user} le %{datetime}"
added_on: "ajouté le %{datetime}"
@@ -2633,7 +2636,7 @@ fr:
other: "%{count} ans"
x_seconds:
one: "une seconde"
other: "%{count} seconde"
other: "%{count} secondes"
x_seconds_abbreviated:
one: "1 s"
other: "%{count} s"
@@ -2650,7 +2653,7 @@ fr:
description_active: "Actif ?"
description_attachment_toggle: "Afficher/Masquer les pièces jointes"
description_autocomplete: >
Ce champ utilise la saisie semi-automatique. Lorsque vous tapez le titre d'un lot de travaux, vous recevrez une liste de choix possibles. Choisissez-en un en utilisant les flèches haut et bas et selectionnez-le avec Tab ou Entrée. Sinon, vous pouvez entrer le numéro de lot de travaux directement.
Ce champ utilise la saisie semi-automatique. Lorsque vous tapez le titre d'un lot de travaux, vous recevrez une liste de choix possibles. Choisissez-en un en utilisant les flèches haut et bas et sélectionnez-le avec Tab ou Entrée. Sinon, vous pouvez entrer le numéro de lot de travaux directement.
description_available_columns: "Colonnes disponibles"
description_choose_project: "Projets"
description_compare_from: "Comparer avec"
@@ -2890,8 +2893,8 @@ fr:
error_unable_to_connect: "Impossible de se connecter (%{value})"
error_unable_delete_wiki: "Impossible de supprimer la page wiki."
error_unable_update_wiki: "Impossible de mettre la page wiki à jour."
error_workflow_copy_source: "Veuillez sélectioner un type de source ou rôle"
error_workflow_copy_target: "Veuillez sélectioner une cible type(s) et rôle(s)"
error_workflow_copy_source: "Veuillez sélectionner un type de source ou rôle"
error_workflow_copy_target: "Veuillez sélectionner une cible type(s) et rôle(s)"
error_menu_item_not_created: L'élément de menu n'a pas pu être ajouté
error_menu_item_not_saved: L'élément de menu n'a pas pu être sauvegardé
error_wiki_root_menu_item_conflict: >
@@ -3057,7 +3060,7 @@ fr:
no_results_text: "Aucun résultat"
toggle_switch:
label_on: "Activé"
label_off: "Désactiver"
label_off: "Désactivé"
general_csv_decimal_separator: ","
general_csv_encoding: "UTF-8"
general_csv_separator: "."
@@ -3140,7 +3143,7 @@ fr:
work_package_related_changed_times: par changement vers %{link} connexe
work_package_duplicate_closed: Le statut a été mis à jour automatiquement par le doublon de lot de travaux %{link}
unaccessable_work_package_changed: par changement vers un lot de travaux connexe
budget_deleted: La budget a été supprimé
budget_deleted: Le budget a été supprimé
working_days_changed:
changed: "par changement vers des jours ouvrables (%{changes})"
days:
@@ -3305,11 +3308,11 @@ fr:
label_all_words: "Tous les mots"
label_all_open_wps: "Tous les ouverts"
label_always_visible: "Toujours affiché"
label_announcement: "Annonce ou avis. "
label_announcement: "Annonce"
label_angular: "AngularJS"
label_app_modules: "Modules %{app_title}"
label_api_access_key: "Clé d'accès API"
label_api_access_key_created_on: "Clé d'accès API créé il y a %{value}"
label_api_access_key_created_on: "Clé d'accès API créée il y a %{value}"
label_api_access_key_type: "API"
label_auto_option: "(auto)"
label_ical_access_key_type: "iCalendar"
@@ -3358,7 +3361,7 @@ fr:
label_branch: "Branche"
label_browse: "Parcourir"
label_builtin: "Intégré"
label_bulk_edit_selected_work_packages: "Edition en masse des Lots de Travaux selectionnés"
label_bulk_edit_selected_work_packages: "Édition en masse des lots de travaux sélectionnés"
label_bundled: "(Inclus)"
label_calendar: "Calendrier"
label_calendars_and_dates: "Calendriers et dates"
@@ -3406,7 +3409,7 @@ fr:
label_copy_source: "Source"
label_copy_target: "Cible"
label_copy_workflow_from: "Copier flux de travail à partir de"
label_copy_project: "Copier projet"
label_copy_project: "Copie du projet"
label_core_version: "Version du cœur"
label_core_build: "Construction de base"
label_created_by: "Créé par %{user}"
@@ -3492,7 +3495,7 @@ fr:
label_f_hour: "%{value} heure"
label_f_hour_plural: "%{value} heures"
label_favorite: "Favori"
label_feed_plural: "Fluxs"
label_feed_plural: "Flux"
label_feeds_access_key: "Clé d'accès RSS"
label_feeds_access_key_created_on: "Clé d'accès RSS créé il y a %{value}"
label_feeds_access_key_type: "RSS"
@@ -3675,7 +3678,7 @@ fr:
label_not_configured: "Non configuré"
label_not_found: "non trouvé"
label_none: "aucune"
label_none_parentheses: "(none)"
label_none_parentheses: "(aucun)"
label_not_contains: "ne contient pas"
label_not_equals: "n'est pas"
label_life_cycle_step_plural: "Cycle de vie du projet"
@@ -3884,16 +3887,10 @@ fr:
label_user_named: "Utilisateur %{name}"
label_user_activity: "Activité de %{value}"
label_user_anonymous: "Anonyme"
label_user_mail_option_all: "Tout évènement dans tous mes projets"
label_user_mail_option_none: "Aucun évènement"
label_user_mail_option_only_assigned: "Les éléments qui me sont assignés"
label_user_mail_option_only_my_events: "Uniquement pour les éléments que je suis ou auxquels je participe"
label_user_mail_option_only_owner: "Les éléments dont je suis le propriétaire"
label_user_mail_option_selected: "Pour chaque événement sur le projet selectionné seulement"
label_user_menu: "Menu utilisateur"
label_user_new: "Nouvel utilisateur"
label_user_plural: "Utilisateurs"
label_user_search: "Recherche d'Utilisateurs"
label_user_search: "Recherche d'utilisateurs"
label_user_settings: "Paramètres de l'utilisateur"
label_users_settings: "Paramètres des utilisateurs"
label_value_x: "Valeur : %{x}"
@@ -3929,7 +3926,6 @@ fr:
label_wiki_show_index_page_link: "Montrer l'entrée de sous-menu 'Table des Matières'"
label_wiki_show_menu_item: "Afficher en tant qu'élément dans le menu de navigation du projet"
label_wiki_show_new_page_link: "Montrer le sous-menu 'Créer une nouvelle page enfant'"
label_wiki_show_submenu_item: "Montrer comme sous-menu de "
label_wiki_start: "Page d'accueil"
label_work: "Travail"
label_work_package: "Lot de travaux"
@@ -3948,7 +3944,7 @@ fr:
label_work_package_tracking: "Suivi des lots de travaux"
label_work_package_view_all: "Afficher tous les lots de travaux"
label_workflow: "Flux de travail"
label_workflow_copy: "Copier le processus d'entreprise"
label_workflow_copy: "Copier le flux de travail"
label_workflow_plural: "Flux de travail"
label_workflow_summary: "Résumé"
label_working_days_and_hours: "Jours et heures travaillés"
@@ -4211,8 +4207,8 @@ fr:
notice_parent_item_not_found: "L'élément parent est introuvable."
notice_project_not_deleted: "Le projet n'a pas été supprimé."
notice_project_not_found: "Projet introuvable."
notice_smtp_address_unsafe: "L'adresse SMTP %{address} n'est pas sûre. Veuillez l'ajouter à OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_successful_connection: "Connection réussie."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Connexion réussie."
notice_successful_create: "Création réussie."
notice_successful_delete: "Suppression réussie."
notice_successful_cancel: "Annulation réussie."
@@ -4234,7 +4230,7 @@ fr:
notice_wont_delete_auth_source: La connexion LDAP ne peut pas être supprimée tant que des utilisateurs l'utilisent.
notice_project_cannot_update_custom_fields: "Vous ne pouvez pas mettre à jour les champs personnalisés disponibles du projet. Le projet nest pas valide : %{errors}"
notice_attachment_migration_wiki_page: >
Cette page a été générée automatiquement durant la mise à jour de OpenProject. Il contient toutes les pièces jointes précédemment associées à la %{container_type} « %{container_name} ».
Cette page a été générée automatiquement durant la mise à jour de OpenProject. Elle contient toutes les pièces jointes précédemment associées à la %{container_type} « %{container_name} ».
#Default format for numbers
number:
format:
@@ -4630,9 +4626,9 @@ fr:
setting_use_wysiwyg_description: "Sélectionnez cette option pour activer l’éditeur CKEditor5 WYSIWYG pour tous les utilisateurs par défaut. CKEditor a des fonctionnalités limitées pour GFM Markdown."
setting_column_options: "Colonnes de listes du lot de travaux par défaut"
setting_commit_fix_keywords: "Réparer les mots clés"
setting_commit_logs_encoding: "Encoding of the Commit messages"
setting_commit_logtime_activity_id: "Activité pour les « Logged Time »"
setting_commit_logtime_enabled: "Activer « time logging »"
setting_commit_logs_encoding: "Encodage des messages de commit"
setting_commit_logtime_activity_id: "Activité pour le temps consignés"
setting_commit_logtime_enabled: "Activer la consignation de temps"
setting_commit_ref_keywords: "Referencement des mots clés"
setting_consent_time: "Moment de l'accord"
setting_consent_info: "Texte d'information sur l'accord"
@@ -4682,7 +4678,7 @@ fr:
setting_work_package_startdate_is_adddate: "Utiliser la date actuelle comme date de début des nouveaux lots de travaux"
setting_work_packages_projects_export_limit: "Limite d'exportation des lots de travaux/projets"
setting_journal_aggregation_time_minutes: "Actions utilisateur agrégées dans"
setting_log_requesting_user: "Enregister le login utilisateur, nom et adresse e-mail pour toutes les requêtes"
setting_log_requesting_user: "Enregistrer le login utilisateur, nom et adresse e-mail pour toutes les requêtes"
setting_login_required: "Authentification requise"
setting_login_required_caption: "Lorsque cette case est cochée, toutes les requêtes envoyées à l'application doivent être authentifiées."
setting_lost_password: "Activer la réinitialisation du mot de passe"
@@ -4695,11 +4691,11 @@ fr:
setting_new_project_user_role_id: "Rôle donné à un utilisateur non administrateur qui crée un projet"
setting_new_project_send_confirmation_email: "Envoyer une notification à l'auteur lors de la création d'un nouveau projet"
setting_new_project_notification_text: "Texte de la notification"
setting_password_active_rules: "Les classes de caractère activées"
setting_password_count_former_banned: "Nombre des plus récent mots des passe utilisé qui sont interdit de réutilisation."
setting_password_active_rules: "Classes de caractères actives"
setting_password_count_former_banned: "Nombre de mots de passe récents interdits de réutilisation"
setting_password_days_valid: "Nombre de jours après lequel le changement de mot de passe est obligatoire"
setting_password_min_length: "Longueur minimale"
setting_password_min_adhered_rules: "Nombre minimale des classe de caractère requise"
setting_password_min_adhered_rules: "Nombre minimal de classes de caractères requises"
setting_per_page_options: "Options des objets par page"
setting_percent_complete_on_status_closed: "% d'achèvement lorsque le statut est fermé"
setting_percent_complete_on_status_closed_no_change: "Aucun changement"
@@ -4722,7 +4718,7 @@ fr:
setting_repository_checkout_base_url: "URL de base de « checkout »"
setting_repository_checkout_text: "Texte d'instruction de « checkout »"
setting_repository_log_display_limit: "Nombre maximal des révisions affichées sur « file log »"
setting_repository_truncate_at: "Le nombre maiximum de fichiers exposes au navigateur"
setting_repository_truncate_at: "Le nombre maximum de fichiers affichés dans le navigateur de dépôt"
setting_self_registration: "Auto-enregistrement"
setting_self_registration_caption: >
Choisissez le mécanisme d'auto-inscription pour les utilisateurs. Faites attention au paramètre que vous choisissez, car certaines options permettent aux utilisateurs d'activer leurs propres comptes pour cette instance.
@@ -4882,7 +4878,7 @@ fr:
project_mandate: "Mandat du projet"
submission:
description_template: >
**Ce dossier de travail a été créé automatiquement à l'issue du flux de travail %{wizard_name} .** Un artefact PDF contenant toutes les informations soumises a été généré et joint à ce dossier de travail à des fins de référence et d'audit. Si vous avez besoin de mettre à jour ou de réexécuter les étapes d'initiation, vous pouvez rouvrir l'assistant à tout moment en utilisant le lien ci-dessous :
**Ce dossier de travail a été créé automatiquement à l'issue du flux de travail %{wizard_name}.** Un artefact PDF contenant toutes les informations soumises a été généré et joint à ce dossier de travail à des fins de référence et d'audit. Si vous avez besoin de mettre à jour ou de réexécuter les étapes d'initiation, vous pouvez rouvrir l'assistant à tout moment en utilisant le lien ci-dessous :
description: "Lorsqu'un utilisateur envoie une demande de lancement de projet, un nouveau lot de travail est créé avec l'artefact de la demande en pièce jointe au format PDF. Les paramètres ci-dessous définissent le type, le statut et le destinataire de ce nouveau lot de travaux."
work_package_type: "Type de lot de travaux"
work_package_type_caption: "Le type de lot de travaux qui doit être utilisé pour stocker l'artefact terminé."
@@ -5001,7 +4997,7 @@ fr:
text_default_administrator_account_changed: "Le compte administrateur par défaut a été changé"
text_default_encoding: "Défaut: UTF-8"
text_destroy: "Supprimer"
text_destroy_with_associated: "There are additional objects associated with the work package(s) that are to be deleted. Those objects are of the following types:"
text_destroy_with_associated: "Il y a des objets supplémentaires associés à ce(s) lot(s) de travaux qui doivent être supprimés. Ces objets sont des types suivants :"
text_destroy_what_to_do: "Que voulez-vous faire?"
text_diff_truncated: "... Cette « diff » a été tronquée car elle dépasse la taille maximale d'affichage."
text_email_delivery_not_configured: "L'envoi d'e-mails n'est pas configuré et les notifications sont désactivées.\nConfigurer votre serveur SMTP pour les activer."
@@ -5042,12 +5038,12 @@ fr:
text_load_default_configuration: "Charger la configuration par défaut"
text_no_roles_defined: Il n'y a pas de rôles définis.
text_no_access_tokens_configurable: "Il n'y a aucun jeton d'accès qui puisse être configuré."
text_no_configuration_data: "Les rôles, les types, l'état des lots de travaux et les flux de travaux n'ont pas encore été configurés.\nIl est fortement recommandé de charger la configuration par défaut. Vous serez capable de la modifier une fois chargée."
text_no_configuration_data: "Les rôles, les types, l'état des lots de travaux et les flux de travail n'ont pas encore été configurés.\nIl est fortement recommandé de charger la configuration par défaut. Vous serez capable de la modifier une fois chargée."
text_no_notes: "Il n'existe aucun commentaire pour ce lot de travaux."
text_notice_too_many_values_are_inperformant: "Remarque : L'affichage de plus de 100 articles par page peut augmenter le temps de chargement de la page."
text_notice_security_badge_displayed_html: >
Remarque : si cette option est activée, un badge indiquant l'état de votre installation s'affichera dans le panneau <a href="%{information_panel_path}">%{information_panel_label}</a> administration et sur la page d'accueil. Il n'est affiché que pour les administrateurs. <br/>Le badge vérifiera votre version actuelle d'OpenProject par rapport à la base de données officielle d'OpenProject pour vous avertir de toute mise à jour ou vulnérabilité connue. Pour plus d'informations sur ce que la vérification fournit, quelles données sont nécessaires pour fournir les mises à jour disponibles, et comment désactiver cette vérification, veuillez visiter <a href="%{more_info_url}">la documentation de configuration</a>.
text_own_membership_delete_confirmation: "Vous êtes sur le point de retirer tout ou partie de vos permissions et ne pourrez peut-être plus modifier le projet par la suite.\nÊtes vous sûr de vouloir continuer?"
text_own_membership_delete_confirmation: "Vous êtes sur le point de retirer tout ou partie de vos permissions et ne pourrez peut-être plus modifier le projet par la suite.\nVoulez-vous vraiment continuer?"
text_permanent_delete_confirmation_checkbox_label: "Je comprends que cette suppression ne peut pas être annulée"
text_permanent_remove_confirmation_checkbox_label: "Je comprends que cette suppression ne peut pas être annulée"
text_plugin_assets_writable: "Répertoire des « plugin assets » est accessible en écriture"
@@ -5069,7 +5065,7 @@ fr:
text_wrote: "a écrit"
text_warn_on_leaving_unsaved: "Le lot de travaux contient du texte non sauvegardé qui sera perdu si vous quittez cette page."
text_what_did_you_change_click_to_add_comment: "Quavez-vous changé ? Cliquez ici pour ajouter un commentaire"
text_wiki_destroy_confirmation: "Êtes vous sur de vouloir supprimer ce wiki et tout son contenu?"
text_wiki_destroy_confirmation: "Voulez-vous vraiment supprimer ce wiki et tout son contenu?"
text_wiki_page_destroy_children: "Supprimer les pages enfants et toute leur descendance"
text_wiki_page_destroy_question: "Cette page possède %{descendants} page(s) enfant et descendant(s). Que voulez vous faire?"
text_wiki_page_nullify_children: "Garder les pages enfants en tant que pages d'origine"
@@ -5126,7 +5122,7 @@ fr:
all: "tous"
active: "actif"
activate: "Activer"
activate_and_reset_failed_logins: "Activer et réinitialiser les connexions echouées"
activate_and_reset_failed_logins: "Activer et réinitialiser les connexions échouées"
authentication_provider: "Fournisseur d'authentification"
identity_url_text: "L'identifiant unique interne fourni par le fournisseur d'authentification."
authentication_settings_disabled_due_to_external_authentication: >
@@ -5149,7 +5145,7 @@ fr:
no_login: "Cet utilisateur s'authentifie avec un mot de passe. Tant que cela est désactivé, il ne peut s'authentifier."
password_change_unsupported: Le changement de mot de passe n'est pas supporté.
registered: "enregistré"
reset_failed_logins: "Réinitialiser les connexions echouées"
reset_failed_logins: "Réinitialiser les connexions échouées"
status_user_and_brute_force: "%{user} et %{brute_force}"
status_change: "Changement de statut"
text_change_disabled_for_provider_login: "Le nom et l'adresse électronique sont définis par votre fournisseur d'accès et ne peuvent donc pas être modifiés."
@@ -5471,7 +5467,7 @@ fr:
none_given: "Aucune application OAuth n'a été autorisée à accéder à votre compte utilisateur."
x_active_tokens:
one: "un jeton actif"
other: "un jeton actif %{count}"
other: "%{count} jetons actifs"
flows:
authorization_code: "Flux de code d'autorisation"
client_credentials: "Flux des informations d'identification client"
@@ -5527,8 +5523,8 @@ fr:
invalid_scope: "Vous n'êtes pas autorisé à accéder à la ressource demandée (invalid_scope)."
http:
request:
failed_authorization: "La requête côté serveur a échoué en s'autorisant elle-même."
missing_authorization: "La requête latérale du serveur a échoué en raison de l'absence d'informations d'autorisation."
failed_authorization: "La requête côté serveur a échoué lors de l'authentification."
missing_authorization: "La requête côté serveur a échoué en raison de l'absence d'informations d'autorisation."
response:
unexpected: "Réponse inattendue reçue."
you: vous
+3 -11
View File
@@ -107,9 +107,8 @@ he:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -4002,12 +4001,6 @@ he:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "אנונימי"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "משתמש חדש"
label_user_plural: "משתמשים"
@@ -4047,7 +4040,6 @@ he:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "דף פתיחה"
label_work: "Work"
label_work_package: "חבילת עבודה"
@@ -4331,7 +4323,7 @@ he:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ hi:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3888,12 +3887,6 @@ hi:
label_user_named: "उपयोगकर्ता %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "अज्ञात"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3933,7 +3926,6 @@ hi:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "प्रारंभ पृष्ठ"
label_work: "Work"
label_work_package: "कार्य पैकेज"
@@ -4215,7 +4207,7 @@ hi:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ hr:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3946,12 +3945,6 @@ hr:
label_user_named: "User %{name}"
label_user_activity: "%{value}-a aktivnost"
label_user_anonymous: "Anonimno"
label_user_mail_option_all: "Za bilo koji događaj na svim mojim projektima"
label_user_mail_option_none: "Nema novih događanja"
label_user_mail_option_only_assigned: "Samo stvari koje su mi dodijeljene"
label_user_mail_option_only_my_events: "Samo stvari koje nadgledam ili u koje sam uključen"
label_user_mail_option_only_owner: "Samo za stvari kojih sam vlasnik"
label_user_mail_option_selected: "Za bilo koji događaj na samo odabranim projektima"
label_user_menu: "User menu"
label_user_new: "Novi korisnik"
label_user_plural: "Korisnici"
@@ -3991,7 +3984,6 @@ hr:
label_wiki_show_index_page_link: "Prikaži stavku podizbornika 'Kazalo sadržaja'"
label_wiki_show_menu_item: "Prikaži kao stavku izbornika u izborniku projekta"
label_wiki_show_new_page_link: "Prikaži stavku podizbornika 'Kreiraj novu podređenu stranicu'"
label_wiki_show_submenu_item: "Prikaži kao stavku podizbornika iz "
label_wiki_start: "Početna stranica"
label_work: "Work"
label_work_package: "Radni paket"
@@ -4274,7 +4266,7 @@ hr:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projekt nije izbrisan."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Uspješna spojen."
notice_successful_create: "Uspješno kreirano."
notice_successful_delete: "Brisanje uspješno."
+3 -11
View File
@@ -107,9 +107,8 @@ hu:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "A felhasználó egyes műveletei (pl. egy munkacsomag kétszeri frissítése) egyetlen műveletté egyesülnek, ha korkülönbségük kisebb, mint a megadott időtartam. Ezek egyetlen műveletként jelennek meg az alkalmazásban. Ez ugyanannyi idővel késlelteti az értesítéseket, csökkenti az elküldött emailek számát, valamint befolyásolja a %{webhook_link} késleltetését is.\n"
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3889,12 +3888,6 @@ hu:
label_user_named: "Felhasználó: %{name}"
label_user_activity: "%{value} tevékenység"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "Minden saját projektet érintő esetben"
label_user_mail_option_none: "Nem kérek értesítéseket"
label_user_mail_option_only_assigned: "Csak a hozzám rendelt feladatokról"
label_user_mail_option_only_my_events: "Csak a megfigyelt feladatok vagy amelyben részt veszek"
label_user_mail_option_only_owner: "Csak azok a feladatok, amelyeknek én vagyok a tulajdonosa"
label_user_mail_option_selected: "Minden eseményről a kiválasztott projektekben"
label_user_menu: "User menu"
label_user_new: "Új felhasználó"
label_user_plural: "Felhasználók"
@@ -3934,7 +3927,6 @@ hu:
label_wiki_show_index_page_link: "Megjeleníti az almenüpont feladatainak \"Tartalomjegyzékét\""
label_wiki_show_menu_item: "Megjeleníti mint menüpont a projekt navigációban"
label_wiki_show_new_page_link: "Almenüpont megjelenítése \" új gyermekoldal létrehozása\""
label_wiki_show_submenu_item: "Megjelenítés mint: almenüpont "
label_wiki_start: "Kezdő oldal"
label_work: "Munka"
label_work_package: "Feladatcsoport"
@@ -4215,7 +4207,7 @@ hu:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "A projekt nem lett törölve."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Sikeresen létrejött a kapcsolat."
notice_successful_create: "Sikeres létrehozás."
notice_successful_delete: "Sikeres törlés."
+3 -11
View File
@@ -107,9 +107,8 @@ id:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Setiap tindakan pengguna (mis. memperbarui paket kerja dua kali) digabungkan menjadi satu tindakan jika perbedaan usianya kurang dari rentang waktu yang ditentukan. Mereka akan ditampilkan sebagai tindakan tunggal dalam aplikasi. Ini juga akan menunda pemberitahuan dengan jumlah waktu yang sama sehingga mengurangi jumlah email yang dikirim dan juga akan memengaruhi penundaan %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3830,12 +3829,6 @@ id:
label_user_named: "User %{name}"
label_user_activity: "%{value} aktivitas"
label_user_anonymous: "Anonimus"
label_user_mail_option_all: "Untuk semua Event pada semua proyek saya"
label_user_mail_option_none: "Tidak ada event"
label_user_mail_option_only_assigned: "Hanya untuk hal-hal yang saya ditugaskan untuk"
label_user_mail_option_only_my_events: "Hanya untuk hal-hal yang saya pantau atau saya terlibat didalamnya"
label_user_mail_option_only_owner: "Hanya untuk hal-hal yang saya sebagai Ownernya"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "User baru"
label_user_plural: "User"
@@ -3875,7 +3868,6 @@ id:
label_wiki_show_index_page_link: "Tampilkan item submenu 'Daftar isi'"
label_wiki_show_menu_item: "Tampilkan sebagai item menu navigasi Project"
label_wiki_show_new_page_link: "Tampilkan submenu item 'Buat sub-halaman baru'"
label_wiki_show_submenu_item: "Tampilkan sebagai submenu item "
label_wiki_start: "Homepage"
label_work: "Work"
label_work_package: "Paket-Penugasan"
@@ -4156,7 +4148,7 @@ id:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Project tidak dihapus."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Sambungan berhasil."
notice_successful_create: "Berhasil dibuat."
notice_successful_delete: "Berhasil dihapus."
+3 -11
View File
@@ -107,9 +107,8 @@ it:
trial: "Prova"
jemalloc_allocator: Allocatore di memoria Jemalloc
journal_aggregation:
explanation:
text: "Le singole azioni di un utente (es. l'aggiornamento di una macro-attività due volte) vengono aggregate in un'unica azione se il tempo intercorso tra esse è inferiore al periodo minimo di tempo impostato. Verranno visualizzate quindi come un'unica azione all'interno dell'applicazione. Questo ritarderà anche le notifiche della stessa quantità di tempo, riducendo così il numero di email inviate, e influirà anche sul ritardo di %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Importa"
jira:
@@ -3887,12 +3886,6 @@ it:
label_user_named: "Utente %{name}"
label_user_activity: "attività di %{value}"
label_user_anonymous: "Anonimo"
label_user_mail_option_all: "Per qualsiasi evento su tutti i miei progetti"
label_user_mail_option_none: "Per nessun evento"
label_user_mail_option_only_assigned: "Solo per cose alle quali sono stato assegnato"
label_user_mail_option_only_my_events: "Solo per le cose che osservo o nelle quali sono coinvolto"
label_user_mail_option_only_owner: "Solo per le cose di cui sono proprietario"
label_user_mail_option_selected: "Per qualsiasi evento solo nei progetti selezionati"
label_user_menu: "Menu utente"
label_user_new: "Nuovo utente"
label_user_plural: "Utenti"
@@ -3932,7 +3925,6 @@ it:
label_wiki_show_index_page_link: "Mostra voce del sotto-menù 'Sommario'"
label_wiki_show_menu_item: "Mostra come voce del menù nella navigazione del progetto"
label_wiki_show_new_page_link: "Mostra voce del sotto-menù 'Crea nuova pagina figlio'"
label_wiki_show_submenu_item: "Mostra come voce di sottomenù di "
label_wiki_start: "Pagina iniziale"
label_work: "Lavoro"
label_work_package: "Macro-attività"
@@ -4214,7 +4206,7 @@ it:
notice_parent_item_not_found: "L'elemento genitore non è stato trovato."
notice_project_not_deleted: "Il progetto non è stato eliminato."
notice_project_not_found: "Progetto non trovato."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Connesso con successo."
notice_successful_create: "Creato con successo."
notice_successful_delete: "Cancellato con successo."
+3 -11
View File
@@ -107,9 +107,8 @@ ja:
trial: "試用版"
jemalloc_allocator: Jemalloc メモリアロケータ
journal_aggregation:
explanation:
text: "ユーザーの個々のアクション (例:ワークパッケージを2回更新する)は、指定された時間範囲よりも時間差が小さい場合、単一のアクションに集約されます。 これらはアプリケーション内で単一のアクションとして表示されます。 これにより、送信されるメールの数が減少し、 %{webhook_link} の遅延にも影響します。"
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3833,12 +3832,6 @@ ja:
label_user_named: "ユーザー名 %{name}"
label_user_activity: "%{value}の活動"
label_user_anonymous: "匿名ユーザ"
label_user_mail_option_all: "参加しているプロジェクトの全イベント"
label_user_mail_option_none: "通知しない"
label_user_mail_option_only_assigned: "自分が担当している事柄のみ"
label_user_mail_option_only_my_events: "ウォッチまたは関係している事柄のみ"
label_user_mail_option_only_owner: "自分が作成した事柄のみ"
label_user_mail_option_selected: "選択したプロジェクトのみのイベントに対して"
label_user_menu: "ユーザーメニュー"
label_user_new: "新規ユーザ"
label_user_plural: "ユーザ"
@@ -3878,7 +3871,6 @@ ja:
label_wiki_show_index_page_link: "下位のメニューで「目次」を表示"
label_wiki_show_menu_item: "プロジェクトのメニューで項目として表示"
label_wiki_show_new_page_link: "下位のメニューで「子ページを新規作成」の項目を表示"
label_wiki_show_submenu_item: "上位のメニュー項目"
label_wiki_start: "開始ページ"
label_work: "予定時間"
label_work_package: "ワーク パッケージ"
@@ -4159,7 +4151,7 @@ ja:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "プロジェクトを削除していません。"
notice_project_not_found: "プロジェクトが見つかりません。"
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "正常に接続しました。"
notice_successful_create: "正常に作成しました。"
notice_successful_delete: "正常に削除しました。"
+2 -2
View File
@@ -558,7 +558,7 @@ fr:
date_alerts:
milestone_date: "Date jalon"
overdue: "En retard"
overdue_since: "pour %{difference_in_days}."
overdue_since: "de %{difference_in_days}."
property_today: "a lieu aujourd'hui."
property_is: "a lieu dans %{difference_in_days}."
property_was: "avait lieu il y a %{difference_in_days}."
@@ -993,7 +993,7 @@ fr:
embedded_tab_disabled: "Cet onglet de configuration n'est pas disponible pour la vue intégrée que vous êtes en train de modifier."
default: "défaut"
display_settings: "Paramètres d'affichage"
default_mode: "Liste ombrée"
default_mode: "Liste"
hierarchy_mode: "Hiérarchie"
hierarchy_hint: "Tous les résultats du tableau filtrés seront augmentés de leurs ancêtres . Les hiérarchies peuvent être dépliées et repliées."
display_sums_hint: "Afficher les sommes de tous les attributs sommables dans une ligne sous les résultats du tableau."
+3 -11
View File
@@ -107,9 +107,8 @@ ka:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "ვებჰუკი"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ ka:
label_user_named: "მომხმარებელი %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "ანონიმური"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "მოვლენების გარეშე"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "ახალი მომხმარებელი"
label_user_plural: "მომხმარებლები"
@@ -3935,7 +3928,6 @@ ka:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "საწყისი გვერდი"
label_work: "სამუშაო"
label_work_package: "სამუშაო პაკეტი"
@@ -4217,7 +4209,7 @@ ka:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ kk:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ kk:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ kk:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ kk:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ ko:
trial: "평가판"
jemalloc_allocator: Jemalloc 메모리 할당기
journal_aggregation:
explanation:
text: "사용자의 개별 작업(예: 작업 패키지를 두 번 업데이트)은 연령 차이가 지정된 기간 미만인 경우 단일 작업으로 집계됩니다. 애플리케이션 내에서 단일 작업으로 표시됩니다. 또한 이는 전송되는 이메일 수를 줄이는 동일한 시간만큼 알림을 지연시키고 %{webhook_link} 지연에도 영향을 미칩니다."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "가져오기"
jira:
@@ -3834,12 +3833,6 @@ ko:
label_user_named: "사용자 %{name}"
label_user_activity: "%{value}의 작업"
label_user_anonymous: "익명"
label_user_mail_option_all: "모든 내 프로젝트의 이벤트에 대해"
label_user_mail_option_none: "이벤트 없음"
label_user_mail_option_only_assigned: "나에게 할당된 사항만"
label_user_mail_option_only_my_events: "내가 주시하거나 관련된 사항만"
label_user_mail_option_only_owner: "내가 소유자인 사항만"
label_user_mail_option_selected: "선택된 프로젝트에서 발생하는 이벤트만"
label_user_menu: "사용자 메뉴"
label_user_new: "새 사용자"
label_user_plural: "사용자"
@@ -3879,7 +3872,6 @@ ko:
label_wiki_show_index_page_link: "하위 메뉴 항목 '목차' 표시"
label_wiki_show_menu_item: "프로젝트 탐색에서 메뉴 항목으로 표시"
label_wiki_show_new_page_link: "하위 메뉴 항목 '새 자식 페이지 만들기' 표시"
label_wiki_show_submenu_item: "다음의 하위 메뉴 항목으로 표시: "
label_wiki_start: "시작 페이지"
label_work: "작업"
label_work_package: "작업 패키지"
@@ -4160,7 +4152,7 @@ ko:
notice_parent_item_not_found: "부모 항목을 찾을 수 없습니다."
notice_project_not_deleted: "프로젝트가 삭제되지 않았습니다."
notice_project_not_found: "프로젝트를 찾을 수 없습니다."
notice_smtp_address_unsafe: "SMTP 주소 %{address}은(는) 안전하지 않습니다. OPENPROJECT_SSRF_PROTECTION_ALLOWLIST에 추가하세요."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "연결에 성공했습니다."
notice_successful_create: "생성에 성공했습니다."
notice_successful_delete: "삭제에 성공했습니다."
+3 -11
View File
@@ -107,9 +107,8 @@ lt:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Visi atskiri naudotojo veiksmai (t.y. darbų paketo atnaujinimas du kartus) yra sugrupuojami į vieną veiksmą, jei laiko tarpas tarp jų yra mažesnis už šį nustatymą. Programoje jie bus rodomi kaip vienas veiksmas. Tiek pat bus pavėlinti ir pranešimai. Dėl to sumažės siunčiamų el.laiškų skaičius ir taipogi įtakos %{webhook_link} delsimą."
link: "tinklo jungtis"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3999,12 +3998,6 @@ lt:
label_user_named: "Naudotojas %{name}"
label_user_activity: "%{value} veikla"
label_user_anonymous: "Anonimas"
label_user_mail_option_all: "Bet kokiam įvykiui visuose mano projektuose"
label_user_mail_option_none: "Jokių įvykių"
label_user_mail_option_only_assigned: "Tiktai dalykams, kuriems esu priskirtas"
label_user_mail_option_only_my_events: "Tiktai dalykams, kuriuos stebiu arba esu įtrauktas"
label_user_mail_option_only_owner: "Tiktai dalykams, kurių šeimininkas esu aš"
label_user_mail_option_selected: "Bet kokiam įvykiui tiktai pasirinktuose projektuose"
label_user_menu: "User menu"
label_user_new: "Naujas vartotojas"
label_user_plural: "Naudotojai"
@@ -4044,7 +4037,6 @@ lt:
label_wiki_show_index_page_link: "Rodyti submeniu punktą „Turinys“"
label_wiki_show_menu_item: "Rodyti kaip meniu punktą projekto navigacijoje"
label_wiki_show_new_page_link: "Rodyti submeniu punktą „Sukurti naują vaiko puslapį“"
label_wiki_show_submenu_item: "Rodyti kaip submeniu punktą "
label_wiki_start: "Pradžios puslapis"
label_work: "Darbas"
label_work_package: "Darbų paketas"
@@ -4328,7 +4320,7 @@ lt:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projektas nebuvo panaikintas."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Sėkmingas susijungimas."
notice_successful_create: "Sėkmingas sukūrimas."
notice_successful_delete: "Sėkmingas panaikinimas."
+3 -11
View File
@@ -107,9 +107,8 @@ lv:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3946,12 +3945,6 @@ lv:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "Par jebkuru notikumu, visos manos projektos"
label_user_mail_option_none: "Nevēlos saņemt e-pasta paziņojumus"
label_user_mail_option_only_assigned: "Tikai par lietām kas piešķirtas man"
label_user_mail_option_only_my_events: "Tikai par lietām, kam sekoju, vai es esmu iesaistīts"
label_user_mail_option_only_owner: "Tikai par lietām, kuras es esmu izveidojis"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Lietotāji"
@@ -3991,7 +3984,6 @@ lv:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Sākuma lapa"
label_work: "Work"
label_work_package: "Darba pieteikums"
@@ -4274,7 +4266,7 @@ lv:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ mn:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ mn:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ mn:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ mn:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ ms:
trial: "Trial"
jemalloc_allocator: Pengagih ingatan Jemalloc
journal_aggregation:
explanation:
text: "Tindakan individu pengguna (cth. mengemas kini pakej kerja dua kali) dikumpulkan ke dalam satu tindakan tunggal jika perbezaan umur mereka kurang daripada tempoh masa yang ditetapkan. Mereka akan dipaparkan sebagai tindakan tunggal dalam aplikasi. Ini juga akan menangguhkan pemberitahuan dengan jumlah masa yang sama, mengurangkan bilangan e-mel yang dihantar serta akan memberi kesan kepada penagguhan %{webhook_link}."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3832,12 +3831,6 @@ ms:
label_user_named: "Pengguna %{name}"
label_user_activity: "aktiviti %{value}"
label_user_anonymous: "Anonim"
label_user_mail_option_all: "Untuk sebarang peristiwa pada semua projek saya"
label_user_mail_option_none: "Tiada peristiwa"
label_user_mail_option_only_assigned: "Hanya untuk perkara yang ditugaskan kepada saya"
label_user_mail_option_only_my_events: "Hanya untuk perkara yang saya perhatikan atau yang saya terlibat dalam"
label_user_mail_option_only_owner: "Hanya untuk perkara yang merupakan saya pemiliknya"
label_user_mail_option_selected: "Untuk sebarang peristiwa pada projek yang terpilih sahaja"
label_user_menu: "User menu"
label_user_new: "Pengguna baharu"
label_user_plural: "Pengguna-pengguna"
@@ -3877,7 +3870,6 @@ ms:
label_wiki_show_index_page_link: "Paparkan item submenu 'Jadual Kandungan'"
label_wiki_show_menu_item: "Paparkan sebagai item menu dalam navigasi projek"
label_wiki_show_new_page_link: "Paparkan item submenu 'Cipta laman anak baharu'"
label_wiki_show_submenu_item: "Paparkan sebagai item submenu "
label_wiki_start: "Halaman mula"
label_work: "Kerja"
label_work_package: "Pakej kerja"
@@ -4158,7 +4150,7 @@ ms:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Projek tersebut tidak dipadam."
notice_project_not_found: "Projek tidak ditemui."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Sambungan berjaya."
notice_successful_create: "Penciptaan yang berjaya."
notice_successful_delete: "Pemadaman yang berjaya."
+3 -11
View File
@@ -107,9 +107,8 @@ ne:
trial: "Trial"
jemalloc_allocator: Jemalloc memory allocator
journal_aggregation:
explanation:
text: "Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect %{webhook_link} delay."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3890,12 +3889,6 @@ ne:
label_user_named: "User %{name}"
label_user_activity: "%{value}'s activity"
label_user_anonymous: "Anonymous"
label_user_mail_option_all: "For any event on all my projects"
label_user_mail_option_none: "No events"
label_user_mail_option_only_assigned: "Only for things I am assigned to"
label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
label_user_mail_option_only_owner: "Only for things I am the owner of"
label_user_mail_option_selected: "For any event on the selected projects only"
label_user_menu: "User menu"
label_user_new: "New user"
label_user_plural: "Users"
@@ -3935,7 +3928,6 @@ ne:
label_wiki_show_index_page_link: "Show submenu item 'Table of Contents'"
label_wiki_show_menu_item: "Show as menu item in project navigation"
label_wiki_show_new_page_link: "Show submenu item 'Create new child page'"
label_wiki_show_submenu_item: "Show as submenu item of "
label_wiki_start: "Start page"
label_work: "Work"
label_work_package: "Work package"
@@ -4217,7 +4209,7 @@ ne:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "The project wasn't deleted."
notice_project_not_found: "Project not found."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Successful connection."
notice_successful_create: "Successful creation."
notice_successful_delete: "Successful deletion."
+3 -11
View File
@@ -107,9 +107,8 @@ nl:
trial: "Trial"
jemalloc_allocator: Jemalloc geheugentoewijzer
journal_aggregation:
explanation:
text: "Individuele acties van een gebruiker (bijv. het bijwerken van een werkpakket twee keer) wordt samengevoegd tot een enkele actie als hun leeftijdverschil minder is dan de aangegeven timespat. Ze worden weergegeven als een enkele actie binnen de applicatie. Dit zal ook meldingen vertragen met dezelfde tijd die het aantal verstuurde e-mails vermindert en zal ook %{webhook_link} vertraging beïnvloeden."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3886,12 +3885,6 @@ nl:
label_user_named: "Gebruiker %{name}"
label_user_activity: "%{value} activiteit"
label_user_anonymous: "Anoniem"
label_user_mail_option_all: "Voor een evenement op al mijn projecten"
label_user_mail_option_none: "Geen evenementen"
label_user_mail_option_only_assigned: "Alleen voor dingen die aan mij toegewezen zijn"
label_user_mail_option_only_my_events: "Alleen voor dingen die ik kijk of waar ik bij betrokken ben"
label_user_mail_option_only_owner: "Alleen voor dingen waar ik de eigenaar van ben"
label_user_mail_option_selected: "Voor een gebeurtenis op de geselecteerde projecten alleen"
label_user_menu: "User menu"
label_user_new: "Nieuwe gebruiker"
label_user_plural: "Gebruikers"
@@ -3931,7 +3924,6 @@ nl:
label_wiki_show_index_page_link: "Toon submenu item 'Inhoudsopgave'"
label_wiki_show_menu_item: "Weergeven als menu-item in project navigatie"
label_wiki_show_new_page_link: "Vervolgmenu-item 'Maken nieuwe onderliggende pagina' weergeven"
label_wiki_show_submenu_item: "Toon als submenu-item van "
label_wiki_start: "Startpagina"
label_work: "Werk"
label_work_package: "Werkpakket"
@@ -4212,7 +4204,7 @@ nl:
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Het project is niet verwijderd."
notice_project_not_found: "Project niet gevonden."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Geslaagde verbinding."
notice_successful_create: "Aanmaak geslaagd."
notice_successful_delete: "Verwijdering geslaagd."
+3 -11
View File
@@ -107,9 +107,8 @@
trial: "Trial"
jemalloc_allocator: Jemalloc minne allokator
journal_aggregation:
explanation:
text: "Individuelle handlinger av en bruker (f.eks. oppdatering av en arbeidspakke to ganger) aggregeres til en enkelt handling hvis aldersforskjellen er mindre enn det spesifiserte tidsrommet. De vil bli vist som en enkelt handling i programmet. Dette vil også forsinke varslinger med samme tidsperiode som reduserer antall e-poster som sendes, og vil også påvirke %{webhook_link} forsinkelse."
link: "webhook"
caption: >
Individual actions of a user (e.g. updating a work package twice) are aggregated into a single action if their age difference is less than the specified timespan. They will be displayed as a single action within the application. This will also delay notifications by the same amount of time reducing the number of emails being sent and will also affect the [webhook](webhook_link) delay.
import:
title: "Import"
jira:
@@ -3889,12 +3888,6 @@
label_user_named: "Bruker %{name}"
label_user_activity: "%{value}s aktivitet"
label_user_anonymous: "Anonym"
label_user_mail_option_all: "For enhver hendelse i alle mine prosjekter"
label_user_mail_option_none: "Ingen hendelser"
label_user_mail_option_only_assigned: "Kun for ting jeg er involvert i"
label_user_mail_option_only_my_events: "Kun for ting jeg overvåker eller er involvert i"
label_user_mail_option_only_owner: "Kun for ting jeg står som eier av"
label_user_mail_option_selected: "For alle hendelser kun på valgte prosjekter"
label_user_menu: "User menu"
label_user_new: "Ny bruker"
label_user_plural: "Brukere"
@@ -3934,7 +3927,6 @@
label_wiki_show_index_page_link: "Vis undermenyelement 'Innholdsfortegnelse'"
label_wiki_show_menu_item: "Vis som menyelement i prosjektmeny"
label_wiki_show_new_page_link: "Vis undermenyelement 'Opprett ny underside'"
label_wiki_show_submenu_item: "Vis som undermenyelement for "
label_wiki_start: "Startside"
label_work: "Arbeid"
label_work_package: "Arbeidspakke"
@@ -4216,7 +4208,7 @@
notice_parent_item_not_found: "Parent item not found."
notice_project_not_deleted: "Prosjektet ble ikke slettet."
notice_project_not_found: "Prosjektet ble ikke funnet."
notice_smtp_address_unsafe: "SMTP address %{address} is not safe. Please add it to OPENPROJECT_SSRF_PROTECTION_ALLOWLIST."
notice_smtp_address_unsafe_env_hint: "SMTP address %{address} is not safe. Please add it to the whitelist using the %{env_name} environment variable."
notice_successful_connection: "Vellykket tilkobling."
notice_successful_create: "Opprettelsen var vellykket."
notice_successful_delete: "Slettingen var vellykket."

Some files were not shown because too many files have changed in this diff Show More